96 *method = fun.method[0];
99 for(
int i = 0; i < *n; i++) {
112 x = y = b = c = d = e = NULL;
121 (*this).copy_from(x);
143 for(
int i=0; i < *n; i++) {
147 spline_coef(method, n, x, y, b, c, d, e);
157 spline_eval(method, nu, u, v,
164 for (
int i=0; i<x.size(); i++) y[i] = (*
this)(x[i]);
185 void natural_spline(
int n, Type *x, Type *y, Type *b, Type *c, Type *d)
190 x--; y--; b--; c--; d--;
199 b[1] = t / (x[2]-x[1]);
201 c[1] = c[2] = d[1] = d[2] = 0.0;
211 c[2] = (y[2] - y[1])/d[1];
212 for( i=2 ; i<n ; i++) {
213 d[i] = x[i+1] - x[i];
214 b[i] = 2.0 * (d[i-1] + d[i]);
215 c[i+1] = (y[i+1] - y[i])/d[i];
216 c[i] = c[i+1] - c[i];
221 for(i=3 ; i<n ; i++) {
223 b[i] = b[i] - t*d[i-1];
224 c[i] = c[i] - t*c[i-1];
229 c[nm1] = c[nm1]/b[nm1];
230 for(i=n-2 ; i>1 ; i--)
231 c[i] = (c[i]-d[i]*c[i+1])/b[i];
239 b[1] = (y[2] - y[1])/d[1] - d[i] * c[2];
242 b[n] = (y[n] - y[nm1])/d[nm1] + d[nm1] * c[nm1];
243 for(i=2 ; i<n ; i++) {
244 b[i] = (y[i+1]-y[i])/d[i] - d[i]*(c[i+1]+2.0*c[i]);
245 d[i] = (c[i+1]-c[i])/d[i];
263 void fmm_spline(
int n, Type *x, Type *y, Type *b, Type *c, Type *d)
270 x--; y--; b--; c--; d--;
279 b[1] = t / (x[2]-x[1]);
281 c[1] = c[2] = d[1] = d[2] = 0.0;
291 c[2] = (y[2] - y[1])/d[1];
292 for(i=2 ; i<n ; i++) {
293 d[i] = x[i+1] - x[i];
294 b[i] = 2.0 * (d[i-1] + d[i]);
295 c[i+1] = (y[i+1] - y[i])/d[i];
296 c[i] = c[i+1] - c[i];
307 c[1] = c[3]/(x[4]-x[2]) - c[2]/(x[3]-x[1]);
308 c[n] = c[nm1]/(x[n] - x[n-2]) - c[n-2]/(x[nm1]-x[n-3]);
309 c[1] = c[1]*d[1]*d[1]/(x[4]-x[1]);
310 c[n] = -c[n]*d[nm1]*d[nm1]/(x[n]-x[n-3]);
315 for(i=2 ; i<=n ; i++) {
317 b[i] = b[i] - t*d[i-1];
318 c[i] = c[i] - t*c[i-1];
324 for(i=nm1 ; i>=1 ; i--)
325 c[i] = (c[i]-d[i]*c[i+1])/b[i];
330 b[n] = (y[n] - y[n-1])/d[n-1] + d[n-1]*(c[n-1]+ 2.0*c[n]);
331 for(i=1 ; i<=nm1 ; i++) {
332 b[i] = (y[i+1]-y[i])/d[i] - d[i]*(c[i+1]+2.0*c[i]);
333 d[i] = (c[i+1]-c[i])/d[i];
352 void periodic_spline(
int n, Type *x, Type *y,
353 Type *b, Type *c, Type *d, Type *e)
360 x--; y--; b--; c--; d--; e--;
362 if(n < 2 || y[1] != y[n]) {
368 b[1] = b[2] = c[1] = c[2] = d[1] = d[2] = 0.0;
371 b[1] = b[2] = b[3] = -(y[1] - y[2])*(x[1] - 2*x[2] + x[3])/(x[3]-x[2])/(x[2]-x[1]);
372 c[1] = -3*(y[1]-y[2])/(x[3]-x[2])/(x[2]-x[1]);
375 d[1] = -2*c[1]/3/(x[2]-x[1]);
376 d[2] = -d[1]*(x[2]-x[1])/(x[3]-x[2]);
392 B[nm1]= x[n] - x[nm1];
393 A[1] = 2.0 * (B[1] + B[nm1]);
394 C[1] = (y[2] - y[1])/B[1] - (y[n] - y[nm1])/B[nm1];
396 for(i = 2; i < n; i++) {
397 B[i] = x[i+1] - x[i];
398 A[i] = 2.0 * (B[i] + B[i-1]);
399 C[i] = (y[i+1] - y[i])/B[i] - (y[i] - y[i-1])/B[i-1];
409 E[1] = (x[n] - x[nm1])/L[1];
411 for(i = 1; i <= nm1 - 2; i++) {
413 if(i != 1) E[i] = -E[i-1] * M[i-1] / L[i];
414 L[i+1] = sqrt(A[i+1]-M[i]*M[i]);
417 M[nm1-1] = (B[nm1-1] - E[nm1-2] * M[nm1-2])/L[nm1-1];
418 L[nm1] = sqrt(A[nm1] - M[nm1-1]*M[nm1-1] - s);
427 for(i=2 ; i<=nm1-1 ; i++) {
428 Y[i] = (D[i] - M[i-1]*Y[i-1])/L[i];
429 s = s + E[i-1] * Y[i-1];
431 Y[nm1] = (D[nm1] - M[nm1-1] * Y[nm1-1] - s) / L[nm1];
435 X[nm1] = Y[nm1]/L[nm1];
436 X[nm1-1] = (Y[nm1-1] - M[nm1-1] * X[nm1])/L[nm1-1];
437 for(i=nm1-2 ; i>=1 ; i--)
438 X[i] = (Y[i] - M[i] * X[i+1] - E[i] * X[nm1])/L[i];
446 for(i=1 ; i<=nm1 ; i++) {
448 b[i] = (y[i+1]-y[i])/s - s*(c[i+1]+2.0*c[i]);
449 d[i] = (c[i+1]-c[i])/s;
467 void spline_coef(
int *method,
int *n, Type *x, Type *y,
468 Type *b, Type *c, Type *d, Type *e)
472 periodic_spline(*n, x, y, b, c, d, e);
break;
475 natural_spline(*n, x, y, b, c, d);
break;
478 fmm_spline(*n, x, y, b, c, d);
break;
482 void spline_eval(
int *method,
int *nu, Type *u, Type *v,
483 int *n, Type *x, Type *y, Type *b, Type *c, Type *d)
488 const int n_1 = *n - 1;
492 if(*method == 1 && *n > 1) {
494 for(l = 0; l < *nu; l++) {
497 v[l] = fmod(asDouble(u[l]-x[0]), asDouble(dx));
498 if(v[l] < 0.0) v[l] += dx;
503 for(l = 0; l < *nu; l++)
508 for(l = 0; l < *nu; l++) {
510 if(ul < x[i] || (i < n_1 && x[i+1] < ul)) {
523 tmp = (*method == 2 && ul < x[0]) ? 0.0 : d[i];
525 v[l] = y[i] + dx*(b[i] + dx*(c[i] + dx*tmp));
splinefun(const vector< Type > &x_, const vector< Type > &y_, int method_=3)
Construct spline function object.
Vector class used by TMB.
Type operator()(const Type &x_)
Evaluate spline - scalar argument case.
Utility functions for TMB (automatically included)