31 namespace electron_density {
32 namespace SplineInterp {
34 void put_line(
double* data,
int dim,
int x1,
int x2,
double line[],
int dims[]) {
39 ptr = &data[x1*dims[2] + x2];
40 inc = dims[1]*dims[2];
41 }
else if (dim == 1) {
42 ptr = &data[x1*dims[1]*dims[2] + x2];
45 ptr = &data[x1*dims[1]*dims[2] + x2*dims[2]];
49 for (i=0; i<dims[dim]; i++) {
56 void get_line(
double* data,
int dim,
int x1,
int x2,
double line[],
int dims[]) {
61 ptr = &data[x1*dims[2] + x2];
62 inc = dims[1]*dims[2];
63 }
else if (dim == 1) {
64 ptr = &data[x1*dims[1]*dims[2] + x2];
67 ptr = &data[x1*dims[1]*dims[2] + x2*dims[2]];
71 for (i=0; i<dims[dim]; i++) {
92 if (Tolerance > 0.0) {
93 Horizon = (long)ceil(log(Tolerance) / log(fabs(z)));
95 if (Horizon < DataLength) {
99 for (n = 1
L; n < Horizon; n++) {
100 Sum += zn * c[DataLength - n];
109 for (n = 1
L; n < DataLength; n++) {
110 Sum += zn * c[DataLength - n];
113 return(Sum / (1.0 - zn));
132 Horizon = DataLength;
133 if (Tolerance > 0.0) {
134 Horizon = (long)ceil(log(Tolerance) / log(fabs(z)));
136 if (Horizon < DataLength) {
139 Sum = c[DataLength-1];
140 for (n = 0
L; n < Horizon; n++) {
149 Sum = c[DataLength-1];
150 for (n = 0
L; n < DataLength-1; n++) {
154 return(-z*Sum / (1.0 - zn));
174 if (DataLength == 1
L) {
178 for (k = 0
L; k < NbPoles; k++) {
179 Lambda = Lambda * (1.0 - z[k]) * (1.0 - 1.0 / z[k]);
182 for (n = 0
L; n < DataLength; n++) {
186 for (k = 0
L; k < NbPoles; k++) {
190 for (n = 1
L; n < DataLength; n++) {
191 c[n] += z[k] * c[n - 1
L];
196 for (n = DataLength - 2
L; 0 <= n; n--) {
197 c[n] = z[k] * (c[n + 1
L] - c[n]);
206 std::vector< double > line;
215 Pole[0] = sqrt(8.0) - 3.0;
219 Pole[0] = sqrt(3.0) - 2.0;
223 Pole[0] = sqrt(664.0 - sqrt(438976.0)) + sqrt(304.0) - 19.0;
224 Pole[1] = sqrt(664.0 + sqrt(438976.0)) - sqrt(304.0) - 19.0;
228 Pole[0] = sqrt(135.0 / 2.0 - sqrt(17745.0 / 4.0)) + sqrt(105.0 / 4.0)
230 Pole[1] = sqrt(135.0 / 2.0 + sqrt(17745.0 / 4.0)) - sqrt(105.0 / 4.0)
234 std::cerr <<
"Invalid spline degree\n";
242 line.resize( dims[0] );
243 if ((
int)line.size() != dims[0]) { std::cerr <<
"Row allocation failed\n";
return(1); }
244 for (y = 0
L; y < dims[1]; y++) {
245 for (z = 0
L; z < dims[2]; z++) {
246 get_line(data, 0, y, z, &line[0], dims);
248 put_line(data, 0, y, z, &line[0], dims);
255 line.resize( dims[1] );
256 if ((
int)line.size() != dims[1]) { std::cerr <<
"Row allocation failed\n";
return(1); }
257 for (x = 0
L; x < dims[0]; x++) {
258 for (z = 0
L; z < dims[2]; z++) {
259 get_line(data, 1, x, z, &line[0], dims);
261 put_line(data, 1, x, z, &line[0], dims);
268 line.resize( dims[2] );
269 if ((
int)line.size() != dims[2]) { std::cerr <<
"Row allocation failed\n";
return(1); }
270 for (x = 0
L; x < dims[0]; x++) {
271 for (y = 0
L; y < dims[1]; y++) {
272 get_line(data, 2, x, y, &line[0], dims);
274 put_line(data, 2, x, y, &line[0], dims);
283 int grad3(
double grad[3],
double *Bcoeff,
int dims[3],
double X[3],
int degree) {
285 double w, w2, w4,
t, t0, t1;
286 double sum_k, sum_jk;
288 int i,j,k, pt, dim, gradDim;
292 for (gradDim=0; gradDim<3; gradDim++) {
293 for (dim=0; dim<3; dim++) {
294 pt = (
int)floor(X[dim] - (degree-1) / 2.0);
295 for (i = 0
L; i <= degree; i++)
299 if (dim == gradDim) {
302 w = X[dim] - (double)idx[dim][1];
303 wt[dim][2] = 3.0 / 4.0 - w * w;
304 wt[dim][3] = (1.0 / 2.0) * (w - wt[dim][2] + 1.0);
305 wt[dim][1] = 1.0 - wt[dim][2] - wt[dim][3];
308 wt[dim][0] = - wt[dim][1];
309 wt[dim][1] = wt[dim][1] - wt[dim][2];
310 wt[dim][2] = wt[dim][2] - wt[dim][3];
313 std::cerr <<
"Invalid spline degree\n";
319 w = X[dim] - (double)idx[dim][1];
320 wt[dim][1] = 3.0 / 4.0 - w * w;
321 wt[dim][2] = (1.0 / 2.0) * (w - wt[dim][1] + 1.0);
322 wt[dim][0] = 1.0 - wt[dim][1] - wt[dim][2];
325 w = X[dim] - (double)idx[dim][1];
326 wt[dim][3] = (1.0 / 6.0) * w * w * w;
327 wt[dim][0] = (1.0 / 6.0) + (1.0 / 2.0) * w * (w - 1.0) - wt[dim][3];
328 wt[dim][2] = w + wt[dim][0] - 2.0 * wt[dim][3];
329 wt[dim][1] = 1.0 - wt[dim][0] - wt[dim][2] - wt[dim][3];
332 w = X[dim] - (double)idx[dim][2];
334 t = (1.0 / 6.0) * w2;
335 wt[dim][0] = 1.0 / 2.0 - w;
336 wt[dim][0] *= wt[dim][0];
337 wt[dim][0] *= (1.0 / 24.0) * wt[dim][0];
338 t0 = w * (t - 11.0 / 24.0);
339 t1 = 19.0 / 96.0 + w2 * (1.0 / 4.0 -
t);
340 wt[dim][1] = t1 + t0;
341 wt[dim][3] = t1 - t0;
342 wt[dim][4] = wt[dim][0] + t0 + (1.0 / 2.0) * w;
343 wt[dim][2] = 1.0 - wt[dim][0] - wt[dim][1] - wt[dim][3] - wt[dim][4];
346 w = X[dim] - (double)idx[dim][2];
348 wt[dim][5] = (1.0 / 120.0) * w * w2 * w2;
353 wt[dim][0] = (1.0 / 24.0) * (1.0 / 5.0 + w2 + w4) - wt[dim][5];
354 t0 = (1.0 / 24.0) * (w2 * (w2 - 5.0) + 46.0 / 5.0);
355 t1 = (-1.0 / 12.0) * w * (t + 4.0);
356 wt[dim][2] = t0 + t1;
357 wt[dim][3] = t0 - t1;
358 t0 = (1.0 / 16.0) * (9.0 / 5.0 -
t);
359 t1 = (1.0 / 24.0) * w * (w4 - w2 - 5.0);
360 wt[dim][1] = t0 + t1;
361 wt[dim][4] = t0 - t1;
364 std::cerr <<
"Invalid spline degree\n";
370 for (i = 0
L; i <= degree; i++) {
374 idx[dim][i] = idx[dim][i] % dims[dim];
376 idx[dim][i] += dims[dim];
381 for (i = 0; i <= degree; i++) {
385 for (j = 0; j <= degree; j++) {
387 for (k = 0; k <= degree; k++) {
388 sum_k += wt[2][k] * Bcoeff[idx[0][i]*dims[1]*dims[2] + idx[1][j]*dims[2] + idx[2][k]];
390 sum_jk += wt[1][j] * sum_k;
392 grad[gradDim] += wt[0][i] * sum_jk;
401 double interp3(
double *Bcoeff,
int dims[3],
double X[3],
int degree) {
404 double w, w2, w4,
t, t0, t1;
405 double sum_k, sum_jk;
410 for (dim=0; dim<3; dim++) {
411 pt = (
int)floor(X[dim] - (degree-1) / 2.0);
412 for (i = 0
L; i <= degree; i++)
418 w = X[dim] - (double)idx[dim][1];
419 wt[dim][1] = 3.0 / 4.0 - w * w;
420 wt[dim][2] = (1.0 / 2.0) * (w - wt[dim][1] + 1.0);
421 wt[dim][0] = 1.0 - wt[dim][1] - wt[dim][2];
424 w = X[dim] - (double)idx[dim][1];
425 wt[dim][3] = (1.0 / 6.0) * w * w * w;
426 wt[dim][0] = (1.0 / 6.0) + (1.0 / 2.0) * w * (w - 1.0) - wt[dim][3];
427 wt[dim][2] = w + wt[dim][0] - 2.0 * wt[dim][3];
428 wt[dim][1] = 1.0 - wt[dim][0] - wt[dim][2] - wt[dim][3];
431 w = X[dim] - (double)idx[dim][2];
433 t = (1.0 / 6.0) * w2;
434 wt[dim][0] = 1.0 / 2.0 - w;
435 wt[dim][0] *= wt[dim][0];
436 wt[dim][0] *= (1.0 / 24.0) * wt[dim][0];
437 t0 = w * (t - 11.0 / 24.0);
438 t1 = 19.0 / 96.0 + w2 * (1.0 / 4.0 -
t);
439 wt[dim][1] = t1 + t0;
440 wt[dim][3] = t1 - t0;
441 wt[dim][4] = wt[dim][0] + t0 + (1.0 / 2.0) * w;
442 wt[dim][2] = 1.0 - wt[dim][0] - wt[dim][1] - wt[dim][3] - wt[dim][4];
445 w = X[dim] - (double)idx[dim][2];
447 wt[dim][5] = (1.0 / 120.0) * w * w2 * w2;
452 wt[dim][0] = (1.0 / 24.0) * (1.0 / 5.0 + w2 + w4) - wt[dim][5];
453 t0 = (1.0 / 24.0) * (w2 * (w2 - 5.0) + 46.0 / 5.0);
454 t1 = (-1.0 / 12.0) * w * (t + 4.0);
455 wt[dim][2] = t0 + t1;
456 wt[dim][3] = t0 - t1;
457 t0 = (1.0 / 16.0) * (9.0 / 5.0 -
t);
458 t1 = (1.0 / 24.0) * w * (w4 - w2 - 5.0);
459 wt[dim][1] = t0 + t1;
460 wt[dim][4] = t0 - t1;
463 std::cerr <<
"Invalid spline degree\n";
468 for (i = 0
L; i <= degree; i++) {
472 idx[dim][i] = idx[dim][i] % dims[dim];
474 idx[dim][i] += dims[dim];
489 for (i = 0; i <= degree; i++) {
491 for (j = 0; j <= degree; j++) {
493 for (k = 0; k <= degree; k++) {
494 sum_k += wt[2][k] * Bcoeff[idx[0][i]*dims[1]*dims[2] + idx[1][j]*dims[2] + idx[2][k]];
496 sum_jk += wt[1][j] * sum_k;
498 value += wt[0][i] * sum_jk;