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
1549proc 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+
4593when 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