@@ -17,15 +17,15 @@ module mir.interpolate.constant;
1717
1818// /
1919version (mir_test)
20- @safe pure unittest
20+ @safe pure @nogc unittest
2121{
2222 import mir.ndslice;
2323 import mir.math.common: approxEqual;
2424
25- immutable x = [0 , 1 , 2 , 3 ];
26- immutable y = [10 , 20 , 30 , 40 ];
25+ static immutable x = [0 , 1 , 2 , 3 ];
26+ static immutable y = [10 , 20 , 30 , 40 ];
2727
28- auto interpolant = constant! int (x.sliced , y.sliced );
28+ auto interpolant = constant! int (x.rcslice , y.rcslice ! ( const int ) );
2929
3030 assert (interpolant(- 1 ) == 10 );
3131 assert (interpolant(0 ) == 10 );
@@ -38,15 +38,18 @@ version(mir_test)
3838}
3939
4040
41-
42- import std.traits ;
43- import mir.primitives;
44- import mir.ndslice.slice;
41+ import core.lifetime : move;
4542import mir.internal.utility;
43+ import mir.functional;
44+ import mir.interpolate;
4645import mir.math.common: optmath;
47-
46+ import mir.ndslice.slice;
47+ import mir.primitives;
48+ import mir.rc.array;
49+ import mir.utility: min, max;
50+ import std.meta : AliasSeq, staticMap;
51+ import std.traits ;
4852public import mir.interpolate: atInterval;
49- import mir.interpolate;
5053
5154/+ +
5255Constructs multivariate constant interpolant with nodes on rectilinear grid.
@@ -60,97 +63,66 @@ Constraints:
6063
6164Returns: $(LREF Constant)
6265+/
63- template constant (T, size_t N = 1 , FirstGridIterator = immutable (T) * , NextGridIterators = Repeat ! (N - 1 , FirstGridIterator) )
64- if ( is (T == Unqual ! T) && N <= 6 )
66+ Constant ! (F, N, X) constant(F, size_t N = 1 , X = F )
67+ (Repeat ! (N, Slice ! ( RCI ! ( immutable X))) grid, Slice ! ( RCI ! ( const F), N) values )
6568{
66- static if (N > 1 ) pragma (msg, " Warning: multivariate constant interpolant was not tested." );
67-
68- import std.meta : AliasSeq;
69-
70- @optmath:
71-
72- private alias GridIterators = AliasSeq! (FirstGridIterator, NextGridIterators);
73- private alias GridVectors = Constant! (T, N, GridIterators).GridVectors;
74-
75- /+ +
76- Params:
77- grid = immutable `x` values for interpolant
78- values = `f(x)` values for interpolant
79- Constraints:
80- `grid` and `values` must have the same length >= 3
81- Returns: $(LREF Spline)
82- +/
83- Constant! (T, N, GridIterators) constant(yIterator, SliceKind ykind)(
84- GridVectors grid,
85- Slice! (yIterator, 1 , ykind) values
86- ) pure @trusted
87- {
88- static if (__VERSION__ >= 2085 ) import core.lifetime : move; else import std.algorithm.mutation : move;
89- auto ret = typeof (return )(grid);
90- ret._data[] = values ;
91- return ret.move;
92- }
69+ return typeof (return )(forward! grid, values .move);
9370}
9471
9572/+ +
9673Multivariate constant interpolant with nodes on rectilinear grid.
9774+/
98- struct Constant (F, size_t N = 1 , FirstGridIterator = immutable (F)*, NextGridIterators = Repeat!(N - 1, FirstGridIterator))
99- if (N && N <= 6 && NextGridIterators.length == N - 1 )
75+ extern (C++ , " mir" , " interpolate" )
76+ struct Constant (F, size_t N = 1 , X = F)
77+ if (N && N <= 6 )
10078{
101- import mir.rc.array;
102- import std.meta : AliasSeq, staticMap;
103-
104- package alias GridIterators = AliasSeq! (FirstGridIterator, NextGridIterators);
105- package alias GridVectors = staticMap! (GridVector, GridIterators);
106-
10779@optmath:
10880
10981 // / Aligned buffer allocated with `mir.internal.memory`. $(RED For internal use.)
110- mir_slice ! (mir_rci ! F , N) _data;
82+ Slice ! ( RCI ! ( const F) , N) _data;
11183 // / Grid iterators. $(RED For internal use.)
112- GridIterators _grid;
84+ RCI ! ( immutable X)[N] _grid;
11385
114- import mir.utility: min, max;
86+ extern ( D ):
11587
11688 /+ +
11789 +/
118- this (GridVectors grid) @safe @nogc
90+ this (Repeat ! (N, Slice ! ( RCI ! ( immutable X))) grid, Slice ! ( RCI ! ( const F), N) data ) @safe @nogc
11991 {
120- size_t length = 1 ;
121- size_t [N] shape;
122- enum msg = " constant interpolant: minimal allowed length for the grid equals 1." ;
92+ enum msg_min = " constant interpolant: minimal allowed length for the grid equals 1." ;
93+ enum msg_eq = " constant interpolant: X and Y values length should be equal." ;
12394 version (D_Exceptions)
124- static immutable exc = new Exception (msg);
95+ {
96+ static immutable exc_min = new Exception (msg_min);
97+ static immutable exc_eq = new Exception (msg_eq);
98+ }
12599 foreach (i, ref x; grid)
126100 {
127101 if (x.length < 1 )
128102 {
129- version (D_Exceptions)
130- throw exc;
131- else
132- assert (0 , msg);
103+ version (D_Exceptions) throw exc_min;
104+ else assert (0 , msg_min);
105+ }
106+ if (x.length != data._lengths[i])
107+ {
108+ version (D_Exceptions) throw exc_eq;
109+ else assert (0 , msg_eq);
133110 }
134- length *= shape [i] = x.length ;
111+ _grid [i] = x._iterator ;
135112 }
136-
137- auto rca = mir_rcarray! F(length);
138- this ._data = rca.asSlice.sliced(shape);
139- this ._grid = staticMap! (iter, grid);
113+ _data = data;
140114 }
141115
142116@trusted :
143117
144118 // /
145119 Constant lightConst ()() const @property { return * cast (Constant* )&this ; }
146- // /
147- Constant lightImmutable ()() immutable @property { return * cast (Constant* )&this ; }
148120
149121 // /
150- GridVectors[dimension] grid (size_t dimension = 0 )() scope return const @property
122+ Slice ! ( RCI ! ( immutable X)) grid(size_t dimension = 0 )() scope return const @property
151123 if (dimension < N)
152124 {
153- return _grid[dimension].sliced(_data._lengths[dimension]);
125+ return _grid[dimension].lightConst. sliced(_data._lengths[dimension]);
154126 }
155127
156128 /+ +
@@ -175,19 +147,15 @@ struct Constant(F, size_t N = 1, FirstGridIterator = immutable(F)*, NextGridIter
175147 template opCall (uint derivative = 0 )
176148 if (derivative <= derivativeOrder)
177149 {
178- @trusted :
179150 /+ +
180- `(x)` and `[x]` operators .
151+ `(x)` operator .
181152 Complexity:
182153 `O(log(grid.length))`
183154 +/
184- auto opCall (X... )(in X xs) scope const
155+ auto opCall (X... )(in X xs) scope const @trusted
185156 if (X.length == N)
186- // @FUTURE@
187- // X.length == N || derivative == 0 && X.length && X.length <= N
188157 {
189158 size_t [N] indexes = void ;
190-
191159 foreach (i; Iota! N)
192160 {
193161 static if (isInterval! (typeof (xs[i])))
0 commit comments