ADMB Documentation  -a65f1c97
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cspline.cpp
Go to the documentation of this file.
1 
6 #include <fvar.hpp>
7 
8 dvector spline(const dvector &x,const dvector&y,double yp1,double ypn);
9 
10 double splint(const dvector& xa,const dvector& ya,const dvector& y2a,double x);
11 
13  const dvector& _y,double yp1,double ypn) : x(_x) , y(_y)
14 {
15  y2.allocate(x);
16  y2=spline(x,y,yp1,ypn);
17 }
18 
20 {
21  // need to deal with u<x(1) or u>x(2)
22  return splint(x,y,y2,u);
23 }
24 
26 {
27  int mmin=u.indexmin();
28  int mmax=u.indexmax();
29  dvector z(mmin,mmax);
30  for (int i=mmin;i<=mmax;i++)
31  {
32  z(i)=splint(x,y,y2,u(i));
33  }
34  return z;
35 }
36 
37 dvector spline(const dvector &_x,const dvector&_y,double yp1,double ypn)
38 {
39  dvector& x=(dvector&) _x;
40  dvector& y=(dvector&) _y;
41  int orig_min=x.indexmin();
42  x.shift(1);
43  y.shift(1);
44  // need to check that x is monotone increasing;
45  if ( x.indexmax() != y.indexmax() )
46  {
47  cerr << " Incompatible bounds in input to spline" << endl;
48  }
49  int n=x.indexmax();
50  dvector y2(1,n);
51  int i,k;
52  double p,qn,sig,un;
53 
54  dvector u(1,n-1);
55  if (yp1 > 0.99e30)
56  {
57  y2[1]=u[1]=0.0;
58  }
59  else
60  {
61  y2[1] = -0.5;
62  u[1]=(3.0/(x[2]-x[1]))*((y[2]-y[1])/(x[2]-x[1])-yp1);
63  }
64  for (i=2;i<=n-1;i++)
65  {
66  sig=(x[i]-x[i-1])/(x[i+1]-x[i-1]);
67  p=sig*y2[i-1]+2.0;
68  y2[i]=(sig-1.0)/p;
69  u[i]=(y[i+1]-y[i])/(x[i+1]-x[i]) - (y[i]-y[i-1])/(x[i]-x[i-1]);
70  u[i]=(6.0*u[i]/(x[i+1]-x[i-1])-sig*u[i-1])/p;
71  }
72  if (ypn > 0.99e30)
73  {
74  qn=un=0.0;
75  }
76  else
77  {
78  qn=0.5;
79  un=(3.0/(x[n]-x[n-1]))*(ypn-(y[n]-y[n-1])/(x[n]-x[n-1]));
80  }
81  y2[n]=(un-qn*u[n-1])/(qn*y2[n-1]+1.0);
82  for (k=n-1;k>=1;k--)
83  {
84  y2[k]=y2[k]*y2[k+1]+u[k];
85  }
86  x.shift(orig_min);
87  y.shift(orig_min);
88  y2.shift(orig_min);
89  return y2;
90 }
91 
92 double splint(const dvector& _xa,const dvector& _ya,const dvector& _y2a,
93  double x)
94 {
95  dvector& xa=(dvector&) _xa;
96  dvector& ya=(dvector&) _ya;
97  dvector& y2a=(dvector&) _y2a;
98  int orig_min=xa.indexmin();
99  xa.shift(1);
100  ya.shift(1);
101  y2a.shift(1);
102  double y;
103  int n = xa.indexmax();
104  int klo,khi,k;
105  double h,b,a;
106 
107  klo=1;
108  khi=n;
109  while (khi-klo > 1)
110  {
111  k=(khi+klo) >> 1;
112  if (xa[k] > x) khi=k;
113  else klo=k;
114  }
115  h=xa[khi]-xa[klo];
116  a=(xa[khi]-x)/h;
117  b=(x-xa[klo])/h;
118  y=a*ya[klo]+b*ya[khi]+((a*a*a-a)*y2a[klo]+(b*b*b-b)*y2a[khi])*(h*h)/6.0;
119  xa.shift(orig_min);
120  ya.shift(orig_min);
121  y2a.shift(orig_min);
122  return y;
123 }
double operator()(double u)
Definition: cspline.cpp:19
#define x
Vector of double precision numbers.
Definition: dvector.h:50
int indexmin() const
Get minimum valid index.
Definition: dvector.h:199
void allocate(int ncl, int ncu)
Allocate memory for a dvector.
Definition: dvector.cpp:409
cubic_spline_function(const dvector &_x, const dvector &_y, double yp1=0.0, double ypn=0.0)
Definition: cspline.cpp:12
double splint(const dvector &xa, const dvector &ya, const dvector &y2a, double x)
Definition: cspline.cpp:92
prnstream & endl(prnstream &)
int indexmax() const
Get maximum valid index.
Definition: dvector.h:204
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
dvector spline(const dvector &x, const dvector &y, double yp1, double ypn)
Definition: cspline.cpp:37
dvector * h
Definition: fvar.hpp:3647
dvector & shift(int min)
Shift valid range of subscripts.
Definition: dvector.cpp:52