9 #include "boost/format.hpp"
14 namespace afwGeom = lsst::afw::geom;
16 namespace lsst {
namespace afw {
namespace math {
namespace detail {
18 static int search_array(
double z,
double const *
x,
int n,
int i);
29 for (
unsigned int i = 0; i !=
_coeffs.size(); ++i) {
39 std::vector<double> &
y
42 int const nknot =
_knots.size();
43 int const n = x.size();
54 for (
int i = 0; i != n; ++i) {
55 ind = search_array(x[i], &
_knots[0], nknot, ind);
59 }
else if(ind >= nknot) {
63 double const dx = x[i] -
_knots[ind];
74 std::vector<double> &dydx
77 int const nknot =
_knots.size();
78 int const n = x.size();
91 for (
int i = 0; i != n; ++i) {
92 ind = search_array(x[i], &
_knots[0], nknot, ind);
96 }
else if(ind >= nknot) {
100 double const dx = x[i] -
_knots[ind];
179 std::vector<double>
const&
y,
184 if(x.size() != y.size()) {
185 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
186 (
boost::format(
"TautSpline: x and y must have the same size; saw %d %d\n")
187 % x.size() % y.size()).str());
190 int const ntau = x.size();
192 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
214 std::vector<double>
const&
y,
218 const double *tau = &x[0];
219 const double *gtau = &y[0];
220 int const ntau = x.size();
223 int const nknot = ntau;
228 for (
int i = 1; i < nknot;i++) {
230 if(tau[i - 1] >= tau[i]) {
231 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
232 (
boost::format(
"point %d and the next, %f %f, are out of order")
233 % (i - 1) % tau[i - 1] % tau[i]).str());
239 _coeffs[1][0] = (gtau[1] - gtau[0])/(tau[1] - tau[0]);
243 _coeffs[1][1] = (gtau[1] - gtau[0])/(tau[1] - tau[0]);
246 double tmp = (tau[2]-tau[0])*(tau[2]-tau[1])*(tau[1]-tau[0]);
248 _coeffs[1][0] = ((gtau[1] - gtau[0])*pow(tau[2] - tau[0],2) -
249 (gtau[2] - gtau[0])*pow(tau[1] - tau[0],2))/tmp;
250 _coeffs[2][0] = -2*((gtau[1] - gtau[0])*(tau[2] - tau[0]) -
251 (gtau[2] - gtau[0])*(tau[1] - tau[0]))/tmp;
259 _coeffs[0][2] = gtau[2];
260 _coeffs[1][2] = _coeffs[1][0] + (tau[2] - tau[0])*_coeffs[2][0];
261 _coeffs[2][2] = _coeffs[2][0];
278 std::vector<std::vector<double> > s(6);
280 for (
int i = 0; i != 6; i++) {
287 for (
int i = 0; i < ntau - 1; i++) {
288 s[0][i] = tau[i + 1] - tau[i];
290 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
291 (
boost::format(
"point %d and the next, %f %f, are out of order")
292 % i % tau[i] % tau[i+1]).str());
294 s[3][i + 1] = (gtau[i + 1] - gtau[i])/s[0][i];
296 for (
int i = 1; i < ntau - 1; ++i) {
297 s[3][i] = s[3][i + 1] - s[3][i];
308 double gamma = gamma0;
311 }
else if(gamma > 3) {
317 double const onemg3 = 1 - gamma/3;
339 for (
int i = 1; i < ntau - 2; ++i) {
344 if((method == 2 && s[3][i]*s[3][i + 1] >= 0) || method == 3) {
345 double const temp = fabs(s[3][i + 1]);
346 double const denom = fabs(s[3][i]) + temp;
349 if (fabs(z - 0.5) <= 1.0/6.0) {
364 double temp = onemg3/onemzt;
365 alpha = (temp < 1 ? temp : 1);
366 factor = zeta/(alpha*(zt2 - 1) + 1);
367 s[5][i] = zeta*factor/6;
368 s[1][i] += s[0][i]*((1 - alpha*onemzt)*factor/2 - s[5][i]);
382 }
else if(z_half == 0) {
383 s[1][i] += s[0][i]/3;
386 onemzt = gamma*(1 - z);
388 double const temp = onemg3/zeta;
389 alpha = (temp < 1 ? temp : 1);
390 factor = onemzt/(1 - alpha*zeta*(onemzt + 1));
391 s[5][i] = onemzt*factor/6;
392 s[1][i] += s[0][i]/3;
393 s[2][i] = s[5][i]*s[0][i];
409 const double factr2 = zeta*(alpha*(zt2 - 1.) + 1.)/(alpha*(zeta*zt2 - 1.) + 1.);
410 ratio = factr2*s[0][1]/s[1][0];
411 s[1][1] = factr2*s[0][1] + s[0][0];
412 s[2][1] = -factr2*s[0][0];
413 }
else if (z_half == 0) {
414 ratio = s[0][1]/s[1][0];
415 s[1][1] = s[0][1] + s[0][0];
418 ratio = s[0][1]/s[1][0];
419 s[1][1] = s[0][1] + s[0][0];
420 s[2][1] = -s[0][0]*6*alpha*s[5][1];
430 s[1][1] += ratio*s[2][0];
431 s[2][1] += ratio*entry3;
432 s[3][1] = ratio*s[3][1];
440 s[1][i] += ratio*s[2][i - 1];
441 s[3][i] += ratio*s[3][i - 1];
447 ratio = -s[5][i]*s[0][i]/s[1][i];
448 s[1][i + 1] = s[0][i]/3;
449 }
else if(z_half == 0) {
450 ratio = -(s[0][i]/6)/s[1][i];
451 s[1][i + 1] = s[0][i]/3;
453 ratio = -(s[0][i]/6)/s[1][i];
454 s[1][i + 1] = s[0][i]*((1 - zeta*
alpha)*factor/2 - s[5][i]);
458 s[4][ntau - 2] = 0.5;
463 double const entry_ = ratio*s[2][ntau - 3] + s[1][ntau - 2] + s[0][ntau - 2]/3;
464 s[1][ntau - 1] = s[0][ntau - 2]/6;
465 s[3][ntau - 1] = ratio*s[3][ntau - 3] + s[3][ntau - 2];
467 ratio = s[0][ntau - 2]*6*s[5][ntau - 3]*alpha/s[1][ntau - 3];
468 s[1][ntau - 2] = ratio*s[2][ntau - 3] + s[0][ntau - 2] + s[0][ntau - 3];
469 s[2][ntau - 2] = -s[0][ntau - 3];
470 }
else if (z_half == 0) {
471 ratio = s[0][ntau - 2]/s[1][ntau - 3];
472 s[1][ntau - 2] = ratio*s[2][ntau - 3] + s[0][ntau - 2] + s[0][ntau - 3];
473 s[2][ntau - 2] = -s[0][ntau - 3];
475 const double factr2 = onemzt*(alpha*(onemzt*onemzt - 1) + 1)/(alpha*(onemzt*onemzt*onemzt - 1) + 1);
476 ratio = factr2*s[0][ntau - 2]/s[1][ntau - 3];
477 s[1][ntau - 2] = ratio*s[2][ntau - 3] + factr2*s[0][ntau - 3] + s[0][ntau - 2];
478 s[2][ntau - 2] = -factr2*s[0][ntau - 3];
486 s[3][ntau - 2] = ratio*s[3][ntau - 3];
487 ratio = -entry_/s[1][ntau - 2];
488 s[1][ntau - 1] += ratio*s[2][ntau - 2];
489 s[3][ntau - 1] += ratio*s[3][ntau - 2];
494 s[3][ntau - 1] /= s[1][ntau - 1];
495 for (
int i = ntau - 2; i > 0; --i) {
496 s[3][i] = (s[3][i] - s[2][i]*s[3][i + 1])/s[1][i];
499 s[3][0] = (s[3][0] - s[2][0]*s[3][1] - entry3*s[3][2])/s[1][0];
508 int const nknot0 = nknot;
511 for (
int i = 0; i < ntau - 1; ++i) {
512 double const z = s[4][i];
513 if((z < 0.5 && z != 0.0) || (z > 0.5 && (1 - z) != 0.0)) {
517 assert (nknot == nknot0);
524 for (
int i = 0; i < ntau - 1; ++i) {
527 double const divdif = (gtau[i + 1] - gtau[i])/s[0][i];
529 double const z_half = z - 0.5;
538 double const c = s[3][i + 1]/6;
539 double const d = s[3][i]*s[5][i];
542 double const del = zeta*s[0][i];
545 double temp = onemg3/onemzt;
546 alpha = (temp < 1 ? temp : 1);
547 factor = onemzt*onemzt*
alpha;
549 _coeffs[0][j] = gtau[i] + divdif*del + temp*temp*(d*onemzt*(factor - 1) + c*zeta*(zt2 - 1));
550 _coeffs[1][j] = divdif + s[0][i]*(d*(1 - 3*factor) + c*(3*zt2 - 1));
551 _coeffs[2][j] = (d*alpha*onemzt + c*zeta)*6;
552 _coeffs[3][j] = (c - d*
alpha)*6/s[0][i];
554 _coeffs[1][j - 1] = 0;
555 _coeffs[3][j - 1] = 0;
557 _coeffs[3][j - 1] = _coeffs[3][j] - d*6*(1 -
alpha)/(del*zt2);
558 _coeffs[1][j - 1] = _coeffs[1][j] -
559 del*(_coeffs[2][j] - del/2*_coeffs[3][j - 1]);
562 }
else if (z_half == 0) {
563 _coeffs[1][j] = divdif - s[0][i]*(s[3][i]*2 + s[3][i + 1])/6;
564 _coeffs[3][j] = (s[3][i + 1] - s[3][i])/s[0][i];
566 onemzt = gamma*(1 - z);
573 double const temp = onemg3/zeta;
574 alpha = (temp < 1 ? temp : 1);
575 double const c = s[3][i + 1]*s[5][i];
576 double const d = s[3][i]/6;
577 double const del = zeta*s[0][i];
578 _knots[j + 1] = tau[i] + del;
579 _coeffs[1][j] = divdif - s[0][i]*(2*d + c);
580 _coeffs[3][j] = (c*alpha - d)*6/s[0][i];
583 _coeffs[3][j] = _coeffs[3][j - 1] +
584 (1 -
alpha)*6*c/(s[0][i]*(onemzt*onemzt*onemzt));
585 _coeffs[2][j] = _coeffs[2][j - 1] + del*_coeffs[3][j - 1];
586 _coeffs[1][j] = _coeffs[1][j - 1] +
587 del*(_coeffs[2][j - 1] + del/2*_coeffs[3][j - 1]);
588 _coeffs[0][j] = _coeffs[0][j - 1] +
589 del*(_coeffs[1][j - 1] +
590 del/2*(_coeffs[2][j - 1] + del/3*_coeffs[3][j - 1]));
606 double const del = tau[ntau - 1] -
_knots[nknot - 2];
613 _coeffs[2][nknot - 1] = _coeffs[2][nknot - 2] + del*_coeffs[3][nknot - 2];
614 _coeffs[3][nknot - 1] = _coeffs[3][nknot - 2];
616 assert (j + 1 == nknot);
624 spcof1(
const double x[],
double avh,
const double y[],
const double dy[],
625 int n,
double p,
double q,
double a[],
double *c[3],
double u[],
629 sperr1(
const double x[],
double avh,
const double dy[],
int n,
630 double *r[3],
double p,
double var, std::vector<double> *se);
633 spfit1(
const double x[],
double avh,
const double dy[],
int n,
634 double rho,
double *p,
double *q,
double var,
double stat[],
635 const double a[],
double *c[3],
double *r[3],
double *t[2],
636 double u[],
double v[]);
639 spint1(
const double x[],
double *avh,
const double y[],
double dy[],
int n,
640 double a[],
double *c[3],
double *r[3],
double *t[2]);
711 std::vector<double>
const&
x,
712 std::vector<double>
const& f,
713 std::vector<double>
const& df,
716 std::vector<double> *errs
720 int const n = x.size();
721 double const ratio = 2.0;
722 double const tau = 1.618033989;
723 double avdf, avar, stat[6];
724 double p, q, delta, r1, r2, r3, r4;
725 double gf1, gf2, gf3, gf4, avh, err;
737 std::vector<double> scratch(7*(n+2));
740 r[0] = &scratch[0] + 1;
741 r[1] = r[0] + (n + 2);
742 r[2] = r[1] + (n + 2);
744 t[0] = r[2] + (n + 2);
745 t[1] = t[0] + (n + 2);
746 double *u = t[1] + (n + 2);
747 double *v = u + (n + 2);
751 std::vector<double> sdf = df;
753 avdf = spint1(&x[0], &avh, &f[0], &sdf[0], n, y, c, r, t);
762 gf1 = spfit1(&x[0], avh, &sdf[0], n, r1, &p, &q, avar, stat, y, c, r, t, u, v);
767 gf2 = spfit1(&x[0], avh, &sdf[0], n, r2, &p, &q, avar, stat, y, c, r, t, u, v);
770 gf1 = spfit1(&x[0], avh, &sdf[0], n, r1, &p, &q, avar, stat, y, c, r, t, u,v);
791 gf3 = spfit1(&x[0], avh, &sdf[0], n, r3, &p, &q, avar, stat, y, c, r, t, u, v);
809 delta = (r2 - r1) / tau;
812 gf3 = spfit1(&x[0], avh, &sdf[0], n, r3, &p, &q, avar, stat, y, c, r, t, u, v);
813 gf4 = spfit1(&x[0], avh, &sdf[0], n, r4, &p, &q, avar, stat, y, c, r, t, u, v);
825 gf3 = spfit1(&x[0], avh, &sdf[0], n, r3, &p, &q, avar, stat, y, c, r, t, u, v);
833 gf4 = spfit1(&x[0], avh, &sdf[0], n, r4, &p, &q, avar, stat, y, c, r, t, u, v);
836 err = (r2 - r1) / (r1 + r2);
837 }
while(err*err + 1 > 1 && err > 1e-6);
840 gf1 = spfit1(&x[0], avh, &sdf[0], n, r1, &p, &q, avar, stat, y, c, r, t, u,v);
846 spcof1(&x[0], avh, &f[0], &sdf[0], n, p, q, y, c, u, v);
848 stat[2] /= avdf*avdf;
849 stat[3] /= avdf*avdf;
850 stat[4] /= avdf*avdf;
855 sperr1(&x[0], avh, &sdf[0], n, r, p, avar, errs);
876 spint1(
const double x[],
895 for (i = 0; i < n - 1; ++i) {
906 for (
int i = 0; i < n; ++i) {
913 for (i = 0; i < n; ++i) {
919 h = (x[1] - x[0])/(*avh);
920 ff = (f[1] - f[0])/h;
924 for (i = 1; i < n - 1; ++i) {
926 h = (x[i + 1] - x[i])/(*avh);
928 ff = (f[i + 1] - f[i])/h;
930 t[0][i] = (g + h) * 2./3.;
932 r[2][i] = df[i - 1]/g;
933 r[0][i] = df[i + 1]/h;
934 r[1][i] = -df[i]/g - df[i]/h;
943 for (i = 1; i < n - 1; i++) {
944 c[0][i] = r[0][i]*r[0][i] + r[1][i]*r[1][i] + r[2][i]*r[2][i];
945 c[1][i] = r[0][i]*r[1][i+1] + r[1][i]*r[2][i+1];
946 c[2][i] = r[0][i]*r[2][i+2];
979 spfit1(
const double x[],
995 double const eps = std::numeric_limits<double>::epsilon();
1003 if(fabs(rho) < eps) {
1005 }
else if(fabs(1/rho) < eps) {
1017 r[0][-1] = r[0][0] = 0;
1019 for (
int i = 1; i < n - 1; ++i) {
1020 r[2][i-2] = g*r[0][i - 2];
1021 r[1][i-1] = f*r[0][i - 1];
1023 double tmp = p*c[0][i] + q*t[0][i] - f*r[1][i-1] - g*r[2][i-2];
1030 f = p*c[1][i] + q*t[1][i] - h*r[1][i-1];
1038 for (
int i = 1; i < n - 1; i++) {
1039 u[i] = a[i] - r[1][i-1]*u[i-1] - r[2][i-2]*u[i-2];
1042 for (
int i = n - 2; i > 0; i--) {
1043 u[i] = r[0][i]*u[i] - r[1][i]*u[i+1] - r[2][i]*u[i+2];
1049 for (
int i = 0; i < n - 1; i++) {
1051 h = (u[i + 1] - u[i])/((x[i+1] - x[i])/avh);
1052 v[i] = dy[i]*(h - g);
1055 v[n-1] = -h*dy[n-1];
1060 r[0][n-1] = r[1][n-1] = r[0][n] = 0;
1061 for (i = n - 2; i > 0; i--) {
1064 r[1][i] = -g*r[0][i+1] - h*r[1][i+1];
1065 r[2][i] = -g*r[1][i+1] - h*r[0][i+2];
1066 r[0][i] = r[0][i] - g*r[1][i] - h*r[2][i];
1072 for (i = 1; i < n - 1; ++i) {
1073 f += r[0][i]*c[0][i];
1074 g += r[1][i]*c[1][i];
1075 h += r[2][i]*c[2][i];
1083 stat[2] = n*e/(f*f + 1e-20);
1085 stat[5] = e*p/((f < 0) ? f - 1e-10 : f + 1e-10);
1087 fun = stat[3] - 2*var*stat[1]/n + var;
1091 stat[4] = stat[5] - stat[3];
1105 spcof1(
const double x[],
1123 for (i = 0; i < n; ++i) {
1124 a[i] = y[i] - p * dy[i] * v[i];
1130 for (i = 0; i < n - 1; ++i) {
1132 c[2][i] = (u[i + 1] - u[i])/(3*h);
1133 c[0][i] = (a[i + 1] - a[i])/h - (h*c[2][i] + u[i])*h;
1145 sperr1(
const double x[],
1152 std::vector<double> *se)
1160 h = avh/(x[1] - x[0]);
1161 (*se)[0] = 1 - p*dy[0]*dy[0]*h*h*r[0][1];
1162 r[0][0] = r[1][0] = r[2][0] = 0;
1166 for (i = 1; i < n - 1; ++i) {
1168 h = avh/(x[i+1] - x[i]);
1170 f1 = f*r[0][i-1] + g*r[1][i-1] + h*r[2][i-1];
1171 g1 = f*r[1][i-1] + g*r[0][i] + h*r[1][i];
1172 h1 = f*r[2][i-1] + g*r[1][i] + h*r[0][i+1];
1173 (*se)[i] = 1 - p*dy[i]*dy[i]*(f*f1 + g*g1 + h*h1);
1175 (*se)[n-1] = 1 - p*dy[n-1]*dy[n-1]*h*h*r[0][n-2];
1179 for (
int i = 0; i < n; ++i) {
1180 double const tmp = (*se)[i]*var;
1181 (*se)[i] = (tmp >= 0) ? sqrt(tmp)*dy[i] : 0;
1200 std::vector<double>
const& _gtau,
1205 const double *tau = &_tau[0];
1206 const double *gtau = &_gtau[0];
1207 int const ntau = _tau.size();
1208 std::vector<double>
x,
y;
1210 if(tau[0] == 0.0f) {
1211 int const np = 2*ntau - 1;
1215 x[ntau - 1] = tau[0]; y[ntau - 1] = gtau[0];
1216 for (
int i = 1; i != ntau; ++i) {
1218 x[ntau - 1 + i] = tau[i]; y[ntau - 1 + i] = gtau[i];
1219 x[ntau - 1 - i] = -tau[i]; y[ntau - 1 - i] = gtau[i];
1221 x[ntau - 1 + i] = tau[i]; y[ntau - 1 + i] = gtau[i];
1222 x[ntau - 1 - i] = -tau[i]; y[ntau - 1 - i] = -gtau[i];
1226 int const np = 2*ntau;
1230 for (
int i = 0; i != ntau; ++i) {
1232 x[ntau + i] = tau[i]; y[ntau + i] = gtau[i];
1233 x[ntau - 1 - i] = -tau[i]; y[ntau - 1 - i] = gtau[i];
1235 x[ntau + i] = tau[i]; y[ntau + i] = gtau[i];
1236 x[ntau - 1 - i] = -tau[i]; y[ntau - 1 - i] = -gtau[i];
1246 for (ii = sp.
_knots.size() - 1; ii >= 0; --ii) {
1247 if(sp.
_knots[ii] < 0.0f) {
1251 int const i0 = ii + 1;
1252 int const nknot = sp.
_knots.size() - i0;
1256 for (
int i = i0; i !=
static_cast<int>(sp.
_knots.size()); ++i) {
1258 for (
int j = 0; j != 4; ++j) {
1271 search_array(
double z,
double const *x,
int n,
int i)
1276 if(i < 0 || i >= n) {
1280 unsigned int step = 1;
1287 lo = i; hi = lo + 1;
1317 while(hi - lo > 1) {
1335 while(lo < n - 1 && x[lo + 1] == xm) lo++;
1345 keep_valid_roots(std::vector<double>& roots,
1346 std::vector<double>& newRoots,
double x0,
double x1)
1348 for (
unsigned int i = 0; i != newRoots.size(); ++i) {
1349 if(newRoots[i] >= x0 && newRoots[i] < x1) {
1350 roots.push_back(newRoots[i]);
1363 do_quadratic(
double a,
double b,
double c, std::vector<double> & roots)
1365 if(::fabs(a) < std::numeric_limits<double>::epsilon()) {
1366 if(::fabs(b) >= std::numeric_limits<double>::epsilon()) {
1367 roots.push_back(-c/b);
1370 double const tmp = b*b - 4*a*c;
1374 roots.push_back((-b - sqrt(tmp))/(2*a));
1376 roots.push_back((-b + sqrt(tmp))/(2*a));
1378 roots.push_back(c/(a*roots[0]));
1382 if(roots[0] > roots[1]) {
1383 double const tmp2 = roots[0]; roots[0] = roots[1]; roots[1] = tmp2;
1394 do_cubic(
double a,
double b,
double c,
double d, std::vector<double> & roots)
1396 if (::fabs(a) < std::numeric_limits<double>::epsilon()) {
1397 do_quadratic(b, c, d, roots);
1400 b /= a; c /= a; d /= a;
1402 double const q = (b*b - 3*c)/9;
1403 double const r = (2*b*b*b - 9*b*c + 27*d)/54;
1409 double const sq = (q >= 0) ? sqrt(q) : -sqrt(-q);
1410 double const sq3 = sq*sq*sq;
1411 if(::fabs(r) < sq3) {
1412 double const theta = ::acos(r/sq3);
1414 roots.push_back(-2*sq*cos(theta/3) - b/3);
1420 if(roots[0] > roots[1]) {
1423 if(roots[1] > roots[2]) {
1426 if(roots[0] > roots[1]) {
1431 }
else if(::fabs(r) == sq3) {
1432 double const aa = -((r < 0) ? -::pow(-r,1.0/3.0) : ::pow(r,1.0/3.0));
1434 if(::fabs(aa) < std::numeric_limits<double>::epsilon()) {
1435 roots.push_back(-b/3);
1438 roots.push_back(2*aa - b/3);
1439 roots.push_back(-aa - b/3);
1441 if(roots[0] > roots[1]) {
1448 double tmp = ::sqrt(r*r - (q > 0 ? sq3*sq3 : -sq3*sq3));
1449 tmp = r + (r < 0 ? -tmp : tmp);
1450 double const aa = -((tmp < 0) ? -::pow(-tmp,1.0/3.0) : ::pow(tmp,1.0/3.0));
1451 double const bb = (fabs(aa) < std::numeric_limits<double>::epsilon()) ? 0 : q/aa;
1453 roots.push_back((aa + bb) - b/3);
1455 roots.push_back(-(aa + bb)/2 - b/3);
1456 roots.push_back(::sqrt(3)/2*(aa - bb));
1484 std::vector<double>
roots;
1486 double const x1 =
b;
1487 int const nknot =
_knots.size();
1489 int i0 = search_array(x0, &
_knots[0], nknot, -1);
1490 int const i1 = search_array(x1, &
_knots[0], nknot, i0);
1491 assert (i1 >= i0 && i1 <= nknot - 1);
1493 std::vector<double> newRoots;
1507 for (
unsigned int j = 0; j != newRoots.size(); ++j) {
1508 newRoots[j] +=
_knots[i0];
1510 keep_valid_roots(roots, newRoots, x0,
_knots[i0]);
1513 }
else if(i0 >= nknot) {
1518 for (
unsigned int j = 0; j != newRoots.size(); ++j) {
1519 newRoots[j] +=
_knots[i0];
1521 keep_valid_roots(roots, newRoots, x0, x1);
1529 for (
int i = i0;i <= i1;i++) {
1532 for (
unsigned int j = 0; j != newRoots.size(); ++j) {
1533 newRoots[j] +=
_knots[i];
1535 keep_valid_roots(roots, newRoots, ((i == i0) ? x0 :
_knots[i]), ((i == i1) ? x1 :
_knots[i + 1]));
std::vector< std::vector< double > > _coeffs
SmoothedSpline(std::vector< double > const &x, std::vector< double > const &y, std::vector< double > const &dy, double s, double *chisq=NULL, std::vector< double > *errs=NULL)
void swap(ImageBase< PixelT > &a, ImageBase< PixelT > &b)
std::vector< double > roots(double const value, double const x0, double const x1) const
void interpolate(std::vector< double > const &x, std::vector< double > &y) const
void derivative(std::vector< double > const &x, std::vector< double > &dydx) const
TautSpline(std::vector< double > const &x, std::vector< double > const &y, double const gamma=0, Symmetry type=Unknown)
std::vector< double > _knots
#define LSST_EXCEPT(type,...)
void _allocateSpline(int const nknot)
afw::table::Key< double > b
void calculateTautSpline(std::vector< double > const &x, std::vector< double > const &y, double const gamma0)
void calculateTautSplineEvenOdd(std::vector< double > const &x, std::vector< double > const &y, double const gamma0, bool even)