00001 #include<cmath>
00002 #include<stdio.h>
00003 #include<string.h>
00004
00005 #include<iostream>
00006 #include<fstream>
00007
00008 #include "TRadSpline.h"
00009
00010 using namespace std;
00011
00013
00014
00015
00016
00017
00018
00019
00021
00022
00023
00024 TRadSpline3::TRadSpline3(const char *title,
00025 double x[], double y[], int n, const char *opt,
00026 double valbeg, double valend) :
00027 TRadSpline(title,-1,x[0],x[n-1],n,false),
00028 fValBeg(valbeg), fValEnd(valend), fBegCond(0), fEndCond(0)
00029 {
00030
00031
00032
00033
00034
00035
00036
00037
00038 if(opt) SetCond(opt);
00039
00040
00041
00042 fPoly = new TRadSplinePoly3[n];
00043 for (int i=0; i<n; ++i) {
00044 fPoly[i].X() = x[i];
00045 fPoly[i].Y() = y[i];
00046 }
00047
00048
00049 BuildCoeff();
00050 }
00051
00052
00053 TRadSpline3::TRadSpline3(const char *title,
00054 double xmin, double xmax,
00055 double y[], int n, const char *opt,
00056 double valbeg, double valend) :
00057 TRadSpline(title,(xmax-xmin)/(n-1), xmin, xmax, n, true),
00058 fValBeg(valbeg), fValEnd(valend),
00059 fBegCond(0), fEndCond(0)
00060 {
00061
00062
00063
00064
00065
00066
00067
00068
00069 if(opt) SetCond(opt);
00070
00071
00072
00073 fPoly = new TRadSplinePoly3[n];
00074 for (int i=0; i<n; ++i) {
00075 fPoly[i].X() = fXmin+i*fDelta;
00076 fPoly[i].Y() = y[i];
00077 }
00078
00079
00080 BuildCoeff();
00081 }
00082
00083 TRadSpline3::TRadSpline3(const char *title,
00084 double xmin, double xmax,
00085 double (*func)(const double&), int n, const char *opt,
00086 double valbeg, double valend) :
00087 TRadSpline(title,(xmax-xmin)/(n-1), xmin, xmax, n, true),
00088 fValBeg(valbeg), fValEnd(valend),
00089 fBegCond(0), fEndCond(0)
00090 {
00091
00092
00093
00094
00095
00096
00097
00098
00099 if(opt) SetCond(opt);
00100
00101
00102 fPoly = new TRadSplinePoly3[n];
00103 for (int i=0; i<n; ++i) {
00104 double x=fXmin+i*fDelta;
00105 fPoly[i].X() = x;
00106 fPoly[i].Y() = func(x);
00107 }
00108
00109 BuildCoeff();
00110 }
00111
00112 void TRadSpline3::SetCond(const char *opt)
00113 {
00114
00115
00116
00117 const char *b1 = strstr(opt,"b1");
00118 const char *e1 = strstr(opt,"e1");
00119 const char *b2 = strstr(opt,"b2");
00120 const char *e2 = strstr(opt,"e2");
00121 if (b1 && b2)
00122 printf("%s %s\n","SetCond","Cannot specify first and second derivative at first point");
00123 if (e1 && e2)
00124 printf("%s %s\n","SetCond","Cannot specify first and second derivative at last point");
00125 if (b1) fBegCond=1;
00126 else if (b2) fBegCond=2;
00127 if (e1) fEndCond=1;
00128 else if (e2) fEndCond=2;
00129 }
00130
00131
00132 void TRadSpline3::Test()
00133 {
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 double hx;
00158 double diff[3];
00159 double a[800], c[4];
00160 int i, j, k, m, n;
00161 double x[200], y[200], z;
00162 int jj, mm;
00163 int mm1, nm1;
00164 double com[3];
00165 printf("1 TEST OF TRadSpline3 WITH NONEQUIDISTANT KNOTS\n");
00166 n = 5;
00167 x[0] = -3;
00168 x[1] = -1;
00169 x[2] = 0;
00170 x[3] = 3;
00171 x[4] = 4;
00172 y[0] = 7;
00173 y[1] = 11;
00174 y[2] = 26;
00175 y[3] = 56;
00176 y[4] = 29;
00177 m = 2;
00178 mm = m << 1;
00179 mm1 = mm-1;
00180 printf("\n-N = %3d M =%2d\n",n,m);
00181 TRadSpline3 *spline = new TRadSpline3("Test",x,y,n);
00182 for (i = 0; i < n; ++i)
00183 spline->GetCoeff(i,hx, a[i],a[i+200],a[i+400],a[i+600]);
00184 delete spline;
00185 for (i = 0; i < mm1; ++i) diff[i] = com[i] = 0;
00186 for (k = 0; k < n; ++k) {
00187 for (i = 0; i < mm; ++i) c[i] = a[k+i*200];
00188 printf(" ---------------------------------------%3d --------------------------------------------\n",k+1);
00189 printf("%12.8f\n",x[k]);
00190 if (k == n-1) {
00191 printf("%16.8f\n",c[0]);
00192 } else {
00193 for (i = 0; i < mm; ++i) printf("%16.8f",c[i]);
00194 printf("\n");
00195 for (i = 0; i < mm1; ++i)
00196 if ((z=fabs(a[k+i*200])) > com[i]) com[i] = z;
00197 z = x[k+1]-x[k];
00198 for (i = 1; i < mm; ++i)
00199 for (jj = i; jj < mm; ++jj) {
00200 j = mm+i-jj;
00201 c[j-2] = c[j-1]*z+c[j-2];
00202 }
00203 for (i = 0; i < mm; ++i) printf("%16.8f",c[i]);
00204 printf("\n");
00205 for (i = 0; i < mm1; ++i)
00206 if (!(k >= n-2 && i != 0))
00207 if((z = fabs(c[i]-a[k+1+i*200]))
00208 > diff[i]) diff[i] = z;
00209 }
00210 }
00211 printf(" MAXIMUM ABSOLUTE VALUES OF DIFFERENCES \n");
00212 for (i = 0; i < mm1; ++i) printf("%18.9E",diff[i]);
00213 printf("\n");
00214 printf(" MAXIMUM ABSOLUTE VALUES OF COEFFICIENTS \n");
00215 if (fabs(c[0]) > com[0])
00216 com[0] = fabs(c[0]);
00217 for (i = 0; i < mm1; ++i) printf("%16.8f",com[i]);
00218 printf("\n");
00219 m = 2;
00220 for (n = 10; n <= 100; n += 10) {
00221 mm = m << 1;
00222 mm1 = mm-1;
00223 nm1 = n-1;
00224 for (i = 0; i < nm1; i += 2) {
00225 x[i] = i+1;
00226 x[i+1] = i+2;
00227 y[i] = 1;
00228 y[i+1] = 0;
00229 }
00230 if (n % 2 != 0) {
00231 x[n-1] = n;
00232 y[n-1] = 1;
00233 }
00234 printf("\n-N = %3d M =%2d\n",n,m);
00235 spline = new TRadSpline3("Test",x,y,n);
00236 for (i = 0; i < n; ++i)
00237 spline->GetCoeff(i,hx,a[i],a[i+200],a[i+400],a[i+600]);
00238 delete spline;
00239 for (i = 0; i < mm1; ++i)
00240 diff[i] = com[i] = 0;
00241 for (k = 0; k < n; ++k) {
00242 for (i = 0; i < mm; ++i)
00243 c[i] = a[k+i*200];
00244 if (n < 11) {
00245 printf(" ---------------------------------------%3d --------------------------------------------\n",k+1);
00246 printf("%12.8f\n",x[k]);
00247 if (k == n-1) printf("%16.8f\n",c[0]);
00248 }
00249 if (k == n-1) break;
00250 if (n <= 10) {
00251 for (i = 0; i < mm; ++i) printf("%16.8f",c[i]);
00252 printf("\n");
00253 }
00254 for (i = 0; i < mm1; ++i)
00255 if ((z=fabs(a[k+i*200])) > com[i])
00256 com[i] = z;
00257 z = x[k+1]-x[k];
00258 for (i = 1; i < mm; ++i)
00259 for (jj = i; jj < mm; ++jj) {
00260 j = mm+i-jj;
00261 c[j-2] = c[j-1]*z+c[j-2];
00262 }
00263 if (n <= 10) {
00264 for (i = 0; i < mm; ++i) printf("%16.8f",c[i]);
00265 printf("\n");
00266 }
00267 for (i = 0; i < mm1; ++i)
00268 if (!(k >= n-2 && i != 0))
00269 if ((z = fabs(c[i]-a[k+1+i*200]))
00270 > diff[i]) diff[i] = z;
00271 }
00272 printf(" MAXIMUM ABSOLUTE VALUES OF DIFFERENCES \n");
00273 for (i = 0; i < mm1; ++i) printf("%18.9E",diff[i]);
00274 printf("\n");
00275 printf(" MAXIMUM ABSOLUTE VALUES OF COEFFICIENTS \n");
00276 if (fabs(c[0]) > com[0])
00277 com[0] = fabs(c[0]);
00278 for (i = 0; i < mm1; ++i) printf("%16.8E",com[i]);
00279 printf("\n");
00280 }
00281 }
00282
00283
00284
00285 int TRadSpline3::FindX(double x) const
00286 {
00287 int klow=0;
00288
00289
00290
00291 if(x<=fXmin) klow=0;
00292 else if(x>=fXmax) klow=fNp-1;
00293 else {
00294 if(fKstep) {
00295
00296
00297 klow = (int((x-fXmin)/fDelta)<fNp-1)?int((x-fXmin)/fDelta):fNp-1;
00298 } else {
00299 int khig=fNp-1, khalf;
00300
00301
00302 while(khig-klow>1)
00303 if(x>fPoly[khalf=(klow+khig)/2].X())
00304 klow=khalf;
00305 else
00306 khig=khalf;
00307 }
00308
00309
00310 if(!(fPoly[klow].X()<=x && x<=fPoly[klow+1].X()))
00311 printf("Binary search failed x(%d) = %f < %f < x(%d) = %f\n",
00312 klow, fPoly[klow].X(), x, klow+1, fPoly[klow+1].X());
00313 }
00314 return klow;
00315 }
00316
00317
00318 double TRadSpline3::Eval(double x) const
00319 {
00320 int klow=FindX(x);
00321 return fPoly[klow].Eval(x);
00322 }
00323
00324
00325 double TRadSpline3::Derivative(double x) const
00326 {
00327 int klow=FindX(x);
00328 return fPoly[klow].Derivative(x);
00329 }
00330
00331
00332 void TRadSpline3::SaveAs(const char *filename) const
00333 {
00334
00335
00336
00337
00338 ofstream *f = new ofstream(filename,ios::out);
00339 if (f == 0) {
00340 printf("Cannot open file:%s\n",filename);
00341 return;
00342 }
00343
00344
00345 char buffer[512];
00346 int nch = strlen(filename);
00347 sprintf(buffer,"double %s",filename);
00348 char *dot = strstr(buffer,".");
00349 if (dot) *dot = 0;
00350 strcat(buffer,"(double x) {\n");
00351 nch = strlen(buffer); f->write(buffer,nch);
00352 sprintf(buffer," const int fNp = %d, fKstep = %d;\n",fNp,fKstep);
00353 nch = strlen(buffer); f->write(buffer,nch);
00354 sprintf(buffer," const double fDelta = %g, fXmin = %g, fXmax = %g;\n",fDelta,fXmin,fXmax);
00355 nch = strlen(buffer); f->write(buffer,nch);
00356
00357
00358
00359 sprintf(buffer," const double fX[%d] = {",fNp);
00360 nch = strlen(buffer); f->write(buffer,nch);
00361 buffer[0] = 0;
00362 int i;
00363 char numb[20];
00364 for (i=0;i<fNp;i++) {
00365 sprintf(numb," %g,",fPoly[i].X());
00366 nch = strlen(numb);
00367 if (i == fNp-1) numb[nch-1]=0;
00368 strcat(buffer,numb);
00369 if (i%5 == 4 || i == fNp-1) {
00370 nch = strlen(buffer); f->write(buffer,nch);
00371 if (i != fNp-1) sprintf(buffer,"\n ");
00372 }
00373 }
00374 sprintf(buffer," };\n");
00375 nch = strlen(buffer); f->write(buffer,nch);
00376
00377 sprintf(buffer," const double fY[%d] = {",fNp);
00378 nch = strlen(buffer); f->write(buffer,nch);
00379 buffer[0] = 0;
00380 for (i=0;i<fNp;i++) {
00381 sprintf(numb," %g,",fPoly[i].Y());
00382 nch = strlen(numb);
00383 if (i == fNp-1) numb[nch-1]=0;
00384 strcat(buffer,numb);
00385 if (i%5 == 4 || i == fNp-1) {
00386 nch = strlen(buffer); f->write(buffer,nch);
00387 if (i != fNp-1) sprintf(buffer,"\n ");
00388 }
00389 }
00390 sprintf(buffer," };\n");
00391 nch = strlen(buffer); f->write(buffer,nch);
00392
00393 sprintf(buffer," const double fB[%d] = {",fNp);
00394 nch = strlen(buffer); f->write(buffer,nch);
00395 buffer[0] = 0;
00396 for (i=0;i<fNp;i++) {
00397 sprintf(numb," %g,",fPoly[i].B());
00398 nch = strlen(numb);
00399 if (i == fNp-1) numb[nch-1]=0;
00400 strcat(buffer,numb);
00401 if (i%5 == 4 || i == fNp-1) {
00402 nch = strlen(buffer); f->write(buffer,nch);
00403 if (i != fNp-1) sprintf(buffer,"\n ");
00404 }
00405 }
00406 sprintf(buffer," };\n");
00407 nch = strlen(buffer); f->write(buffer,nch);
00408
00409 sprintf(buffer," const double fC[%d] = {",fNp);
00410 nch = strlen(buffer); f->write(buffer,nch);
00411 buffer[0] = 0;
00412 for (i=0;i<fNp;i++) {
00413 sprintf(numb," %g,",fPoly[i].C());
00414 nch = strlen(numb);
00415 if (i == fNp-1) numb[nch-1]=0;
00416 strcat(buffer,numb);
00417 if (i%5 == 4 || i == fNp-1) {
00418 nch = strlen(buffer); f->write(buffer,nch);
00419 if (i != fNp-1) sprintf(buffer,"\n ");
00420 }
00421 }
00422 sprintf(buffer," };\n");
00423 nch = strlen(buffer); f->write(buffer,nch);
00424
00425 sprintf(buffer," const double fD[%d] = {",fNp);
00426 nch = strlen(buffer); f->write(buffer,nch);
00427 buffer[0] = 0;
00428 for (i=0;i<fNp;i++) {
00429 sprintf(numb," %g,",fPoly[i].D());
00430 nch = strlen(numb);
00431 if (i == fNp-1) numb[nch-1]=0;
00432 strcat(buffer,numb);
00433 if (i%5 == 4 || i == fNp-1) {
00434 nch = strlen(buffer); f->write(buffer,nch);
00435 if (i != fNp-1) sprintf(buffer,"\n ");
00436 }
00437 }
00438 sprintf(buffer," };\n");
00439 nch = strlen(buffer); f->write(buffer,nch);
00440
00441
00442 sprintf(buffer," int klow=0;\n");
00443 nch = strlen(buffer); f->write(buffer,nch);
00444
00445 sprintf(buffer," // If out of boundaries, extrapolate. It may be badly wrong\n");
00446 sprintf(buffer," if(x<=fXmin) klow=0;\n");
00447 nch = strlen(buffer); f->write(buffer,nch);
00448 sprintf(buffer," else if(x>=fXmax) klow=fNp-1;\n");
00449 nch = strlen(buffer); f->write(buffer,nch);
00450 sprintf(buffer," else {\n");
00451 nch = strlen(buffer); f->write(buffer,nch);
00452 sprintf(buffer," if(fKstep) {\n");
00453 nch = strlen(buffer); f->write(buffer,nch);
00454
00455 sprintf(buffer," // Equidistant knots, use histogramming\n");
00456 nch = strlen(buffer); f->write(buffer,nch);
00457 sprintf(buffer," klow = int((x-fXmin)/fDelta);\n");
00458 nch = strlen(buffer); f->write(buffer,nch);
00459 sprintf(buffer," if (klow < fNp-1) klow = fNp-1;\n");
00460 nch = strlen(buffer); f->write(buffer,nch);
00461 sprintf(buffer," } else {\n");
00462 nch = strlen(buffer); f->write(buffer,nch);
00463 sprintf(buffer," int khig=fNp-1, khalf;\n");
00464 nch = strlen(buffer); f->write(buffer,nch);
00465
00466 sprintf(buffer," // Non equidistant knots, binary search\n");
00467 nch = strlen(buffer); f->write(buffer,nch);
00468 sprintf(buffer," while(khig-klow>1)\n");
00469 nch = strlen(buffer); f->write(buffer,nch);
00470 sprintf(buffer," if(x>fX[khalf=(klow+khig)/2]) klow=khalf;\n");
00471 nch = strlen(buffer); f->write(buffer,nch);
00472 sprintf(buffer," else khig=khalf;\n");
00473 nch = strlen(buffer); f->write(buffer,nch);
00474 sprintf(buffer," }\n");
00475 nch = strlen(buffer); f->write(buffer,nch);
00476 sprintf(buffer," }\n");
00477 nch = strlen(buffer); f->write(buffer,nch);
00478 sprintf(buffer," // Evaluate now\n");
00479 nch = strlen(buffer); f->write(buffer,nch);
00480 sprintf(buffer," double dx=x-fX[klow];\n");
00481 nch = strlen(buffer); f->write(buffer,nch);
00482 sprintf(buffer," return (fY[klow]+dx*(fB[klow]+dx*(fC[klow]+dx*fD[klow])));\n");
00483 nch = strlen(buffer); f->write(buffer,nch);
00484
00485
00486 f->write("}\n",2);
00487
00488 if (f) { f->close(); delete f;}
00489 }
00490
00491
00492 void TRadSpline3::BuildCoeff()
00493 {
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524 int i, j, l, m;
00525 double divdf1,divdf3,dtau,g=0;
00526
00527
00528
00529
00530 l = fNp-1;
00531
00532
00533 for (m=1; m<fNp ; ++m) {
00534 fPoly[m].C() = fPoly[m].X() - fPoly[m-1].X();
00535 fPoly[m].D() = (fPoly[m].Y() - fPoly[m-1].Y())/fPoly[m].C();
00536 }
00537
00538
00539 if(fBegCond==0) {
00540 if(fNp == 2) {
00541
00542 fPoly[0].D() = 1.;
00543 fPoly[0].C() = 1.;
00544 fPoly[0].B() = 2.*fPoly[1].D();
00545 } else {
00546
00547 fPoly[0].D() = fPoly[2].C();
00548 fPoly[0].C() = fPoly[1].C() + fPoly[2].C();
00549 fPoly[0].B() =((fPoly[1].C()+2.*fPoly[0].C())*fPoly[1].D()*fPoly[2].C()+fPoly[1].C()*fPoly[1].C()*fPoly[2].D())/fPoly[0].C();
00550 }
00551 } else if (fBegCond==1) {
00552
00553 fPoly[0].B() = fValBeg;
00554 fPoly[0].D() = 1.;
00555 fPoly[0].C() = 0.;
00556 } else if (fBegCond==2) {
00557
00558 fPoly[0].D() = 2.;
00559 fPoly[0].C() = 1.;
00560 fPoly[0].B() = 3.*fPoly[1].D() - fPoly[1].C()/2.*fValBeg;
00561 }
00562 if(fNp > 2) {
00563
00564
00565
00566 for (m=1; m<l; ++m) {
00567 g = -fPoly[m+1].C()/fPoly[m-1].D();
00568 fPoly[m].B() = g*fPoly[m-1].B() + 3.*(fPoly[m].C()*fPoly[m+1].D()+fPoly[m+1].C()*fPoly[m].D());
00569 fPoly[m].D() = g*fPoly[m-1].C() + 2.*(fPoly[m].C() + fPoly[m+1].C());
00570 }
00571
00572
00573
00574
00575
00576 if(fEndCond == 0) {
00577 if (fNp > 3 || fBegCond != 0) {
00578
00579
00580 g = fPoly[fNp-2].C() + fPoly[fNp-1].C();
00581 fPoly[fNp-1].B() = ((fPoly[fNp-1].C()+2.*g)*fPoly[fNp-1].D()*fPoly[fNp-2].C()
00582 + fPoly[fNp-1].C()*fPoly[fNp-1].C()*(fPoly[fNp-2].Y()-fPoly[fNp-3].Y())/fPoly[fNp-2].C())/g;
00583 g = -g/fPoly[fNp-2].D();
00584 fPoly[fNp-1].D() = fPoly[fNp-2].C();
00585 } else {
00586
00587
00588 fPoly[fNp-1].B() = 2.*fPoly[fNp-1].D();
00589 fPoly[fNp-1].D() = 1.;
00590 g = -1./fPoly[fNp-2].D();
00591 }
00592 } else if (fEndCond == 1) {
00593 fPoly[fNp-1].B() = fValEnd;
00594 goto L30;
00595 } else if (fEndCond == 2) {
00596
00597 fPoly[fNp-1].B() = 3.*fPoly[fNp-1].D() + fPoly[fNp-1].C()/2.*fValEnd;
00598 fPoly[fNp-1].D() = 2.;
00599 g = -1./fPoly[fNp-2].D();
00600 }
00601 } else {
00602 if(fEndCond == 0) {
00603 if (fBegCond > 0) {
00604
00605
00606 fPoly[fNp-1].B() = 2.*fPoly[fNp-1].D();
00607 fPoly[fNp-1].D() = 1.;
00608 g = -1./fPoly[fNp-2].D();
00609 } else {
00610
00611 fPoly[fNp-1].B() = fPoly[fNp-1].D();
00612 goto L30;
00613 }
00614 } else if(fEndCond == 1) {
00615 fPoly[fNp-1].B() = fValEnd;
00616 goto L30;
00617 } else if(fEndCond == 2) {
00618
00619 fPoly[fNp-1].B() = 3.*fPoly[fNp-1].D() + fPoly[fNp-1].C()/2.*fValEnd;
00620 fPoly[fNp-1].D() = 2.;
00621 g = -1./fPoly[fNp-2].D();
00622 }
00623 }
00624
00625 fPoly[fNp-1].D() = g*fPoly[fNp-2].C() + fPoly[fNp-1].D();
00626 fPoly[fNp-1].B() = (g*fPoly[fNp-2].B() + fPoly[fNp-1].B())/fPoly[fNp-1].D();
00627
00628 L30: j = l-1;
00629 do {
00630 fPoly[j].B() = (fPoly[j].B() - fPoly[j].C()*fPoly[j+1].B())/fPoly[j].D();
00631 --j;
00632 } while (j>=0);
00633
00634
00635 for (i=1; i<fNp; ++i) {
00636 dtau = fPoly[i].C();
00637 divdf1 = (fPoly[i].Y() - fPoly[i-1].Y())/dtau;
00638 divdf3 = fPoly[i-1].B() + fPoly[i].B() - 2.*divdf1;
00639 fPoly[i-1].C() = (divdf1 - fPoly[i-1].B() - divdf3)/dtau;
00640 fPoly[i-1].D() = (divdf3/dtau)/dtau;
00641 }
00642 }
00643
00645
00646
00647
00648
00649
00650
00651
00652
00654
00655
00656
00657 TRadSpline5::TRadSpline5(const char *title,
00658 double x[], double y[], int n,
00659 const char *opt, double b1, double e1,
00660 double b2, double e2) :
00661 TRadSpline(title,-1, x[0], x[n-1], n, false)
00662 {
00663
00664
00665
00666
00667
00668 int beg, end;
00669 const char *cb1, *ce1, *cb2, *ce2;
00670
00671
00672 BoundaryConditions(opt,beg,end,cb1,ce1,cb2,ce2);
00673
00674
00675
00676 fPoly = new TRadSplinePoly5[fNp];
00677 for (int i=0; i<n; ++i) {
00678 fPoly[i+beg].X() = x[i];
00679 fPoly[i+beg].Y() = y[i];
00680 }
00681
00682
00683 SetBoundaries(b1,e1,b2,e2,cb1,ce1,cb2,ce2);
00684
00685
00686 BuildCoeff();
00687 }
00688
00689
00690 TRadSpline5::TRadSpline5(const char *title,
00691 double xmin, double xmax,
00692 double y[], int n,
00693 const char *opt, double b1, double e1,
00694 double b2, double e2) :
00695 TRadSpline(title,(xmax-xmin)/(n-1), xmin, xmax, n, true)
00696 {
00697
00698
00699
00700
00701
00702 int beg, end;
00703 const char *cb1, *ce1, *cb2, *ce2;
00704
00705
00706 BoundaryConditions(opt,beg,end,cb1,ce1,cb2,ce2);
00707
00708
00709
00710 fPoly = new TRadSplinePoly5[fNp];
00711 for (int i=0; i<n; ++i) {
00712 fPoly[i+beg].X() = fXmin+i*fDelta;
00713 fPoly[i+beg].Y() = y[i];
00714 }
00715
00716
00717 SetBoundaries(b1,e1,b2,e2,cb1,ce1,cb2,ce2);
00718
00719
00720 BuildCoeff();
00721 }
00722
00723 TRadSpline5::TRadSpline5(const char *title,
00724 double xmin, double xmax,
00725 double (*func)(const double&), int n,
00726 const char *opt, double b1, double e1,
00727 double b2, double e2) :
00728 TRadSpline(title,(xmax-xmin)/(n-1), xmin, xmax, n, true)
00729 {
00730
00731
00732
00733
00734
00735 int beg, end;
00736 const char *cb1, *ce1, *cb2, *ce2;
00737
00738
00739
00740 BoundaryConditions(opt,beg,end,cb1,ce1,cb2,ce2);
00741
00742
00743
00744 fPoly = new TRadSplinePoly5[fNp];
00745 for (int i=0; i<n; ++i) {
00746 double x=fXmin+i*fDelta;
00747 fPoly[i+beg].X() = x;
00748 fPoly[i+beg].Y() = func(x);
00749 }
00750
00751
00752 SetBoundaries(b1,e1,b2,e2,cb1,ce1,cb2,ce2);
00753
00754
00755 BuildCoeff();
00756 }
00757
00758
00759 void TRadSpline5::BoundaryConditions(const char *opt,int &beg,int &end,
00760 const char *&cb1,const char *&ce1,
00761 const char *&cb2,const char *&ce2)
00762 {
00763
00764
00765
00766
00767 cb1=ce1=cb2=ce2=0;
00768 beg=end=0;
00769 if(opt) {
00770 cb1 = strstr(opt,"b1");
00771 ce1 = strstr(opt,"e1");
00772 cb2 = strstr(opt,"b2");
00773 ce2 = strstr(opt,"e2");
00774 if(cb2) {
00775 fNp=fNp+2;
00776 beg=2;
00777 } else if(cb1) {
00778 fNp=fNp+1;
00779 beg=1;
00780 }
00781 if(ce2) {
00782 fNp=fNp+2;
00783 end=2;
00784 } else if(ce1) {
00785 fNp=fNp+1;
00786 end=1;
00787 }
00788 }
00789 }
00790
00791
00792 void TRadSpline5::SetBoundaries(double b1, double e1, double b2, double e2,
00793 const char *cb1, const char *ce1, const char *cb2,
00794 const char *ce2)
00795 {
00796
00797
00798
00799 if(cb2) {
00800
00801
00802 fPoly[0].X() = fPoly[1].X() = fPoly[2].X();
00803 fPoly[0].Y() = fPoly[2].Y();
00804 fPoly[2].Y()=b2;
00805
00806
00807
00808 if(cb1)
00809 fPoly[1].Y()=b1;
00810 else
00811 fPoly[1].Y()=(fPoly[3].Y()-fPoly[0].Y())/(fPoly[3].X()-fPoly[2].X());
00812 } else if(cb1) {
00813
00814
00815 fPoly[0].X() = fPoly[1].X();
00816 fPoly[0].Y() = fPoly[1].Y();
00817 fPoly[1].Y()=b1;
00818 }
00819 if(ce2) {
00820
00821
00822 fPoly[fNp-1].X() = fPoly[fNp-2].X() = fPoly[fNp-3].X();
00823 fPoly[fNp-1].Y()=e2;
00824
00825
00826
00827 if(ce1)
00828 fPoly[fNp-2].Y()=e1;
00829 else
00830 fPoly[fNp-2].Y()=
00831 (fPoly[fNp-3].Y()-fPoly[fNp-4].Y())
00832 /(fPoly[fNp-3].X()-fPoly[fNp-4].X());
00833 } else if(ce1) {
00834
00835
00836 fPoly[fNp-1].X() = fPoly[fNp-2].X();
00837 fPoly[fNp-1].Y()=e1;
00838 }
00839 }
00840
00841 int TRadSpline5::FindX(double x) const
00842 {
00843
00844 int klow=0;
00845
00846
00847
00848 if(x<=fXmin) klow=0;
00849 else if(x>=fXmax) klow=fNp-1;
00850 else {
00851 if(fKstep) {
00852
00853
00854 klow = (int((x-fXmin)/fDelta)<fNp-1)?int((x-fXmin)/fDelta):fNp-1;
00855 } else {
00856 int khig=fNp-1, khalf;
00857
00858
00859 while(khig-klow>1)
00860 if(x>fPoly[khalf=(klow+khig)/2].X())
00861 klow=khalf;
00862 else
00863 khig=khalf;
00864 }
00865
00866
00867 if(!(fPoly[klow].X()<=x && x<=fPoly[klow+1].X()))
00868 printf("Binary search failed x(%d) = %f < %f < x(%d) = %f\n",
00869 klow,fPoly[klow].X(),x,klow+1,fPoly[klow+1].X());
00870 }
00871 return klow;
00872 }
00873
00874
00875 double TRadSpline5::Eval(double x) const
00876 {
00877 int klow=FindX(x);
00878 return fPoly[klow].Eval(x);
00879 }
00880
00881
00882 double TRadSpline5::Derivative(double x) const
00883 {
00884 int klow=FindX(x);
00885 return fPoly[klow].Derivative(x);
00886 }
00887
00888
00889 void TRadSpline5::SaveAs(const char *filename) const
00890 {
00891
00892
00893
00894
00895 ofstream *f = new ofstream(filename,ios::out);
00896 if (f == 0) {
00897 printf("Cannot open file:%s\n",filename);
00898 return;
00899 }
00900
00901
00902 char buffer[512];
00903 int nch = strlen(filename);
00904 sprintf(buffer,"double %s",filename);
00905 char *dot = strstr(buffer,".");
00906 if (dot) *dot = 0;
00907 strcat(buffer,"(double x) {\n");
00908 nch = strlen(buffer); f->write(buffer,nch);
00909 sprintf(buffer," const int fNp = %d, fKstep = %d;\n",fNp,fKstep);
00910 nch = strlen(buffer); f->write(buffer,nch);
00911 sprintf(buffer," const double fDelta = %g, fXmin = %g, fXmax = %g;\n",fDelta,fXmin,fXmax);
00912 nch = strlen(buffer); f->write(buffer,nch);
00913
00914
00915
00916 sprintf(buffer," const double fX[%d] = {",fNp);
00917 nch = strlen(buffer); f->write(buffer,nch);
00918 buffer[0] = 0;
00919 int i;
00920 char numb[20];
00921 for (i=0;i<fNp;i++) {
00922 sprintf(numb," %g,",fPoly[i].X());
00923 nch = strlen(numb);
00924 if (i == fNp-1) numb[nch-1]=0;
00925 strcat(buffer,numb);
00926 if (i%5 == 4 || i == fNp-1) {
00927 nch = strlen(buffer); f->write(buffer,nch);
00928 if (i != fNp-1) sprintf(buffer,"\n ");
00929 }
00930 }
00931 sprintf(buffer," };\n");
00932 nch = strlen(buffer); f->write(buffer,nch);
00933
00934 sprintf(buffer," const double fY[%d] = {",fNp);
00935 nch = strlen(buffer); f->write(buffer,nch);
00936 buffer[0] = 0;
00937 for (i=0;i<fNp;i++) {
00938 sprintf(numb," %g,",fPoly[i].Y());
00939 nch = strlen(numb);
00940 if (i == fNp-1) numb[nch-1]=0;
00941 strcat(buffer,numb);
00942 if (i%5 == 4 || i == fNp-1) {
00943 nch = strlen(buffer); f->write(buffer,nch);
00944 if (i != fNp-1) sprintf(buffer,"\n ");
00945 }
00946 }
00947 sprintf(buffer," };\n");
00948 nch = strlen(buffer); f->write(buffer,nch);
00949
00950 sprintf(buffer," const double fB[%d] = {",fNp);
00951 nch = strlen(buffer); f->write(buffer,nch);
00952 buffer[0] = 0;
00953 for (i=0;i<fNp;i++) {
00954 sprintf(numb," %g,",fPoly[i].B());
00955 nch = strlen(numb);
00956 if (i == fNp-1) numb[nch-1]=0;
00957 strcat(buffer,numb);
00958 if (i%5 == 4 || i == fNp-1) {
00959 nch = strlen(buffer); f->write(buffer,nch);
00960 if (i != fNp-1) sprintf(buffer,"\n ");
00961 }
00962 }
00963 sprintf(buffer," };\n");
00964 nch = strlen(buffer); f->write(buffer,nch);
00965
00966 sprintf(buffer," const double fC[%d] = {",fNp);
00967 nch = strlen(buffer); f->write(buffer,nch);
00968 buffer[0] = 0;
00969 for (i=0;i<fNp;i++) {
00970 sprintf(numb," %g,",fPoly[i].C());
00971 nch = strlen(numb);
00972 if (i == fNp-1) numb[nch-1]=0;
00973 strcat(buffer,numb);
00974 if (i%5 == 4 || i == fNp-1) {
00975 nch = strlen(buffer); f->write(buffer,nch);
00976 if (i != fNp-1) sprintf(buffer,"\n ");
00977 }
00978 }
00979 sprintf(buffer," };\n");
00980 nch = strlen(buffer); f->write(buffer,nch);
00981
00982 sprintf(buffer," const double fD[%d] = {",fNp);
00983 nch = strlen(buffer); f->write(buffer,nch);
00984 buffer[0] = 0;
00985 for (i=0;i<fNp;i++) {
00986 sprintf(numb," %g,",fPoly[i].D());
00987 nch = strlen(numb);
00988 if (i == fNp-1) numb[nch-1]=0;
00989 strcat(buffer,numb);
00990 if (i%5 == 4 || i == fNp-1) {
00991 nch = strlen(buffer); f->write(buffer,nch);
00992 if (i != fNp-1) sprintf(buffer,"\n ");
00993 }
00994 }
00995 sprintf(buffer," };\n");
00996 nch = strlen(buffer); f->write(buffer,nch);
00997
00998 sprintf(buffer," const double fE[%d] = {",fNp);
00999 nch = strlen(buffer); f->write(buffer,nch);
01000 buffer[0] = 0;
01001 for (i=0;i<fNp;i++) {
01002 sprintf(numb," %g,",fPoly[i].E());
01003 nch = strlen(numb);
01004 if (i == fNp-1) numb[nch-1]=0;
01005 strcat(buffer,numb);
01006 if (i%5 == 4 || i == fNp-1) {
01007 nch = strlen(buffer); f->write(buffer,nch);
01008 if (i != fNp-1) sprintf(buffer,"\n ");
01009 }
01010 }
01011 sprintf(buffer," };\n");
01012 nch = strlen(buffer); f->write(buffer,nch);
01013
01014 sprintf(buffer," const double fF[%d] = {",fNp);
01015 nch = strlen(buffer); f->write(buffer,nch);
01016 buffer[0] = 0;
01017 for (i=0;i<fNp;i++) {
01018 sprintf(numb," %g,",fPoly[i].F());
01019 nch = strlen(numb);
01020 if (i == fNp-1) numb[nch-1]=0;
01021 strcat(buffer,numb);
01022 if (i%5 == 4 || i == fNp-1) {
01023 nch = strlen(buffer); f->write(buffer,nch);
01024 if (i != fNp-1) sprintf(buffer,"\n ");
01025 }
01026 }
01027 sprintf(buffer," };\n");
01028 nch = strlen(buffer); f->write(buffer,nch);
01029
01030
01031 sprintf(buffer," int klow=0;\n");
01032 nch = strlen(buffer); f->write(buffer,nch);
01033
01034 sprintf(buffer," // If out of boundaries, extrapolate. It may be badly wrong\n");
01035 sprintf(buffer," if(x<=fXmin) klow=0;\n");
01036 nch = strlen(buffer); f->write(buffer,nch);
01037 sprintf(buffer," else if(x>=fXmax) klow=fNp-1;\n");
01038 nch = strlen(buffer); f->write(buffer,nch);
01039 sprintf(buffer," else {\n");
01040 nch = strlen(buffer); f->write(buffer,nch);
01041 sprintf(buffer," if(fKstep) {\n");
01042 nch = strlen(buffer); f->write(buffer,nch);
01043
01044 sprintf(buffer," // Equidistant knots, use histogramming\n");
01045 nch = strlen(buffer); f->write(buffer,nch);
01046 sprintf(buffer," klow = int((x-fXmin)/fDelta);\n");
01047 nch = strlen(buffer); f->write(buffer,nch);
01048 sprintf(buffer," if (klow < fNp-1) klow = fNp-1;\n");
01049 nch = strlen(buffer); f->write(buffer,nch);
01050 sprintf(buffer," } else {\n");
01051 nch = strlen(buffer); f->write(buffer,nch);
01052 sprintf(buffer," int khig=fNp-1, khalf;\n");
01053 nch = strlen(buffer); f->write(buffer,nch);
01054
01055 sprintf(buffer," // Non equidistant knots, binary search\n");
01056 nch = strlen(buffer); f->write(buffer,nch);
01057 sprintf(buffer," while(khig-klow>1)\n");
01058 nch = strlen(buffer); f->write(buffer,nch);
01059 sprintf(buffer," if(x>fX[khalf=(klow+khig)/2]) klow=khalf;\n");
01060 nch = strlen(buffer); f->write(buffer,nch);
01061 sprintf(buffer," else khig=khalf;\n");
01062 nch = strlen(buffer); f->write(buffer,nch);
01063 sprintf(buffer," }\n");
01064 nch = strlen(buffer); f->write(buffer,nch);
01065 sprintf(buffer," }\n");
01066 nch = strlen(buffer); f->write(buffer,nch);
01067 sprintf(buffer," // Evaluate now\n");
01068 nch = strlen(buffer); f->write(buffer,nch);
01069 sprintf(buffer," double dx=x-fX[klow];\n");
01070 nch = strlen(buffer); f->write(buffer,nch);
01071 sprintf(buffer," return (fY[klow]+dx*(fB[klow]+dx*(fC[klow]+dx*(fD[klow]+dx*(fE[klow]+dx*fF[klow])))));\n");
01072 nch = strlen(buffer); f->write(buffer,nch);
01073
01074
01075 f->write("}\n",2);
01076
01077 if (f) { f->close(); delete f;}
01078 }
01079
01080
01081 void TRadSpline5::BuildCoeff()
01082 {
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149 int i, m;
01150 double pqqr, p, q, r, s, t, u, v,
01151 b1, p2, p3, q2, q3, r2, pq, pr, qr;
01152
01153 if (fNp <= 2) {
01154 return;
01155 }
01156
01157
01158
01159
01160 m = fNp-2;
01161 q = fPoly[1].X()-fPoly[0].X();
01162 r = fPoly[2].X()-fPoly[1].X();
01163 q2 = q*q;
01164 r2 = r*r;
01165 qr = q+r;
01166 fPoly[0].D() = fPoly[0].E() = 0;
01167 if (q) fPoly[1].D() = q*6.*q2/(qr*qr);
01168 else fPoly[1].D() = 0;
01169
01170 if (m > 1) {
01171 for (i = 1; i < m; ++i) {
01172 p = q;
01173 q = r;
01174 r = fPoly[i+2].X()-fPoly[i+1].X();
01175 p2 = q2;
01176 q2 = r2;
01177 r2 = r*r;
01178 pq = qr;
01179 qr = q+r;
01180 if (q) {
01181 q3 = q2*q;
01182 pr = p*r;
01183 pqqr = pq*qr;
01184 fPoly[i+1].D() = q3*6./(qr*qr);
01185 fPoly[i].D() += (q+q)*(pr*15.*pr+(p+r)*q
01186 *(pr* 20.+q2*7.)+q2*
01187 ((p2+r2)*8.+pr*21.+q2+q2))/(pqqr*pqqr);
01188 fPoly[i-1].D() += q3*6./(pq*pq);
01189 fPoly[i].E() = q2*(p*qr+pq*3.*(qr+r+r))/(pqqr*qr);
01190 fPoly[i-1].E() += q2*(r*pq+qr*3.*(pq+p+p))/(pqqr*pq);
01191 fPoly[i-1].F() = q3/pqqr;
01192 } else
01193 fPoly[i+1].D() = fPoly[i].E() = fPoly[i-1].F() = 0;
01194 }
01195 }
01196 if (r) fPoly[m-1].D() += r*6.*r2/(qr*qr);
01197
01198
01199
01200
01201
01202 for (i = 1; i < fNp; ++i) {
01203 if (fPoly[i].X() != fPoly[i-1].X()) {
01204 fPoly[i].B() =
01205 (fPoly[i].Y()-fPoly[i-1].Y())/(fPoly[i].X()-fPoly[i-1].X());
01206 } else {
01207 fPoly[i].B() = fPoly[i].Y();
01208 fPoly[i].Y() = fPoly[i-1].Y();
01209 }
01210 }
01211 for (i = 2; i < fNp; ++i) {
01212 if (fPoly[i].X() != fPoly[i-2].X()) {
01213 fPoly[i].C() =
01214 (fPoly[i].B()-fPoly[i-1].B())/(fPoly[i].X()-fPoly[i-2].X());
01215 } else {
01216 fPoly[i].C() = fPoly[i].B()*.5;
01217 fPoly[i].B() = fPoly[i-1].B();
01218 }
01219 }
01220
01221
01222
01223 if (m > 1) {
01224 p=fPoly[0].C()=fPoly[m-1].E()=fPoly[0].F()
01225 =fPoly[m-2].F()=fPoly[m-1].F()=0;
01226 fPoly[1].C() = fPoly[3].C()-fPoly[2].C();
01227 fPoly[1].D() = 1./fPoly[1].D();
01228
01229 if (m > 2) {
01230 for (i = 2; i < m; ++i) {
01231 q = fPoly[i-1].D()*fPoly[i-1].E();
01232 fPoly[i].D() = 1./(fPoly[i].D()-p*fPoly[i-2].F()-q*fPoly[i-1].E());
01233 fPoly[i].E() -= q*fPoly[i-1].F();
01234 fPoly[i].C() = fPoly[i+2].C()-fPoly[i+1].C()-p*fPoly[i-2].C()
01235 -q*fPoly[i-1].C();
01236 p = fPoly[i-1].D()*fPoly[i-1].F();
01237 }
01238 }
01239 }
01240
01241 fPoly[fNp-2].C() = fPoly[fNp-1].C() = 0;
01242 if (fNp > 3)
01243 for (i=fNp-3; i > 0; --i)
01244 fPoly[i].C() = (fPoly[i].C()-fPoly[i].E()*fPoly[i+1].C()
01245 -fPoly[i].F()*fPoly[i+2].C())*fPoly[i].D();
01246
01247
01248
01249 m = fNp-1;
01250 q = fPoly[1].X()-fPoly[0].X();
01251 r = fPoly[2].X()-fPoly[1].X();
01252 b1 = fPoly[1].B();
01253 q3 = q*q*q;
01254 qr = q+r;
01255 if (qr) {
01256 v = fPoly[1].C()/qr;
01257 t = v;
01258 } else
01259 v = t = 0;
01260 if (q) fPoly[0].F() = v/q;
01261 else fPoly[0].F() = 0;
01262 for (i = 1; i < m; ++i) {
01263 p = q;
01264 q = r;
01265 if (i != m-1) r = fPoly[i+2].X()-fPoly[i+1].X();
01266 else r = 0;
01267 p3 = q3;
01268 q3 = q*q*q;
01269 pq = qr;
01270 qr = q+r;
01271 s = t;
01272 if (qr) t = (fPoly[i+1].C()-fPoly[i].C())/qr;
01273 else t = 0;
01274 u = v;
01275 v = t-s;
01276 if (pq) {
01277 fPoly[i].F() = fPoly[i-1].F();
01278 if (q) fPoly[i].F() = v/q;
01279 fPoly[i].E() = s*5.;
01280 fPoly[i].D() = (fPoly[i].C()-q*s)*10;
01281 fPoly[i].C() =
01282 fPoly[i].D()*(p-q)+(fPoly[i+1].B()-fPoly[i].B()+(u-fPoly[i].E())*
01283 p3-(v+fPoly[i].E())*q3)/pq;
01284 fPoly[i].B() = (p*(fPoly[i+1].B()-v*q3)+q*(fPoly[i].B()-u*p3))/pq-p
01285 *q*(fPoly[i].D()+fPoly[i].E()*(q-p));
01286 } else {
01287 fPoly[i].C() = fPoly[i-1].C();
01288 fPoly[i].D() = fPoly[i].E() = fPoly[i].F() = 0;
01289 }
01290 }
01291
01292
01293
01294 p = fPoly[1].X()-fPoly[0].X();
01295 s = fPoly[0].F()*p*p*p;
01296 fPoly[0].E() = fPoly[0].D() = 0;
01297 fPoly[0].C() = fPoly[1].C()-s*10;
01298 fPoly[0].B() = b1-(fPoly[0].C()+s)*p;
01299
01300 q = fPoly[fNp-1].X()-fPoly[fNp-2].X();
01301 t = fPoly[fNp-2].F()*q*q*q;
01302 fPoly[fNp-1].E() = fPoly[fNp-1].D() = 0;
01303 fPoly[fNp-1].C() = fPoly[fNp-2].C()+t*10;
01304 fPoly[fNp-1].B() += (fPoly[fNp-1].C()-t)*q;
01305 }
01306
01307
01308 void TRadSpline5::Test()
01309 {
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334 double hx;
01335 double diff[5];
01336 double a[1200], c[6];
01337 int i, j, k, m, n;
01338 double p, x[200], y[200], z;
01339 int jj, mm, nn;
01340 int mm1, nm1;
01341 double com[5];
01342
01343 printf("1 TEST OF TRadSpline5 WITH NONEQUIDISTANT KNOTS\n");
01344 n = 5;
01345 x[0] = -3;
01346 x[1] = -1;
01347 x[2] = 0;
01348 x[3] = 3;
01349 x[4] = 4;
01350 y[0] = 7;
01351 y[1] = 11;
01352 y[2] = 26;
01353 y[3] = 56;
01354 y[4] = 29;
01355 m = 3;
01356 mm = m << 1;
01357 mm1 = mm-1;
01358 printf("\n-N = %3d M =%2d\n",n,m);
01359 TRadSpline5 *spline = new TRadSpline5("Test",x,y,n);
01360 for (i = 0; i < n; ++i)
01361 spline->GetCoeff(i,hx, a[i],a[i+200],a[i+400],
01362 a[i+600],a[i+800],a[i+1000]);
01363 delete spline;
01364 for (i = 0; i < mm1; ++i) diff[i] = com[i] = 0;
01365 for (k = 0; k < n; ++k) {
01366 for (i = 0; i < mm; ++i) c[i] = a[k+i*200];
01367 printf(" ---------------------------------------%3d --------------------------------------------\n",k+1);
01368 printf("%12.8f\n",x[k]);
01369 if (k == n-1) {
01370 printf("%16.8f\n",c[0]);
01371 } else {
01372 for (i = 0; i < mm; ++i) printf("%16.8f",c[i]);
01373 printf("\n");
01374 for (i = 0; i < mm1; ++i)
01375 if ((z=fabs(a[k+i*200])) > com[i]) com[i] = z;
01376 z = x[k+1]-x[k];
01377 for (i = 1; i < mm; ++i)
01378 for (jj = i; jj < mm; ++jj) {
01379 j = mm+i-jj;
01380 c[j-2] = c[j-1]*z+c[j-2];
01381 }
01382 for (i = 0; i < mm; ++i) printf("%16.8f",c[i]);
01383 printf("\n");
01384 for (i = 0; i < mm1; ++i)
01385 if (!(k >= n-2 && i != 0))
01386 if((z = fabs(c[i]-a[k+1+i*200]))
01387 > diff[i]) diff[i] = z;
01388 }
01389 }
01390 printf(" MAXIMUM ABSOLUTE VALUES OF DIFFERENCES \n");
01391 for (i = 0; i < mm1; ++i) printf("%18.9E",diff[i]);
01392 printf("\n");
01393 printf(" MAXIMUM ABSOLUTE VALUES OF COEFFICIENTS \n");
01394 if (fabs(c[0]) > com[0])
01395 com[0] = fabs(c[0]);
01396 for (i = 0; i < mm1; ++i) printf("%16.8f",com[i]);
01397 printf("\n");
01398 m = 3;
01399 for (n = 10; n <= 100; n += 10) {
01400 mm = m << 1;
01401 mm1 = mm-1;
01402 nm1 = n-1;
01403 for (i = 0; i < nm1; i += 2) {
01404 x[i] = i+1;
01405 x[i+1] = i+2;
01406 y[i] = 1;
01407 y[i+1] = 0;
01408 }
01409 if (n % 2 != 0) {
01410 x[n-1] = n;
01411 y[n-1] = 1;
01412 }
01413 printf("\n-N = %3d M =%2d\n",n,m);
01414 spline = new TRadSpline5("Test",x,y,n);
01415 for (i = 0; i < n; ++i)
01416 spline->GetCoeff(i,hx,a[i],a[i+200],a[i+400],
01417 a[i+600],a[i+800],a[i+1000]);
01418 delete spline;
01419 for (i = 0; i < mm1; ++i)
01420 diff[i] = com[i] = 0;
01421 for (k = 0; k < n; ++k) {
01422 for (i = 0; i < mm; ++i)
01423 c[i] = a[k+i*200];
01424 if (n < 11) {
01425 printf(" ---------------------------------------%3d --------------------------------------------\n",k+1);
01426 printf("%12.8f\n",x[k]);
01427 if (k == n-1) printf("%16.8f\n",c[0]);
01428 }
01429 if (k == n-1) break;
01430 if (n <= 10) {
01431 for (i = 0; i < mm; ++i) printf("%16.8f",c[i]);
01432 printf("\n");
01433 }
01434 for (i = 0; i < mm1; ++i)
01435 if ((z=fabs(a[k+i*200])) > com[i])
01436 com[i] = z;
01437 z = x[k+1]-x[k];
01438 for (i = 1; i < mm; ++i)
01439 for (jj = i; jj < mm; ++jj) {
01440 j = mm+i-jj;
01441 c[j-2] = c[j-1]*z+c[j-2];
01442 }
01443 if (n <= 10) {
01444 for (i = 0; i < mm; ++i) printf("%16.8f",c[i]);
01445 printf("\n");
01446 }
01447 for (i = 0; i < mm1; ++i)
01448 if (!(k >= n-2 && i != 0))
01449 if ((z = fabs(c[i]-a[k+1+i*200]))
01450 > diff[i]) diff[i] = z;
01451 }
01452 printf(" MAXIMUM ABSOLUTE VALUES OF DIFFERENCES \n");
01453 for (i = 0; i < mm1; ++i) printf("%18.9E",diff[i]);
01454 printf("\n");
01455 printf(" MAXIMUM ABSOLUTE VALUES OF COEFFICIENTS \n");
01456 if (fabs(c[0]) > com[0])
01457 com[0] = fabs(c[0]);
01458 for (i = 0; i < mm1; ++i) printf("%16.8E",com[i]);
01459 printf("\n");
01460 }
01461
01462
01463
01464 printf("1 TEST OF TRadSpline5 WITH NONEQUIDISTANT DOUBLE KNOTS\n");
01465 n = 5;
01466 x[0] = -3;
01467 x[1] = -3;
01468 x[2] = -1;
01469 x[3] = -1;
01470 x[4] = 0;
01471 x[5] = 0;
01472 x[6] = 3;
01473 x[7] = 3;
01474 x[8] = 4;
01475 x[9] = 4;
01476 y[0] = 7;
01477 y[1] = 2;
01478 y[2] = 11;
01479 y[3] = 15;
01480 y[4] = 26;
01481 y[5] = 10;
01482 y[6] = 56;
01483 y[7] = -27;
01484 y[8] = 29;
01485 y[9] = -30;
01486 m = 3;
01487 nn = n << 1;
01488 mm = m << 1;
01489 mm1 = mm-1;
01490 printf("-N = %3d M =%2d\n",n,m);
01491 spline = new TRadSpline5("Test",x,y,nn);
01492 for (i = 0; i < nn; ++i)
01493 spline->GetCoeff(i,hx,a[i],a[i+200],a[i+400],
01494 a[i+600],a[i+800],a[i+1000]);
01495 delete spline;
01496 for (i = 0; i < mm1; ++i)
01497 diff[i] = com[i] = 0;
01498 for (k = 0; k < nn; ++k) {
01499 for (i = 0; i < mm; ++i)
01500 c[i] = a[k+i*200];
01501 printf(" ---------------------------------------%3d --------------------------------------------\n",k+1);
01502 printf("%12.8f\n",x[k]);
01503 if (k == nn-1) {
01504 printf("%16.8f\n",c[0]);
01505 break;
01506 }
01507 for (i = 0; i < mm; ++i) printf("%16.8f",c[i]);
01508 printf("\n");
01509 for (i = 0; i < mm1; ++i)
01510 if ((z=fabs(a[k+i*200])) > com[i]) com[i] = z;
01511 z = x[k+1]-x[k];
01512 for (i = 1; i < mm; ++i)
01513 for (jj = i; jj < mm; ++jj) {
01514 j = mm+i-jj;
01515 c[j-2] = c[j-1]*z+c[j-2];
01516 }
01517 for (i = 0; i < mm; ++i) printf("%16.8f",c[i]);
01518 printf("\n");
01519 for (i = 0; i < mm1; ++i)
01520 if (!(k >= nn-2 && i != 0))
01521 if ((z = fabs(c[i]-a[k+1+i*200]))
01522 > diff[i]) diff[i] = z;
01523 }
01524 printf(" MAXIMUM ABSOLUTE VALUES OF DIFFERENCES \n");
01525 for (i = 1; i <= mm1; ++i) {
01526 printf("%18.9E",diff[i-1]);
01527 }
01528 printf("\n");
01529 if (fabs(c[0]) > com[0])
01530 com[0] = fabs(c[0]);
01531 printf(" MAXIMUM ABSOLUTE VALUES OF COEFFICIENTS \n");
01532 for (i = 0; i < mm1; ++i) printf("%16.8f",com[i]);
01533 printf("\n");
01534 m = 3;
01535 for (n = 10; n <= 100; n += 10) {
01536 nn = n << 1;
01537 mm = m << 1;
01538 mm1 = mm-1;
01539 p = 0;
01540 for (i = 0; i < n; ++i) {
01541 p += fabs(sin(i+1));
01542 x[(i << 1)] = p;
01543 x[(i << 1)+1] = p;
01544 y[(i << 1)] = cos(i+1)-.5;
01545 y[(i << 1)+1] = cos((i << 1)+2)-.5;
01546 }
01547 printf("-N = %3d M =%2d\n",n,m);
01548 spline = new TRadSpline5("Test",x,y,nn);
01549 for (i = 0; i < nn; ++i)
01550 spline->GetCoeff(i,hx,a[i],a[i+200],a[i+400],
01551 a[i+600],a[i+800],a[i+1000]);
01552 delete spline;
01553 for (i = 0; i < mm1; ++i)
01554 diff[i] = com[i] = 0;
01555 for (k = 0; k < nn; ++k) {
01556 for (i = 0; i < mm; ++i)
01557 c[i] = a[k+i*200];
01558 if (n < 11) {
01559 printf(" ---------------------------------------%3d --------------------------------------------\n",k+1);
01560 printf("%12.8f\n",x[k]);
01561 if (k == nn-1) printf("%16.8f\n",c[0]);
01562 }
01563 if (k == nn-1) break;
01564 if (n <= 10) {
01565 for (i = 0; i < mm; ++i) printf("%16.8f",c[i]);
01566 printf("\n");
01567 }
01568 for (i = 0; i < mm1; ++i)
01569 if ((z=fabs(a[k+i*200])) > com[i]) com[i] = z;
01570 z = x[k+1]-x[k];
01571 for (i = 1; i < mm; ++i) {
01572 for (jj = i; jj < mm; ++jj) {
01573 j = mm+i-jj;
01574 c[j-2] = c[j-1]*z+c[j-2];
01575 }
01576 }
01577 if (n <= 10) {
01578 for (i = 0; i < mm; ++i) printf("%16.8f",c[i]);
01579 printf("\n");
01580 }
01581 for (i = 0; i < mm1; ++i)
01582 if (!(k >= nn-2 && i != 0))
01583 if ((z = fabs(c[i]-a[k+1+i*200]))
01584 > diff[i]) diff[i] = z;
01585 }
01586 printf(" MAXIMUM ABSOLUTE VALUES OF DIFFERENCES \n");
01587 for (i = 0; i < mm1; ++i) printf("%18.9E",diff[i]);
01588 printf("\n");
01589 printf(" MAXIMUM ABSOLUTE VALUES OF COEFFICIENTS \n");
01590 if (fabs(c[0]) > com[0])
01591 com[0] = fabs(c[0]);
01592 for (i = 0; i < mm1; ++i) printf("%18.9E",com[i]);
01593 printf("\n");
01594 }
01595
01596
01597
01598
01599 printf("1 TEST OF TRadSpline5 WITH NONEQUIDISTANT KNOTS,\n");
01600 printf(" ONE DOUBLE, ONE TRIPLE KNOT\n");
01601 n = 8;
01602 x[0] = -3;
01603 x[1] = -1;
01604 x[2] = -1;
01605 x[3] = 0;
01606 x[4] = 3;
01607 x[5] = 3;
01608 x[6] = 3;
01609 x[7] = 4;
01610 y[0] = 7;
01611 y[1] = 11;
01612 y[2] = 15;
01613 y[3] = 26;
01614 y[4] = 56;
01615 y[5] = -30;
01616 y[6] = -7;
01617 y[7] = 29;
01618 m = 3;
01619 mm = m << 1;
01620 mm1 = mm-1;
01621 printf("-N = %3d M =%2d\n",n,m);
01622 spline=new TRadSpline5("Test",x,y,n);
01623 for (i = 0; i < n; ++i)
01624 spline->GetCoeff(i,hx,a[i],a[i+200],a[i+400],
01625 a[i+600],a[i+800],a[i+1000]);
01626 delete spline;
01627 for (i = 0; i < mm1; ++i)
01628 diff[i] = com[i] = 0;
01629 for (k = 0; k < n; ++k) {
01630 for (i = 0; i < mm; ++i)
01631 c[i] = a[k+i*200];
01632 printf(" ---------------------------------------%3d --------------------------------------------\n",k+1);
01633 printf("%12.8f\n",x[k]);
01634 if (k == n-1) {
01635 printf("%16.8f\n",c[0]);
01636 break;
01637 }
01638 for (i = 0; i < mm; ++i) printf("%16.8f",c[i]);
01639 printf("\n");
01640 for (i = 0; i < mm1; ++i)
01641 if ((z=fabs(a[k+i*200])) > com[i]) com[i] = z;
01642 z = x[k+1]-x[k];
01643 for (i = 1; i < mm; ++i)
01644 for (jj = i; jj < mm; ++jj) {
01645 j = mm+i-jj;
01646 c[j-2] = c[j-1]*z+c[j-2];
01647 }
01648 for (i = 0; i < mm; ++i) printf("%16.8f",c[i]);
01649 printf("\n");
01650 for (i = 0; i < mm1; ++i)
01651 if (!(k >= n-2 && i != 0))
01652 if ((z = fabs(c[i]-a[k+1+i*200]))
01653 > diff[i]) diff[i] = z;
01654 }
01655 printf(" MAXIMUM ABSOLUTE VALUES OF DIFFERENCES \n");
01656 for (i = 0; i < mm1; ++i) printf("%18.9E",diff[i]);
01657 printf("\n");
01658 printf(" MAXIMUM ABSOLUTE VALUES OF COEFFICIENTS \n");
01659 if (fabs(c[0]) > com[0])
01660 com[0] = fabs(c[0]);
01661 for (i = 0; i < mm1; ++i) printf("%16.8f",com[i]);
01662 printf("\n");
01663
01664
01665
01666
01667 printf("1 TEST OF TRadSpline5 WITH NONEQUIDISTANT KNOTS,\n");
01668 printf(" TWO DOUBLE, ONE TRIPLE KNOT\n");
01669 n = 10;
01670 x[0] = 0;
01671 x[1] = 2;
01672 x[2] = 2;
01673 x[3] = 3;
01674 x[4] = 3;
01675 x[5] = 3;
01676 x[6] = 5;
01677 x[7] = 8;
01678 x[8] = 9;
01679 x[9] = 9;
01680 y[0] = 163;
01681 y[1] = 237;
01682 y[2] = -127;
01683 y[3] = 119;
01684 y[4] = -65;
01685 y[5] = 192;
01686 y[6] = 293;
01687 y[7] = 326;
01688 y[8] = 0;
01689 y[9] = -414;
01690 m = 3;
01691 mm = m << 1;
01692 mm1 = mm-1;
01693 printf("-N = %3d M =%2d\n",n,m);
01694 spline = new TRadSpline5("Test",x,y,n);
01695 for (i = 0; i < n; ++i)
01696 spline->GetCoeff(i,hx,a[i],a[i+200],a[i+400],
01697 a[i+600],a[i+800],a[i+1000]);
01698 delete spline;
01699 for (i = 0; i < mm1; ++i)
01700 diff[i] = com[i] = 0;
01701 for (k = 0; k < n; ++k) {
01702 for (i = 0; i < mm; ++i)
01703 c[i] = a[k+i*200];
01704 printf(" ---------------------------------------%3d --------------------------------------------\n",k+1);
01705 printf("%12.8f\n",x[k]);
01706 if (k == n-1) {
01707 printf("%16.8f\n",c[0]);
01708 break;
01709 }
01710 for (i = 0; i < mm; ++i) printf("%16.8f",c[i]);
01711 printf("\n");
01712 for (i = 0; i < mm1; ++i)
01713 if ((z=fabs(a[k+i*200])) > com[i]) com[i] = z;
01714 z = x[k+1]-x[k];
01715 for (i = 1; i < mm; ++i)
01716 for (jj = i; jj < mm; ++jj) {
01717 j = mm+i-jj;
01718 c[j-2] = c[j-1]*z+c[j-2];
01719 }
01720 for (i = 0; i < mm; ++i) printf("%16.8f",c[i]);
01721 printf("\n");
01722 for (i = 0; i < mm1; ++i)
01723 if (!(k >= n-2 && i != 0))
01724 if((z = fabs(c[i]-a[k+1+i*200]))
01725 > diff[i]) diff[i] = z;
01726 }
01727 printf(" MAXIMUM ABSOLUTE VALUES OF DIFFERENCES \n");
01728 for (i = 0; i < mm1; ++i) printf("%18.9E",diff[i]);
01729 printf("\n");
01730 printf(" MAXIMUM ABSOLUTE VALUES OF COEFFICIENTS \n");
01731 if (fabs(c[0]) > com[0])
01732 com[0] = fabs(c[0]);
01733 for (i = 0; i < mm1; ++i) printf("%16.8f",com[i]);
01734 printf("\n");
01735 }