Skip to content

Commit b5a6b49

Browse files
committed
first version of RbfGrid structure
1 parent 8717c1d commit b5a6b49

File tree

1 file changed

+56
-3
lines changed

1 file changed

+56
-3
lines changed

src/numericalnim/rbf.nim

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,40 @@ type
1111
epsilon*: float
1212
f*: RbfFunc
1313

14+
RbfGrid*[T] = object
15+
grid*: seq[seq[T]]
16+
gridSize*, gridDim*: int
17+
gridDelta*: float
18+
19+
RbfPUType*[T] = object
20+
limits*: tuple[upper: Tensor[float], lower: Tensor[float]]
21+
# Don't hard-code in the patches, this is just for lookup to construct the patches
22+
#
23+
grid*: seq[RbfType[T]]
24+
25+
template km(point: Tensor[float], index: int, delta: float): int =
26+
int(ceil(point[0, index] / delta))
27+
28+
proc findIndex*[T](grid: RbfGrid[T], point: Tensor[float]): int =
29+
result = km(point, grid.gridDim - 1, grid.gridDelta) - 1
30+
for i in 0 ..< grid.gridDim - 1:
31+
result += (km(point, i, grid.gridDelta) - 1) * grid.gridSize ^ (grid.gridDim - i - 1)
32+
33+
proc newRbfGrid*[T](points: Tensor[float], values: seq[T], gridSize: int = 0): RbfGrid[T] =
34+
let nPoints = points.shape[0]
35+
let nDims = points.shape[1]
36+
let gridSize =
37+
if gridSize > 0:
38+
gridSize
39+
else:
40+
int(round(pow(nPoints.float, 1 / nDims) / 2))
41+
let delta = 1 / gridSize
42+
result = RbfGrid[T](gridSize: gridSize, gridDim: nDims, gridDelta: delta, grid: newSeq[seq[T]](gridSize ^ nDims))
43+
for row in 0 ..< nPoints:
44+
let index = result.findIndex(points[row, _])
45+
result.grid[index].add values[row]
46+
47+
1448
# Idea: blocked distance matrix for better cache friendliness
1549
proc distanceMatrix(p1, p2: Tensor[float]): Tensor[float] =
1650
## Returns distance matrix of shape (n_points, n_points)
@@ -42,8 +76,22 @@ proc eval*[T](rbf: RbfType[T], x: Tensor[float]): Tensor[T] =
4276
let A = rbf.f(dist, rbf.epsilon)
4377
result = A * rbf.coeffs
4478

79+
proc scalePoint*(x: Tensor[float], limits: tuple[upper: Tensor[float], lower: Tensor[float]]): Tensor[float] =
80+
(x -. limits.lower) /. (limits.upper - limits.lower)
81+
82+
proc gridIndex*(limits: tuple[upper: Tensor[float], lower: Tensor[float]], gridSide: int): int =
83+
discard
84+
85+
proc newRbfPu*[T](points: Tensor[float], values: Tensor[T], gridSide: int, rbfFunc: RbfFunc = compactRbfFunc, epsilon: float = 1): RbfType[T] =
86+
let upperLimit = max(points, 0)
87+
let lowerLimit = min(points, 0)
88+
let limits = (upper: upperLimit, lower: lowerLimit)
89+
let scaledPoints = points.scalePoint(limits)
90+
echo scaledPoints
91+
echo limits
92+
4593
when isMainModule:
46-
let x1 = @[@[0.0, 0.0, 0.0], @[1.0, 1.0, 0.0], @[1.0, 2.0, 0.0]].toTensor
94+
let x1 = @[@[0.0, 0.0, 0.0], @[1.0, 1.0, 0.0], @[1.0, 2.0, 4.0]].toTensor
4795
let x2 = @[@[0.0, 0.0, 1.0], @[1.0, 1.0, 2.0], @[1.0, 2.0, 3.0]].toTensor
4896
echo distanceMatrix(x1, x1)
4997
let values = @[0.0, 1.0, 2.0].toTensor
@@ -53,6 +101,11 @@ when isMainModule:
53101

54102
let pos = randomTensor(5000, 3, 1.0)
55103
let vals = randomTensor(5000, 1, 1.0)
56-
timeIt "Rbf":
57-
keep newRbf(pos, vals)
104+
# timeIt "Rbf":
105+
# keep newRbf(pos, vals)
106+
let rbfPu = newRbfPu(x1, values, 3)
58107

108+
echo "----------------"
109+
let xGrid = [[0.1, 0.1], [0.9, 0.9], [0.4, 0.4]].toTensor
110+
let valuesGrid = @[0, 9, 5]
111+
echo newRbfGrid(xGrid, valuesGrid, 3)

0 commit comments

Comments
 (0)