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
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