Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
tsoc
openmm
Commits
9d3636f4
"vscode:/vscode.git/clone" did not exist on "2529b922e3477beabc39c2dc0e7cd2d12bf58531"
Commit
9d3636f4
authored
Jan 30, 2014
by
peastman
Browse files
Added 3D spline functions to SplineFitter
parent
9434c6e8
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
450 additions
and
6 deletions
+450
-6
openmmapi/include/openmm/internal/SplineFitter.h
openmmapi/include/openmm/internal/SplineFitter.h
+47
-1
openmmapi/src/SplineFitter.cpp
openmmapi/src/SplineFitter.cpp
+355
-3
tests/TestSplineFitter.cpp
tests/TestSplineFitter.cpp
+48
-2
No files found.
openmmapi/include/openmm/internal/SplineFitter.h
View file @
9d3636f4
...
...
@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2010 Stanford University and the Authors.
*
* Portions copyright (c) 2010
-2014
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -124,6 +124,52 @@ public:
* @param dy on exit, the y derivative of the spline at the specified point
*/
static
void
evaluate2DSplineDerivatives
(
const
std
::
vector
<
double
>&
x
,
const
std
::
vector
<
double
>&
y
,
const
std
::
vector
<
double
>&
values
,
const
std
::
vector
<
std
::
vector
<
double
>
>&
c
,
double
u
,
double
v
,
double
&
dx
,
double
&
dy
);
/**
* Fit a natural cubic spline surface f(x,y,z) to a 3D set of data points. The resulting spline interpolates all the
* data points, has a continuous second derivative everywhere, and has a second derivative of 0 at the boundary.
*
* @param x the values of the first independent variable at the data points to interpolate. They must
* be strictly increasing: x[i] > x[i-1].
* @param y the values of the second independent variable at the data points to interpolate. They must
* be strictly increasing: y[i] > y[i-1].
* @param z the values of the third independent variable at the data points to interpolate. They must
* be strictly increasing: z[i] > z[i-1].
* @param values the values of the dependent variable at the data points to interpolate. They must be ordered
* so that values[i+xsize*j+xsize*ysize*k] = f(x[i],y[j],z[k]), where xsize is the length of x
* and ysize is the length of y.
* @param c on exit, this contains the spline coefficients at each of the data points
*/
static
void
create3DNaturalSpline
(
const
std
::
vector
<
double
>&
x
,
const
std
::
vector
<
double
>&
y
,
const
std
::
vector
<
double
>&
z
,
const
std
::
vector
<
double
>&
values
,
std
::
vector
<
std
::
vector
<
double
>
>&
c
);
/**
* Evaluate a 3D spline generated by one of the other methods in this class.
*
* @param x the values of the first independent variable at the data points to interpolate
* @param y the values of the second independent variable at the data points to interpolate
* @param z the values of the third independent variable at the data points to interpolate
* @param values the values of the dependent variable at the data points to interpolate
* @param c the vector of spline coefficients that was calculated by one of the other methods
* @param u the value of the first independent variable at which to evaluate the spline
* @param v the value of the second independent variable at which to evaluate the spline
* @param w the value of the third independent variable at which to evaluate the spline
* @return the value of the spline at the specified point
*/
static
double
evaluate3DSpline
(
const
std
::
vector
<
double
>&
x
,
const
std
::
vector
<
double
>&
y
,
const
std
::
vector
<
double
>&
z
,
const
std
::
vector
<
double
>&
values
,
const
std
::
vector
<
std
::
vector
<
double
>
>&
c
,
double
u
,
double
v
,
double
w
);
/**
* Evaluate the derivatives of a 3D spline generated by one of the other methods in this class.
*
* @param x the values of the first independent variable at the data points to interpolate
* @param y the values of the second independent variable at the data points to interpolate
* @param z the values of the third independent variable at the data points to interpolate
* @param values the values of the dependent variable at the data points to interpolate
* @param c the vector of spline coefficients that was calculated by one of the other methods
* @param u the value of the first independent variable at which to evaluate the spline
* @param v the value of the second independent variable at which to evaluate the spline
* @param w the value of the third independent variable at which to evaluate the spline
* @param dx on exit, the x derivative of the spline at the specified point
* @param dy on exit, the y derivative of the spline at the specified point
* @param dz on exit, the z derivative of the spline at the specified point
*/
static
void
evaluate3DSplineDerivatives
(
const
std
::
vector
<
double
>&
x
,
const
std
::
vector
<
double
>&
y
,
const
std
::
vector
<
double
>&
z
,
const
std
::
vector
<
double
>&
values
,
const
std
::
vector
<
std
::
vector
<
double
>
>&
c
,
double
u
,
double
v
,
double
w
,
double
&
dx
,
double
&
dy
,
double
&
dz
);
private:
static
void
solveTridiagonalMatrix
(
const
std
::
vector
<
double
>&
a
,
const
std
::
vector
<
double
>&
b
,
const
std
::
vector
<
double
>&
c
,
const
std
::
vector
<
double
>&
rhs
,
std
::
vector
<
double
>&
sol
);
};
...
...
openmmapi/src/SplineFitter.cpp
View file @
9d3636f4
...
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2010 Stanford University and the Authors.
*
* Portions copyright (c) 2010
-2014
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -319,7 +319,7 @@ double SplineFitter::evaluate2DSpline(const vector<double>& x, const vector<doub
double
db
=
(
v
-
y
[
lowery
])
/
deltay
;
const
vector
<
double
>&
coeff
=
c
[
lowerx
+
(
xsize
-
1
)
*
lowery
];
// Evaluate the spline to determine the value
and gradients
.
// Evaluate the spline to determine the value.
double
value
=
0
;
for
(
int
i
=
3
;
i
>=
0
;
i
--
)
...
...
@@ -359,7 +359,7 @@ void SplineFitter::evaluate2DSplineDerivatives(const vector<double>& x, const ve
double
db
=
(
v
-
y
[
lowery
])
/
deltay
;
const
vector
<
double
>&
coeff
=
c
[
lowerx
+
(
xsize
-
1
)
*
lowery
];
// Evaluate the spline to determine the
value and gradient
s.
// Evaluate the spline to determine the
derivative
s.
dx
=
0
;
dy
=
0
;
...
...
@@ -370,3 +370,355 @@ void SplineFitter::evaluate2DSplineDerivatives(const vector<double>& x, const ve
dx
/=
deltax
;
dy
/=
deltay
;
}
void
SplineFitter
::
create3DNaturalSpline
(
const
vector
<
double
>&
x
,
const
vector
<
double
>&
y
,
const
vector
<
double
>&
z
,
const
vector
<
double
>&
values
,
vector
<
vector
<
double
>
>&
c
)
{
int
xsize
=
x
.
size
(),
ysize
=
y
.
size
(),
zsize
=
z
.
size
();
int
xysize
=
xsize
*
ysize
;
if
(
xsize
<
2
||
ysize
<
2
||
zsize
<
2
)
throw
OpenMMException
(
"create2DNaturalSpline: must have at least two points along each axis"
);
if
(
values
.
size
()
!=
xsize
*
ysize
*
zsize
)
throw
OpenMMException
(
"create2DNaturalSpline: incorrect number of values"
);
vector
<
double
>
d1
(
xsize
*
ysize
*
zsize
),
d2
(
xsize
*
ysize
*
zsize
),
d3
(
xsize
*
ysize
*
zsize
);
vector
<
double
>
d12
(
xsize
*
ysize
*
zsize
),
d13
(
xsize
*
ysize
*
zsize
),
d23
(
xsize
*
ysize
*
zsize
),
d123
(
xsize
*
ysize
*
zsize
);
vector
<
double
>
t
(
xsize
),
deriv
(
xsize
);
// Compute derivatives with respect to x.
for
(
int
i
=
0
;
i
<
ysize
;
i
++
)
{
for
(
int
j
=
0
;
j
<
zsize
;
j
++
)
{
for
(
int
k
=
0
;
k
<
xsize
;
k
++
)
t
[
k
]
=
values
[
k
+
xsize
*
i
+
xysize
*
j
];
SplineFitter
::
createNaturalSpline
(
x
,
t
,
deriv
);
for
(
int
k
=
0
;
k
<
xsize
;
k
++
)
d1
[
k
+
xsize
*
i
+
xysize
*
j
]
=
SplineFitter
::
evaluateSplineDerivative
(
x
,
t
,
deriv
,
x
[
k
]);
}
}
// Compute derivatives with respect to y.
t
.
resize
(
ysize
);
deriv
.
resize
(
ysize
);
for
(
int
i
=
0
;
i
<
xsize
;
i
++
)
{
for
(
int
j
=
0
;
j
<
zsize
;
j
++
)
{
for
(
int
k
=
0
;
k
<
ysize
;
k
++
)
t
[
k
]
=
values
[
i
+
xsize
*
k
+
xysize
*
j
];
SplineFitter
::
createNaturalSpline
(
y
,
t
,
deriv
);
for
(
int
k
=
0
;
k
<
ysize
;
k
++
)
d2
[
i
+
xsize
*
k
+
xysize
*
j
]
=
SplineFitter
::
evaluateSplineDerivative
(
y
,
t
,
deriv
,
y
[
k
]);
}
}
// Compute derivatives with respect to z.
t
.
resize
(
zsize
);
deriv
.
resize
(
zsize
);
for
(
int
i
=
0
;
i
<
xsize
;
i
++
)
{
for
(
int
j
=
0
;
j
<
ysize
;
j
++
)
{
for
(
int
k
=
0
;
k
<
zsize
;
k
++
)
t
[
k
]
=
values
[
i
+
xsize
*
j
+
xysize
*
k
];
SplineFitter
::
createNaturalSpline
(
z
,
t
,
deriv
);
for
(
int
k
=
0
;
k
<
zsize
;
k
++
)
d3
[
i
+
xsize
*
j
+
xysize
*
k
]
=
SplineFitter
::
evaluateSplineDerivative
(
z
,
t
,
deriv
,
z
[
k
]);
}
}
// Compute second derivatives with respect to x and y.
t
.
resize
(
xsize
);
deriv
.
resize
(
xsize
);
for
(
int
i
=
0
;
i
<
ysize
;
i
++
)
{
for
(
int
j
=
0
;
j
<
zsize
;
j
++
)
{
for
(
int
k
=
0
;
k
<
xsize
;
k
++
)
t
[
k
]
=
d2
[
k
+
xsize
*
i
+
xysize
*
j
];
SplineFitter
::
createNaturalSpline
(
x
,
t
,
deriv
);
for
(
int
k
=
0
;
k
<
xsize
;
k
++
)
d12
[
k
+
xsize
*
i
+
xysize
*
j
]
=
SplineFitter
::
evaluateSplineDerivative
(
x
,
t
,
deriv
,
x
[
k
]);
}
}
// Compute second derivatives with respect to y and z.
t
.
resize
(
ysize
);
deriv
.
resize
(
ysize
);
for
(
int
i
=
0
;
i
<
zsize
;
i
++
)
{
for
(
int
j
=
0
;
j
<
xsize
;
j
++
)
{
for
(
int
k
=
0
;
k
<
ysize
;
k
++
)
t
[
k
]
=
d3
[
j
+
xsize
*
k
+
xysize
*
i
];
SplineFitter
::
createNaturalSpline
(
y
,
t
,
deriv
);
for
(
int
k
=
0
;
k
<
ysize
;
k
++
)
d23
[
j
+
xsize
*
k
+
xysize
*
i
]
=
SplineFitter
::
evaluateSplineDerivative
(
y
,
t
,
deriv
,
y
[
k
]);
}
}
// Compute second derivatives with respect to x and z.
t
.
resize
(
zsize
);
deriv
.
resize
(
zsize
);
for
(
int
i
=
0
;
i
<
xsize
;
i
++
)
{
for
(
int
j
=
0
;
j
<
ysize
;
j
++
)
{
for
(
int
k
=
0
;
k
<
zsize
;
k
++
)
t
[
k
]
=
d1
[
i
+
xsize
*
j
+
xysize
*
k
];
SplineFitter
::
createNaturalSpline
(
z
,
t
,
deriv
);
for
(
int
k
=
0
;
k
<
zsize
;
k
++
)
d13
[
i
+
xsize
*
j
+
xysize
*
k
]
=
SplineFitter
::
evaluateSplineDerivative
(
z
,
t
,
deriv
,
z
[
k
]);
}
}
// Compute third derivatives with respect to x, y, and z.
t
.
resize
(
xsize
);
deriv
.
resize
(
xsize
);
for
(
int
i
=
0
;
i
<
ysize
;
i
++
)
{
for
(
int
j
=
0
;
j
<
zsize
;
j
++
)
{
for
(
int
k
=
0
;
k
<
xsize
;
k
++
)
t
[
k
]
=
d23
[
k
+
xsize
*
i
+
xysize
*
j
];
SplineFitter
::
createNaturalSpline
(
x
,
t
,
deriv
);
for
(
int
k
=
0
;
k
<
xsize
;
k
++
)
d123
[
k
+
xsize
*
i
+
xysize
*
j
]
=
SplineFitter
::
evaluateSplineDerivative
(
x
,
t
,
deriv
,
x
[
k
]);
}
}
// Now compute the coefficients. This involves multiplying by a sparse 64x64 matrix, given
// here in packed form.
const
int
wt
[]
=
{
1
,
0
,
1
,
1
,
8
,
1
,
4
,
0
,
-
3
,
1
,
3
,
8
,
-
2
,
9
,
-
1
,
4
,
0
,
2
,
1
,
-
2
,
8
,
1
,
9
,
1
,
1
,
16
,
1
,
1
,
32
,
1
,
4
,
16
,
-
3
,
17
,
3
,
32
,
-
2
,
33
,
-
1
,
4
,
16
,
2
,
17
,
-
2
,
32
,
1
,
33
,
1
,
4
,
0
,
-
3
,
2
,
3
,
16
,
-
2
,
18
,
-
1
,
4
,
8
,
-
3
,
10
,
3
,
32
,
-
2
,
34
,
-
1
,
16
,
0
,
9
,
1
,
-
9
,
2
,
-
9
,
3
,
9
,
8
,
6
,
9
,
3
,
10
,
-
6
,
11
,
-
3
,
16
,
6
,
17
,
-
6
,
18
,
3
,
19
,
-
3
,
32
,
4
,
33
,
2
,
34
,
2
,
35
,
1
,
16
,
0
,
-
6
,
1
,
6
,
2
,
6
,
3
,
-
6
,
8
,
-
3
,
9
,
-
3
,
10
,
3
,
11
,
3
,
16
,
-
4
,
17
,
4
,
18
,
-
2
,
19
,
2
,
32
,
-
2
,
33
,
-
2
,
34
,
-
1
,
35
,
-
1
,
4
,
0
,
2
,
2
,
-
2
,
16
,
1
,
18
,
1
,
4
,
8
,
2
,
10
,
-
2
,
32
,
1
,
34
,
1
,
16
,
0
,
-
6
,
1
,
6
,
2
,
6
,
3
,
-
6
,
8
,
-
4
,
9
,
-
2
,
10
,
4
,
11
,
2
,
16
,
-
3
,
17
,
3
,
18
,
-
3
,
19
,
3
,
32
,
-
2
,
33
,
-
1
,
34
,
-
2
,
35
,
-
1
,
16
,
0
,
4
,
1
,
-
4
,
2
,
-
4
,
3
,
4
,
8
,
2
,
9
,
2
,
10
,
-
2
,
11
,
-
2
,
16
,
2
,
17
,
-
2
,
18
,
2
,
19
,
-
2
,
32
,
1
,
33
,
1
,
34
,
1
,
35
,
1
,
1
,
24
,
1
,
1
,
40
,
1
,
4
,
24
,
-
3
,
25
,
3
,
40
,
-
2
,
41
,
-
1
,
4
,
24
,
2
,
25
,
-
2
,
40
,
1
,
41
,
1
,
1
,
48
,
1
,
1
,
56
,
1
,
4
,
48
,
-
3
,
49
,
3
,
56
,
-
2
,
57
,
-
1
,
4
,
48
,
2
,
49
,
-
2
,
56
,
1
,
57
,
1
,
4
,
24
,
-
3
,
26
,
3
,
48
,
-
2
,
50
,
-
1
,
4
,
40
,
-
3
,
42
,
3
,
56
,
-
2
,
58
,
-
1
,
16
,
24
,
9
,
25
,
-
9
,
26
,
-
9
,
27
,
9
,
40
,
6
,
41
,
3
,
42
,
-
6
,
43
,
-
3
,
48
,
6
,
49
,
-
6
,
50
,
3
,
51
,
-
3
,
56
,
4
,
57
,
2
,
58
,
2
,
59
,
1
,
16
,
24
,
-
6
,
25
,
6
,
26
,
6
,
27
,
-
6
,
40
,
-
3
,
41
,
-
3
,
42
,
3
,
43
,
3
,
48
,
-
4
,
49
,
4
,
50
,
-
2
,
51
,
2
,
56
,
-
2
,
57
,
-
2
,
58
,
-
1
,
59
,
-
1
,
4
,
24
,
2
,
26
,
-
2
,
48
,
1
,
50
,
1
,
4
,
40
,
2
,
42
,
-
2
,
56
,
1
,
58
,
1
,
16
,
24
,
-
6
,
25
,
6
,
26
,
6
,
27
,
-
6
,
40
,
-
4
,
41
,
-
2
,
42
,
4
,
43
,
2
,
48
,
-
3
,
49
,
3
,
50
,
-
3
,
51
,
3
,
56
,
-
2
,
57
,
-
1
,
58
,
-
2
,
59
,
-
1
,
16
,
24
,
4
,
25
,
-
4
,
26
,
-
4
,
27
,
4
,
40
,
2
,
41
,
2
,
42
,
-
2
,
43
,
-
2
,
48
,
2
,
49
,
-
2
,
50
,
2
,
51
,
-
2
,
56
,
1
,
57
,
1
,
58
,
1
,
59
,
1
,
4
,
0
,
-
3
,
4
,
3
,
24
,
-
2
,
28
,
-
1
,
4
,
8
,
-
3
,
12
,
3
,
40
,
-
2
,
44
,
-
1
,
16
,
0
,
9
,
1
,
-
9
,
4
,
-
9
,
5
,
9
,
8
,
6
,
9
,
3
,
12
,
-
6
,
13
,
-
3
,
24
,
6
,
25
,
-
6
,
28
,
3
,
29
,
-
3
,
40
,
4
,
41
,
2
,
44
,
2
,
45
,
1
,
16
,
0
,
-
6
,
1
,
6
,
4
,
6
,
5
,
-
6
,
8
,
-
3
,
9
,
-
3
,
12
,
3
,
13
,
3
,
24
,
-
4
,
25
,
4
,
28
,
-
2
,
29
,
2
,
40
,
-
2
,
41
,
-
2
,
44
,
-
1
,
45
,
-
1
,
4
,
16
,
-
3
,
20
,
3
,
48
,
-
2
,
52
,
-
1
,
4
,
32
,
-
3
,
36
,
3
,
56
,
-
2
,
60
,
-
1
,
16
,
16
,
9
,
17
,
-
9
,
20
,
-
9
,
21
,
9
,
32
,
6
,
33
,
3
,
36
,
-
6
,
37
,
-
3
,
48
,
6
,
49
,
-
6
,
52
,
3
,
53
,
-
3
,
56
,
4
,
57
,
2
,
60
,
2
,
61
,
1
,
16
,
16
,
-
6
,
17
,
6
,
20
,
6
,
21
,
-
6
,
32
,
-
3
,
33
,
-
3
,
36
,
3
,
37
,
3
,
48
,
-
4
,
49
,
4
,
52
,
-
2
,
53
,
2
,
56
,
-
2
,
57
,
-
2
,
60
,
-
1
,
61
,
-
1
,
16
,
0
,
9
,
2
,
-
9
,
4
,
-
9
,
6
,
9
,
16
,
6
,
18
,
3
,
20
,
-
6
,
22
,
-
3
,
24
,
6
,
26
,
-
6
,
28
,
3
,
30
,
-
3
,
48
,
4
,
50
,
2
,
52
,
2
,
54
,
1
,
16
,
8
,
9
,
10
,
-
9
,
12
,
-
9
,
14
,
9
,
32
,
6
,
34
,
3
,
36
,
-
6
,
38
,
-
3
,
40
,
6
,
42
,
-
6
,
44
,
3
,
46
,
-
3
,
56
,
4
,
58
,
2
,
60
,
2
,
62
,
1
,
64
,
0
,
-
27
,
1
,
27
,
2
,
27
,
3
,
-
27
,
4
,
27
,
5
,
-
27
,
6
,
-
27
,
7
,
27
,
8
,
-
18
,
9
,
-
9
,
10
,
18
,
11
,
9
,
12
,
18
,
13
,
9
,
14
,
-
18
,
15
,
-
9
,
16
,
-
18
,
17
,
18
,
18
,
-
9
,
19
,
9
,
20
,
18
,
21
,
-
18
,
22
,
9
,
23
,
-
9
,
24
,
-
18
,
25
,
18
,
26
,
18
,
27
,
-
18
,
28
,
-
9
,
29
,
9
,
30
,
9
,
31
,
-
9
,
32
,
-
12
,
33
,
-
6
,
34
,
-
6
,
35
,
-
3
,
36
,
12
,
37
,
6
,
38
,
6
,
39
,
3
,
40
,
-
12
,
41
,
-
6
,
42
,
12
,
43
,
6
,
44
,
-
6
,
45
,
-
3
,
46
,
6
,
47
,
3
,
48
,
-
12
,
49
,
12
,
50
,
-
6
,
51
,
6
,
52
,
-
6
,
53
,
6
,
54
,
-
3
,
55
,
3
,
56
,
-
8
,
57
,
-
4
,
58
,
-
4
,
59
,
-
2
,
60
,
-
4
,
61
,
-
2
,
62
,
-
2
,
63
,
-
1
,
64
,
0
,
18
,
1
,
-
18
,
2
,
-
18
,
3
,
18
,
4
,
-
18
,
5
,
18
,
6
,
18
,
7
,
-
18
,
8
,
9
,
9
,
9
,
10
,
-
9
,
11
,
-
9
,
12
,
-
9
,
13
,
-
9
,
14
,
9
,
15
,
9
,
16
,
12
,
17
,
-
12
,
18
,
6
,
19
,
-
6
,
20
,
-
12
,
21
,
12
,
22
,
-
6
,
23
,
6
,
24
,
12
,
25
,
-
12
,
26
,
-
12
,
27
,
12
,
28
,
6
,
29
,
-
6
,
30
,
-
6
,
31
,
6
,
32
,
6
,
33
,
6
,
34
,
3
,
35
,
3
,
36
,
-
6
,
37
,
-
6
,
38
,
-
3
,
39
,
-
3
,
40
,
6
,
41
,
6
,
42
,
-
6
,
43
,
-
6
,
44
,
3
,
45
,
3
,
46
,
-
3
,
47
,
-
3
,
48
,
8
,
49
,
-
8
,
50
,
4
,
51
,
-
4
,
52
,
4
,
53
,
-
4
,
54
,
2
,
55
,
-
2
,
56
,
4
,
57
,
4
,
58
,
2
,
59
,
2
,
60
,
2
,
61
,
2
,
62
,
1
,
63
,
1
,
16
,
0
,
-
6
,
2
,
6
,
4
,
6
,
6
,
-
6
,
16
,
-
3
,
18
,
-
3
,
20
,
3
,
22
,
3
,
24
,
-
4
,
26
,
4
,
28
,
-
2
,
30
,
2
,
48
,
-
2
,
50
,
-
2
,
52
,
-
1
,
54
,
-
1
,
16
,
8
,
-
6
,
10
,
6
,
12
,
6
,
14
,
-
6
,
32
,
-
3
,
34
,
-
3
,
36
,
3
,
38
,
3
,
40
,
-
4
,
42
,
4
,
44
,
-
2
,
46
,
2
,
56
,
-
2
,
58
,
-
2
,
60
,
-
1
,
62
,
-
1
,
64
,
0
,
18
,
1
,
-
18
,
2
,
-
18
,
3
,
18
,
4
,
-
18
,
5
,
18
,
6
,
18
,
7
,
-
18
,
8
,
12
,
9
,
6
,
10
,
-
12
,
11
,
-
6
,
12
,
-
12
,
13
,
-
6
,
14
,
12
,
15
,
6
,
16
,
9
,
17
,
-
9
,
18
,
9
,
19
,
-
9
,
20
,
-
9
,
21
,
9
,
22
,
-
9
,
23
,
9
,
24
,
12
,
25
,
-
12
,
26
,
-
12
,
27
,
12
,
28
,
6
,
29
,
-
6
,
30
,
-
6
,
31
,
6
,
32
,
6
,
33
,
3
,
34
,
6
,
35
,
3
,
36
,
-
6
,
37
,
-
3
,
38
,
-
6
,
39
,
-
3
,
40
,
8
,
41
,
4
,
42
,
-
8
,
43
,
-
4
,
44
,
4
,
45
,
2
,
46
,
-
4
,
47
,
-
2
,
48
,
6
,
49
,
-
6
,
50
,
6
,
51
,
-
6
,
52
,
3
,
53
,
-
3
,
54
,
3
,
55
,
-
3
,
56
,
4
,
57
,
2
,
58
,
4
,
59
,
2
,
60
,
2
,
61
,
1
,
62
,
2
,
63
,
1
,
64
,
0
,
-
12
,
1
,
12
,
2
,
12
,
3
,
-
12
,
4
,
12
,
5
,
-
12
,
6
,
-
12
,
7
,
12
,
8
,
-
6
,
9
,
-
6
,
10
,
6
,
11
,
6
,
12
,
6
,
13
,
6
,
14
,
-
6
,
15
,
-
6
,
16
,
-
6
,
17
,
6
,
18
,
-
6
,
19
,
6
,
20
,
6
,
21
,
-
6
,
22
,
6
,
23
,
-
6
,
24
,
-
8
,
25
,
8
,
26
,
8
,
27
,
-
8
,
28
,
-
4
,
29
,
4
,
30
,
4
,
31
,
-
4
,
32
,
-
3
,
33
,
-
3
,
34
,
-
3
,
35
,
-
3
,
36
,
3
,
37
,
3
,
38
,
3
,
39
,
3
,
40
,
-
4
,
41
,
-
4
,
42
,
4
,
43
,
4
,
44
,
-
2
,
45
,
-
2
,
46
,
2
,
47
,
2
,
48
,
-
4
,
49
,
4
,
50
,
-
4
,
51
,
4
,
52
,
-
2
,
53
,
2
,
54
,
-
2
,
55
,
2
,
56
,
-
2
,
57
,
-
2
,
58
,
-
2
,
59
,
-
2
,
60
,
-
1
,
61
,
-
1
,
62
,
-
1
,
63
,
-
1
,
4
,
0
,
2
,
4
,
-
2
,
24
,
1
,
28
,
1
,
4
,
8
,
2
,
12
,
-
2
,
40
,
1
,
44
,
1
,
16
,
0
,
-
6
,
1
,
6
,
4
,
6
,
5
,
-
6
,
8
,
-
4
,
9
,
-
2
,
12
,
4
,
13
,
2
,
24
,
-
3
,
25
,
3
,
28
,
-
3
,
29
,
3
,
40
,
-
2
,
41
,
-
1
,
44
,
-
2
,
45
,
-
1
,
16
,
0
,
4
,
1
,
-
4
,
4
,
-
4
,
5
,
4
,
8
,
2
,
9
,
2
,
12
,
-
2
,
13
,
-
2
,
24
,
2
,
25
,
-
2
,
28
,
2
,
29
,
-
2
,
40
,
1
,
41
,
1
,
44
,
1
,
45
,
1
,
4
,
16
,
2
,
20
,
-
2
,
48
,
1
,
52
,
1
,
4
,
32
,
2
,
36
,
-
2
,
56
,
1
,
60
,
1
,
16
,
16
,
-
6
,
17
,
6
,
20
,
6
,
21
,
-
6
,
32
,
-
4
,
33
,
-
2
,
36
,
4
,
37
,
2
,
48
,
-
3
,
49
,
3
,
52
,
-
3
,
53
,
3
,
56
,
-
2
,
57
,
-
1
,
60
,
-
2
,
61
,
-
1
,
16
,
16
,
4
,
17
,
-
4
,
20
,
-
4
,
21
,
4
,
32
,
2
,
33
,
2
,
36
,
-
2
,
37
,
-
2
,
48
,
2
,
49
,
-
2
,
52
,
2
,
53
,
-
2
,
56
,
1
,
57
,
1
,
60
,
1
,
61
,
1
,
16
,
0
,
-
6
,
2
,
6
,
4
,
6
,
6
,
-
6
,
16
,
-
4
,
18
,
-
2
,
20
,
4
,
22
,
2
,
24
,
-
3
,
26
,
3
,
28
,
-
3
,
30
,
3
,
48
,
-
2
,
50
,
-
1
,
52
,
-
2
,
54
,
-
1
,
16
,
8
,
-
6
,
10
,
6
,
12
,
6
,
14
,
-
6
,
32
,
-
4
,
34
,
-
2
,
36
,
4
,
38
,
2
,
40
,
-
3
,
42
,
3
,
44
,
-
3
,
46
,
3
,
56
,
-
2
,
58
,
-
1
,
60
,
-
2
,
62
,
-
1
,
64
,
0
,
18
,
1
,
-
18
,
2
,
-
18
,
3
,
18
,
4
,
-
18
,
5
,
18
,
6
,
18
,
7
,
-
18
,
8
,
12
,
9
,
6
,
10
,
-
12
,
11
,
-
6
,
12
,
-
12
,
13
,
-
6
,
14
,
12
,
15
,
6
,
16
,
12
,
17
,
-
12
,
18
,
6
,
19
,
-
6
,
20
,
-
12
,
21
,
12
,
22
,
-
6
,
23
,
6
,
24
,
9
,
25
,
-
9
,
26
,
-
9
,
27
,
9
,
28
,
9
,
29
,
-
9
,
30
,
-
9
,
31
,
9
,
32
,
8
,
33
,
4
,
34
,
4
,
35
,
2
,
36
,
-
8
,
37
,
-
4
,
38
,
-
4
,
39
,
-
2
,
40
,
6
,
41
,
3
,
42
,
-
6
,
43
,
-
3
,
44
,
6
,
45
,
3
,
46
,
-
6
,
47
,
-
3
,
48
,
6
,
49
,
-
6
,
50
,
3
,
51
,
-
3
,
52
,
6
,
53
,
-
6
,
54
,
3
,
55
,
-
3
,
56
,
4
,
57
,
2
,
58
,
2
,
59
,
1
,
60
,
4
,
61
,
2
,
62
,
2
,
63
,
1
,
64
,
0
,
-
12
,
1
,
12
,
2
,
12
,
3
,
-
12
,
4
,
12
,
5
,
-
12
,
6
,
-
12
,
7
,
12
,
8
,
-
6
,
9
,
-
6
,
10
,
6
,
11
,
6
,
12
,
6
,
13
,
6
,
14
,
-
6
,
15
,
-
6
,
16
,
-
8
,
17
,
8
,
18
,
-
4
,
19
,
4
,
20
,
8
,
21
,
-
8
,
22
,
4
,
23
,
-
4
,
24
,
-
6
,
25
,
6
,
26
,
6
,
27
,
-
6
,
28
,
-
6
,
29
,
6
,
30
,
6
,
31
,
-
6
,
32
,
-
4
,
33
,
-
4
,
34
,
-
2
,
35
,
-
2
,
36
,
4
,
37
,
4
,
38
,
2
,
39
,
2
,
40
,
-
3
,
41
,
-
3
,
42
,
3
,
43
,
3
,
44
,
-
3
,
45
,
-
3
,
46
,
3
,
47
,
3
,
48
,
-
4
,
49
,
4
,
50
,
-
2
,
51
,
2
,
52
,
-
4
,
53
,
4
,
54
,
-
2
,
55
,
2
,
56
,
-
2
,
57
,
-
2
,
58
,
-
1
,
59
,
-
1
,
60
,
-
2
,
61
,
-
2
,
62
,
-
1
,
63
,
-
1
,
16
,
0
,
4
,
2
,
-
4
,
4
,
-
4
,
6
,
4
,
16
,
2
,
18
,
2
,
20
,
-
2
,
22
,
-
2
,
24
,
2
,
26
,
-
2
,
28
,
2
,
30
,
-
2
,
48
,
1
,
50
,
1
,
52
,
1
,
54
,
1
,
16
,
8
,
4
,
10
,
-
4
,
12
,
-
4
,
14
,
4
,
32
,
2
,
34
,
2
,
36
,
-
2
,
38
,
-
2
,
40
,
2
,
42
,
-
2
,
44
,
2
,
46
,
-
2
,
56
,
1
,
58
,
1
,
60
,
1
,
62
,
1
,
64
,
0
,
-
12
,
1
,
12
,
2
,
12
,
3
,
-
12
,
4
,
12
,
5
,
-
12
,
6
,
-
12
,
7
,
12
,
8
,
-
8
,
9
,
-
4
,
10
,
8
,
11
,
4
,
12
,
8
,
13
,
4
,
14
,
-
8
,
15
,
-
4
,
16
,
-
6
,
17
,
6
,
18
,
-
6
,
19
,
6
,
20
,
6
,
21
,
-
6
,
22
,
6
,
23
,
-
6
,
24
,
-
6
,
25
,
6
,
26
,
6
,
27
,
-
6
,
28
,
-
6
,
29
,
6
,
30
,
6
,
31
,
-
6
,
32
,
-
4
,
33
,
-
2
,
34
,
-
4
,
35
,
-
2
,
36
,
4
,
37
,
2
,
38
,
4
,
39
,
2
,
40
,
-
4
,
41
,
-
2
,
42
,
4
,
43
,
2
,
44
,
-
4
,
45
,
-
2
,
46
,
4
,
47
,
2
,
48
,
-
3
,
49
,
3
,
50
,
-
3
,
51
,
3
,
52
,
-
3
,
53
,
3
,
54
,
-
3
,
55
,
3
,
56
,
-
2
,
57
,
-
1
,
58
,
-
2
,
59
,
-
1
,
60
,
-
2
,
61
,
-
1
,
62
,
-
2
,
63
,
-
1
,
64
,
0
,
8
,
1
,
-
8
,
2
,
-
8
,
3
,
8
,
4
,
-
8
,
5
,
8
,
6
,
8
,
7
,
-
8
,
8
,
4
,
9
,
4
,
10
,
-
4
,
11
,
-
4
,
12
,
-
4
,
13
,
-
4
,
14
,
4
,
15
,
4
,
16
,
4
,
17
,
-
4
,
18
,
4
,
19
,
-
4
,
20
,
-
4
,
21
,
4
,
22
,
-
4
,
23
,
4
,
24
,
4
,
25
,
-
4
,
26
,
-
4
,
27
,
4
,
28
,
4
,
29
,
-
4
,
30
,
-
4
,
31
,
4
,
32
,
2
,
33
,
2
,
34
,
2
,
35
,
2
,
36
,
-
2
,
37
,
-
2
,
38
,
-
2
,
39
,
-
2
,
40
,
2
,
41
,
2
,
42
,
-
2
,
43
,
-
2
,
44
,
2
,
45
,
2
,
46
,
-
2
,
47
,
-
2
,
48
,
2
,
49
,
-
2
,
50
,
2
,
51
,
-
2
,
52
,
2
,
53
,
-
2
,
54
,
2
,
55
,
-
2
,
56
,
1
,
57
,
1
,
58
,
1
,
59
,
1
,
60
,
1
,
61
,
1
,
62
,
1
,
63
,
1
};
vector
<
vector
<
int
>
>
weight
(
64
);
int
index
=
0
;
for
(
int
i
=
0
;
i
<
64
;
i
++
)
{
int
numElements
=
wt
[
index
++
];
for
(
int
j
=
0
;
j
<
numElements
;
j
++
)
{
weight
[
i
].
push_back
(
wt
[
index
++
]);
weight
[
i
].
push_back
(
wt
[
index
++
]);
}
}
vector
<
double
>
rhs
(
64
);
c
.
resize
((
xsize
-
1
)
*
(
ysize
-
1
)
*
(
zsize
-
1
));
for
(
int
i
=
0
;
i
<
xsize
-
1
;
i
++
)
{
for
(
int
j
=
0
;
j
<
ysize
-
1
;
j
++
)
{
for
(
int
k
=
0
;
k
<
zsize
-
1
;
k
++
)
{
// Compute the 64 coefficients for patch (i, j, k).
int
nexti
=
i
+
1
;
int
nextj
=
j
+
1
;
int
nextk
=
k
+
1
;
double
deltax
=
x
[
nexti
]
-
x
[
i
];
double
deltay
=
y
[
nextj
]
-
y
[
j
];
double
deltaz
=
z
[
nextj
]
-
z
[
j
];
double
e
[]
=
{
values
[
i
+
j
*
xsize
+
k
*
xysize
],
values
[
nexti
+
j
*
xsize
+
k
*
xysize
],
values
[
i
+
nextj
*
xsize
+
k
*
xysize
],
values
[
nexti
+
nextj
*
xsize
+
k
*
xysize
],
values
[
i
+
j
*
xsize
+
nextk
*
xysize
],
values
[
nexti
+
j
*
xsize
+
nextk
*
xysize
],
values
[
i
+
nextj
*
xsize
+
nextk
*
xysize
],
values
[
nexti
+
nextj
*
xsize
+
nextk
*
xysize
]};
double
e1
[]
=
{
d1
[
i
+
j
*
xsize
+
k
*
xysize
],
d1
[
nexti
+
j
*
xsize
+
k
*
xysize
],
d1
[
i
+
nextj
*
xsize
+
k
*
xysize
],
d1
[
nexti
+
nextj
*
xsize
+
k
*
xysize
],
d1
[
i
+
j
*
xsize
+
nextk
*
xysize
],
d1
[
nexti
+
j
*
xsize
+
nextk
*
xysize
],
d1
[
i
+
nextj
*
xsize
+
nextk
*
xysize
],
d1
[
nexti
+
nextj
*
xsize
+
nextk
*
xysize
]};
double
e2
[]
=
{
d2
[
i
+
j
*
xsize
+
k
*
xysize
],
d2
[
nexti
+
j
*
xsize
+
k
*
xysize
],
d2
[
i
+
nextj
*
xsize
+
k
*
xysize
],
d2
[
nexti
+
nextj
*
xsize
+
k
*
xysize
],
d2
[
i
+
j
*
xsize
+
nextk
*
xysize
],
d2
[
nexti
+
j
*
xsize
+
nextk
*
xysize
],
d2
[
i
+
nextj
*
xsize
+
nextk
*
xysize
],
d2
[
nexti
+
nextj
*
xsize
+
nextk
*
xysize
]};
double
e3
[]
=
{
d3
[
i
+
j
*
xsize
+
k
*
xysize
],
d3
[
nexti
+
j
*
xsize
+
k
*
xysize
],
d3
[
i
+
nextj
*
xsize
+
k
*
xysize
],
d3
[
nexti
+
nextj
*
xsize
+
k
*
xysize
],
d3
[
i
+
j
*
xsize
+
nextk
*
xysize
],
d3
[
nexti
+
j
*
xsize
+
nextk
*
xysize
],
d3
[
i
+
nextj
*
xsize
+
nextk
*
xysize
],
d3
[
nexti
+
nextj
*
xsize
+
nextk
*
xysize
]};
double
e12
[]
=
{
d12
[
i
+
j
*
xsize
+
k
*
xysize
],
d12
[
nexti
+
j
*
xsize
+
k
*
xysize
],
d12
[
i
+
nextj
*
xsize
+
k
*
xysize
],
d12
[
nexti
+
nextj
*
xsize
+
k
*
xysize
],
d12
[
i
+
j
*
xsize
+
nextk
*
xysize
],
d12
[
nexti
+
j
*
xsize
+
nextk
*
xysize
],
d12
[
i
+
nextj
*
xsize
+
nextk
*
xysize
],
d12
[
nexti
+
nextj
*
xsize
+
nextk
*
xysize
]};
double
e13
[]
=
{
d13
[
i
+
j
*
xsize
+
k
*
xysize
],
d13
[
nexti
+
j
*
xsize
+
k
*
xysize
],
d13
[
i
+
nextj
*
xsize
+
k
*
xysize
],
d13
[
nexti
+
nextj
*
xsize
+
k
*
xysize
],
d13
[
i
+
j
*
xsize
+
nextk
*
xysize
],
d13
[
nexti
+
j
*
xsize
+
nextk
*
xysize
],
d13
[
i
+
nextj
*
xsize
+
nextk
*
xysize
],
d13
[
nexti
+
nextj
*
xsize
+
nextk
*
xysize
]};
double
e23
[]
=
{
d23
[
i
+
j
*
xsize
+
k
*
xysize
],
d23
[
nexti
+
j
*
xsize
+
k
*
xysize
],
d23
[
i
+
nextj
*
xsize
+
k
*
xysize
],
d23
[
nexti
+
nextj
*
xsize
+
k
*
xysize
],
d23
[
i
+
j
*
xsize
+
nextk
*
xysize
],
d23
[
nexti
+
j
*
xsize
+
nextk
*
xysize
],
d23
[
i
+
nextj
*
xsize
+
nextk
*
xysize
],
d23
[
nexti
+
nextj
*
xsize
+
nextk
*
xysize
]};
double
e123
[]
=
{
d123
[
i
+
j
*
xsize
+
k
*
xysize
],
d123
[
nexti
+
j
*
xsize
+
k
*
xysize
],
d123
[
i
+
nextj
*
xsize
+
k
*
xysize
],
d123
[
nexti
+
nextj
*
xsize
+
k
*
xysize
],
d123
[
i
+
j
*
xsize
+
nextk
*
xysize
],
d123
[
nexti
+
j
*
xsize
+
nextk
*
xysize
],
d123
[
i
+
nextj
*
xsize
+
nextk
*
xysize
],
d123
[
nexti
+
nextj
*
xsize
+
nextk
*
xysize
]};
for
(
int
m
=
0
;
m
<
8
;
m
++
)
{
rhs
[
m
]
=
e
[
m
];
rhs
[
m
+
8
]
=
e1
[
m
]
*
deltax
;
rhs
[
m
+
16
]
=
e2
[
m
]
*
deltay
;
rhs
[
m
+
24
]
=
e3
[
m
]
*
deltaz
;
rhs
[
m
+
32
]
=
e12
[
m
]
*
deltax
*
deltay
;
rhs
[
m
+
40
]
=
e13
[
m
]
*
deltax
*
deltaz
;
rhs
[
m
+
48
]
=
e23
[
m
]
*
deltay
*
deltaz
;
rhs
[
m
+
56
]
=
e123
[
m
]
*
deltax
*
deltay
*
deltaz
;
}
vector
<
double
>&
coeff
=
c
[
i
+
j
*
(
xsize
-
1
)
+
k
*
(
xsize
-
1
)
*
(
ysize
-
1
)];
coeff
.
resize
(
64
);
for
(
int
m
=
0
;
m
<
64
;
m
++
)
{
double
sum
=
0.0
;
int
numElements
=
weight
[
m
].
size
();
for
(
int
n
=
0
;
n
<
numElements
;
n
+=
2
)
sum
+=
weight
[
m
][
n
+
1
]
*
rhs
[
weight
[
m
][
n
]];
coeff
[
m
]
=
sum
;
}
}
}
}
}
double
SplineFitter
::
evaluate3DSpline
(
const
vector
<
double
>&
x
,
const
vector
<
double
>&
y
,
const
vector
<
double
>&
z
,
const
vector
<
double
>&
values
,
const
vector
<
vector
<
double
>
>&
c
,
double
u
,
double
v
,
double
w
)
{
int
xsize
=
x
.
size
();
int
ysize
=
y
.
size
();
int
zsize
=
z
.
size
();
if
(
u
<
x
[
0
]
||
u
>
x
[
xsize
-
1
]
||
v
<
y
[
0
]
||
v
>
y
[
ysize
-
1
]
||
w
<
z
[
0
]
||
w
>
z
[
zsize
-
1
])
throw
OpenMMException
(
"evaluate3DSpline: specified point is outside the range defined by the spline"
);
// Perform a binary search to identify the interval containing the point to evaluate.
int
lowerx
=
0
;
int
upperx
=
xsize
-
1
;
while
(
upperx
-
lowerx
>
1
)
{
int
middle
=
(
upperx
+
lowerx
)
/
2
;
if
(
x
[
middle
]
>
u
)
upperx
=
middle
;
else
lowerx
=
middle
;
}
int
lowery
=
0
;
int
uppery
=
ysize
-
1
;
while
(
uppery
-
lowery
>
1
)
{
int
middle
=
(
uppery
+
lowery
)
/
2
;
if
(
y
[
middle
]
>
v
)
uppery
=
middle
;
else
lowery
=
middle
;
}
int
lowerz
=
0
;
int
upperz
=
zsize
-
1
;
while
(
upperz
-
lowerz
>
1
)
{
int
middle
=
(
upperz
+
lowerz
)
/
2
;
if
(
z
[
middle
]
>
w
)
upperz
=
middle
;
else
lowerz
=
middle
;
}
double
deltax
=
x
[
upperx
]
-
x
[
lowerx
];
double
deltay
=
y
[
uppery
]
-
y
[
lowery
];
double
deltaz
=
z
[
upperz
]
-
z
[
lowerz
];
double
da
=
(
u
-
x
[
lowerx
])
/
deltax
;
double
db
=
(
v
-
y
[
lowery
])
/
deltay
;
double
dc
=
(
w
-
z
[
lowerz
])
/
deltaz
;
const
vector
<
double
>&
coeff
=
c
[
lowerx
+
(
xsize
-
1
)
*
lowery
+
(
xsize
-
1
)
*
(
ysize
-
1
)
*
lowerz
];
// Evaluate the spline to determine the value and gradients.
double
value
[]
=
{
0
,
0
,
0
,
0
};
for
(
int
i
=
3
;
i
>=
0
;
i
--
)
{
for
(
int
j
=
0
;
j
<
4
;
j
++
)
{
int
base
=
4
*
i
+
16
*
j
;
value
[
j
]
=
db
*
value
[
j
]
+
((
coeff
[
base
+
3
]
*
da
+
coeff
[
base
+
2
])
*
da
+
coeff
[
base
+
1
])
*
da
+
coeff
[
base
];
}
}
return
value
[
0
]
+
dc
*
(
value
[
1
]
+
dc
*
(
value
[
2
]
+
dc
*
value
[
3
]));
}
void
SplineFitter
::
evaluate3DSplineDerivatives
(
const
vector
<
double
>&
x
,
const
vector
<
double
>&
y
,
const
vector
<
double
>&
z
,
const
vector
<
double
>&
values
,
const
vector
<
vector
<
double
>
>&
c
,
double
u
,
double
v
,
double
w
,
double
&
dx
,
double
&
dy
,
double
&
dz
)
{
int
xsize
=
x
.
size
();
int
ysize
=
y
.
size
();
int
zsize
=
z
.
size
();
if
(
u
<
x
[
0
]
||
u
>
x
[
xsize
-
1
]
||
v
<
y
[
0
]
||
v
>
y
[
ysize
-
1
]
||
w
<
z
[
0
]
||
w
>
z
[
zsize
-
1
])
throw
OpenMMException
(
"evaluate3DSpline: specified point is outside the range defined by the spline"
);
// Perform a binary search to identify the interval containing the point to evaluate.
int
lowerx
=
0
;
int
upperx
=
xsize
-
1
;
while
(
upperx
-
lowerx
>
1
)
{
int
middle
=
(
upperx
+
lowerx
)
/
2
;
if
(
x
[
middle
]
>
u
)
upperx
=
middle
;
else
lowerx
=
middle
;
}
int
lowery
=
0
;
int
uppery
=
ysize
-
1
;
while
(
uppery
-
lowery
>
1
)
{
int
middle
=
(
uppery
+
lowery
)
/
2
;
if
(
y
[
middle
]
>
v
)
uppery
=
middle
;
else
lowery
=
middle
;
}
int
lowerz
=
0
;
int
upperz
=
zsize
-
1
;
while
(
upperz
-
lowerz
>
1
)
{
int
middle
=
(
upperz
+
lowerz
)
/
2
;
if
(
z
[
middle
]
>
w
)
upperz
=
middle
;
else
lowerz
=
middle
;
}
double
deltax
=
x
[
upperx
]
-
x
[
lowerx
];
double
deltay
=
y
[
uppery
]
-
y
[
lowery
];
double
deltaz
=
z
[
upperz
]
-
z
[
lowerz
];
double
da
=
(
u
-
x
[
lowerx
])
/
deltax
;
double
db
=
(
v
-
y
[
lowery
])
/
deltay
;
double
dc
=
(
w
-
z
[
lowerz
])
/
deltaz
;
const
vector
<
double
>&
coeff
=
c
[
lowerx
+
(
xsize
-
1
)
*
lowery
+
(
xsize
-
1
)
*
(
ysize
-
1
)
*
lowerz
];
// Evaluate the spline to determine the derivatives.
double
derivx
[]
=
{
0
,
0
,
0
,
0
};
double
derivy
[]
=
{
0
,
0
,
0
,
0
};
double
derivz
[]
=
{
0
,
0
,
0
,
0
};
for
(
int
i
=
3
;
i
>=
0
;
i
--
)
{
for
(
int
j
=
0
;
j
<
4
;
j
++
)
{
int
base
=
4
*
i
+
16
*
j
;
derivx
[
j
]
=
db
*
derivx
[
j
]
+
(
3.0
*
coeff
[
base
+
3
]
*
da
+
2.0
*
coeff
[
base
+
2
])
*
da
+
coeff
[
base
+
1
];
derivz
[
j
]
=
db
*
derivz
[
j
]
+
((
coeff
[
base
+
3
]
*
da
+
coeff
[
base
+
2
])
*
da
+
coeff
[
base
+
1
])
*
da
+
coeff
[
base
];
base
=
i
+
16
*
j
;
derivy
[
j
]
=
da
*
derivy
[
j
]
+
(
3.0
*
coeff
[
base
+
12
]
*
db
+
2.0
*
coeff
[
base
+
8
])
*
db
+
coeff
[
base
+
4
];
}
}
dx
=
derivx
[
0
]
+
dc
*
(
derivx
[
1
]
+
dc
*
(
derivx
[
2
]
+
dc
*
derivx
[
3
]));
dy
=
derivy
[
0
]
+
dc
*
(
derivy
[
1
]
+
dc
*
(
derivy
[
2
]
+
dc
*
derivy
[
3
]));
dz
=
derivz
[
1
]
+
dc
*
(
2.0
*
derivz
[
2
]
+
3.0
*
dc
*
derivz
[
3
]);
dx
/=
deltax
;
dy
/=
deltay
;
dz
/=
deltaz
;
}
tests/TestSplineFitter.cpp
View file @
9d3636f4
...
...
@@ -106,8 +106,8 @@ void test2DSpline() {
}
for
(
int
i
=
0
;
i
<
10
;
i
++
)
{
for
(
int
j
=
0
;
j
<
10
;
j
++
)
{
double
s
=
x
[
0
]
+
(
i
+
1
)
*
(
x
[
xsize
-
1
]
-
x
[
0
])
/
1
1
.0
;
double
t
=
y
[
0
]
+
(
j
+
1
)
*
(
y
[
ysize
-
1
]
-
y
[
0
])
/
1
1
.0
;
double
s
=
x
[
0
]
+
(
i
+
1
)
*
(
x
[
xsize
-
1
]
-
x
[
0
])
/
1
2
.0
;
double
t
=
y
[
0
]
+
(
j
+
1
)
*
(
y
[
ysize
-
1
]
-
y
[
0
])
/
1
2
.0
;
double
value
=
SplineFitter
::
evaluate2DSpline
(
x
,
y
,
f
,
c
,
s
,
t
);
ASSERT_EQUAL_TOL
(
sin
(
s
)
*
cos
(
0.4
*
t
),
value
,
0.02
);
double
dx
,
dy
;
...
...
@@ -118,11 +118,57 @@ void test2DSpline() {
}
}
void
test3DSpline
()
{
const
int
xsize
=
8
;
const
int
ysize
=
9
;
const
int
zsize
=
10
;
vector
<
double
>
x
(
xsize
);
vector
<
double
>
y
(
ysize
);
vector
<
double
>
z
(
zsize
);
vector
<
double
>
f
(
xsize
*
ysize
*
zsize
);
for
(
int
i
=
0
;
i
<
xsize
;
i
++
)
x
[
i
]
=
0.2
*
i
+
0.02
*
sin
(
0.4
*
double
(
i
));
for
(
int
i
=
0
;
i
<
ysize
;
i
++
)
y
[
i
]
=
0.2
*
i
+
0.02
*
sin
(
0.45
*
double
(
i
));
for
(
int
i
=
0
;
i
<
zsize
;
i
++
)
z
[
i
]
=
0.2
*
i
+
0.02
*
sin
(
0.5
*
double
(
i
));
for
(
int
i
=
0
;
i
<
xsize
;
i
++
)
for
(
int
j
=
0
;
j
<
ysize
;
j
++
)
for
(
int
k
=
0
;
k
<
zsize
;
k
++
)
f
[
i
+
j
*
xsize
+
k
*
xsize
*
ysize
]
=
sin
(
x
[
i
])
*
cos
(
0.4
*
y
[
j
])
*
(
1
+
z
[
k
]);
vector
<
vector
<
double
>
>
c
;
SplineFitter
::
create3DNaturalSpline
(
x
,
y
,
z
,
f
,
c
);
for
(
int
i
=
0
;
i
<
xsize
;
i
++
)
for
(
int
j
=
0
;
j
<
ysize
;
j
++
)
{
for
(
int
k
=
0
;
k
<
zsize
;
k
++
)
{
double
value
=
SplineFitter
::
evaluate3DSpline
(
x
,
y
,
z
,
f
,
c
,
x
[
i
],
y
[
j
],
z
[
k
]);
ASSERT_EQUAL_TOL
(
f
[
i
+
j
*
xsize
+
k
*
xsize
*
ysize
],
value
,
1e-6
);
}
}
for
(
int
i
=
0
;
i
<
10
;
i
++
)
{
for
(
int
j
=
0
;
j
<
10
;
j
++
)
{
for
(
int
k
=
0
;
k
<
10
;
k
++
)
{
double
s
=
x
[
0
]
+
(
i
+
1
)
*
(
x
[
xsize
-
1
]
-
x
[
0
])
/
12.0
;
double
t
=
y
[
0
]
+
(
j
+
1
)
*
(
y
[
ysize
-
1
]
-
y
[
0
])
/
12.0
;
double
u
=
z
[
0
]
+
(
k
+
1
)
*
(
z
[
zsize
-
1
]
-
z
[
0
])
/
12.0
;
double
value
=
SplineFitter
::
evaluate3DSpline
(
x
,
y
,
z
,
f
,
c
,
s
,
t
,
u
);
ASSERT_EQUAL_TOL
(
sin
(
s
)
*
cos
(
0.4
*
t
)
*
(
1
+
u
),
value
,
0.02
);
double
dx
,
dy
,
dz
;
SplineFitter
::
evaluate3DSplineDerivatives
(
x
,
y
,
z
,
f
,
c
,
s
,
t
,
u
,
dx
,
dy
,
dz
);
ASSERT_EQUAL_TOL
(
cos
(
s
)
*
cos
(
0.4
*
t
)
*
(
1
+
u
),
dx
,
0.1
);
ASSERT_EQUAL_TOL
(
-
0.4
*
sin
(
s
)
*
sin
(
0.4
*
t
)
*
(
1
+
u
),
dy
,
0.1
);
ASSERT_EQUAL_TOL
(
sin
(
s
)
*
cos
(
0.4
*
t
),
dz
,
0.1
);
}
}
}
}
int
main
()
{
try
{
testNaturalSpline
();
testPeriodicSpline
();
test2DSpline
();
test3DSpline
();
}
catch
(
const
exception
&
e
)
{
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment