public static int Main(string[] args) { double[] x = new double[0]; double[] y = new double[0]; double[] w = new double[0]; double[] xc = new double[0]; double[] yc = new double[0]; int[] dc = new int[0]; int n = 0; int i = 0; int info = 0; spline1d.spline1dinterpolant s = new spline1d.spline1dinterpolant(); double t = 0; spline1d.spline1dfitreport rep = new spline1d.spline1dfitreport(); // // Fitting by constrained Hermite spline // System.Console.Write("FITTING BY CONSTRAINED HERMITE SPLINE"); System.Console.WriteLine(); System.Console.WriteLine(); System.Console.Write("F(x)=sin(x) function being fitted"); System.Console.WriteLine(); System.Console.Write("[0, pi] interval"); System.Console.WriteLine(); System.Console.Write("M=6 number of basis functions to use"); System.Console.WriteLine(); System.Console.Write("S(0)=0 first constraint"); System.Console.WriteLine(); System.Console.Write("S(pi)=0 second constraint"); System.Console.WriteLine(); System.Console.Write("N=100 number of points to fit"); System.Console.WriteLine(); // // Create and fit: // * X contains points // * Y contains values // * W contains weights // * XC contains constraints locations // * YC contains constraints values // * DC contains derivative indexes (0 = constrained function value) // n = 100; x = new double[n]; y = new double[n]; w = new double[n]; for (i = 0; i <= n - 1; i++) { x[i] = Math.PI * i / (n - 1); y[i] = Math.Sin(x[i]); w[i] = 1; } xc = new double[2]; yc = new double[2]; dc = new int[2]; xc[0] = 0; yc[0] = 0; dc[0] = 0; xc[0] = Math.PI; yc[0] = 0; dc[0] = 0; spline1d.spline1dfithermitewc(ref x, ref y, ref w, n, ref xc, ref yc, ref dc, 2, 6, ref info, ref s, ref rep); // // Output results // if (info > 0) { System.Console.WriteLine(); System.Console.Write("OK, we have finished"); System.Console.WriteLine(); System.Console.WriteLine(); System.Console.Write(" x F(x) S(x) Error"); System.Console.WriteLine(); t = 0; while ((double)(t) < (double)(0.999999 * Math.PI)) { System.Console.Write("{0,6:F3}", t); System.Console.Write(" "); System.Console.Write("{0,6:F3}", Math.Sin(t)); System.Console.Write(" "); System.Console.Write("{0,6:F3}", spline1d.spline1dcalc(ref s, t)); System.Console.Write(" "); System.Console.Write("{0,6:F3}", Math.Abs(spline1d.spline1dcalc(ref s, t) - Math.Sin(t))); System.Console.WriteLine(); t = Math.Min(Math.PI, t + 0.25); } System.Console.Write("{0,6:F3}", t); System.Console.Write(" "); System.Console.Write("{0,6:F3}", Math.Sin(t)); System.Console.Write(" "); System.Console.Write("{0,6:F3}", spline1d.spline1dcalc(ref s, t)); System.Console.Write(" "); System.Console.Write("{0,6:F3}", Math.Abs(spline1d.spline1dcalc(ref s, t) - Math.Sin(t))); System.Console.WriteLine(); System.Console.WriteLine(); System.Console.Write("rms error is "); System.Console.Write("{0,6:F3}", rep.rmserror); System.Console.WriteLine(); System.Console.Write("max error is "); System.Console.Write("{0,6:F3}", rep.maxerror); System.Console.WriteLine(); System.Console.Write("S(0) = S(pi) = 0 (exactly)"); System.Console.WriteLine(); System.Console.WriteLine(); } else { System.Console.WriteLine(); System.Console.Write("Something wrong, Info="); System.Console.Write("{0,0:d}", info); } return(0); }
public static int Main(string[] args) { double[] x = new double[0]; double[] y = new double[0]; int n = 0; int i = 0; int info = 0; spline1d.spline1dinterpolant s = new spline1d.spline1dinterpolant(); double t = 0; spline1d.spline1dfitreport rep = new spline1d.spline1dfitreport(); // // Fitting by unconstrained natural cubic spline // System.Console.Write("FITTING BY UNCONSTRAINED NATURAL CUBIC SPLINE"); System.Console.WriteLine(); System.Console.WriteLine(); System.Console.Write("F(x)=sin(x) function being fitted"); System.Console.WriteLine(); System.Console.Write("[0, pi] interval"); System.Console.WriteLine(); System.Console.Write("M=4 number of basis functions to use"); System.Console.WriteLine(); System.Console.Write("N=100 number of points to fit"); System.Console.WriteLine(); // // Create and fit // n = 100; x = new double[n]; y = new double[n]; for (i = 0; i <= n - 1; i++) { x[i] = Math.PI * i / (n - 1); y[i] = Math.Sin(x[i]); } spline1d.spline1dfitcubic(ref x, ref y, n, 4, ref info, ref s, ref rep); // // Output results // if (info > 0) { System.Console.WriteLine(); System.Console.Write("OK, we have finished"); System.Console.WriteLine(); System.Console.WriteLine(); System.Console.Write(" x F(x) S(x) Error"); System.Console.WriteLine(); t = 0; while ((double)(t) < (double)(0.999999 * Math.PI)) { System.Console.Write("{0,6:F3}", t); System.Console.Write(" "); System.Console.Write("{0,6:F3}", Math.Sin(t)); System.Console.Write(" "); System.Console.Write("{0,6:F3}", spline1d.spline1dcalc(ref s, t)); System.Console.Write(" "); System.Console.Write("{0,6:F3}", Math.Abs(spline1d.spline1dcalc(ref s, t) - Math.Sin(t))); System.Console.WriteLine(); t = Math.Min(Math.PI, t + 0.25); } System.Console.Write("{0,6:F3}", t); System.Console.Write(" "); System.Console.Write("{0,6:F3}", Math.Sin(t)); System.Console.Write(" "); System.Console.Write("{0,6:F3}", spline1d.spline1dcalc(ref s, t)); System.Console.Write(" "); System.Console.Write("{0,6:F3}", Math.Abs(spline1d.spline1dcalc(ref s, t) - Math.Sin(t))); System.Console.WriteLine(); System.Console.WriteLine(); System.Console.Write("rms error is "); System.Console.Write("{0,6:F3}", rep.rmserror); System.Console.WriteLine(); System.Console.Write("max error is "); System.Console.Write("{0,6:F3}", rep.maxerror); System.Console.WriteLine(); } else { System.Console.WriteLine(); System.Console.Write("Something wrong, Info="); System.Console.Write("{0,0:d}", info); } return(0); }
public static int Main(string[] args) { double[] x = new double[0]; double[] y = new double[0]; double[] w = new double[0]; double[] xc = new double[0]; double[] yc = new double[0]; int[] dc = new int[0]; int n = 0; int i = 0; int info = 0; spline1d.spline1dinterpolant s = new spline1d.spline1dinterpolant(); double t = 0; spline1d.spline1dfitreport rep = new spline1d.spline1dfitreport(); // // Fitting by constrained Hermite spline // System.Console.Write("FITTING BY CONSTRAINED HERMITE SPLINE"); System.Console.WriteLine(); System.Console.WriteLine(); System.Console.Write("F(x)=sin(x) function being fitted"); System.Console.WriteLine(); System.Console.Write("[0, pi] interval"); System.Console.WriteLine(); System.Console.Write("M=6 number of basis functions to use"); System.Console.WriteLine(); System.Console.Write("S(0)=0 first constraint"); System.Console.WriteLine(); System.Console.Write("S(pi)=0 second constraint"); System.Console.WriteLine(); System.Console.Write("N=100 number of points to fit"); System.Console.WriteLine(); // // Create and fit: // * X contains points // * Y contains values // * W contains weights // * XC contains constraints locations // * YC contains constraints values // * DC contains derivative indexes (0 = constrained function value) // n = 100; x = new double[n]; y = new double[n]; w = new double[n]; for(i=0; i<=n-1; i++) { x[i] = Math.PI*i/(n-1); y[i] = Math.Sin(x[i]); w[i] = 1; } xc = new double[2]; yc = new double[2]; dc = new int[2]; xc[0] = 0; yc[0] = 0; dc[0] = 0; xc[0] = Math.PI; yc[0] = 0; dc[0] = 0; spline1d.spline1dfithermitewc(ref x, ref y, ref w, n, ref xc, ref yc, ref dc, 2, 6, ref info, ref s, ref rep); // // Output results // if( info>0 ) { System.Console.WriteLine(); System.Console.Write("OK, we have finished"); System.Console.WriteLine(); System.Console.WriteLine(); System.Console.Write(" x F(x) S(x) Error"); System.Console.WriteLine(); t = 0; while( (double)(t)<(double)(0.999999*Math.PI) ) { System.Console.Write("{0,6:F3}",t); System.Console.Write(" "); System.Console.Write("{0,6:F3}",Math.Sin(t)); System.Console.Write(" "); System.Console.Write("{0,6:F3}",spline1d.spline1dcalc(ref s, t)); System.Console.Write(" "); System.Console.Write("{0,6:F3}",Math.Abs(spline1d.spline1dcalc(ref s, t)-Math.Sin(t))); System.Console.WriteLine(); t = Math.Min(Math.PI, t+0.25); } System.Console.Write("{0,6:F3}",t); System.Console.Write(" "); System.Console.Write("{0,6:F3}",Math.Sin(t)); System.Console.Write(" "); System.Console.Write("{0,6:F3}",spline1d.spline1dcalc(ref s, t)); System.Console.Write(" "); System.Console.Write("{0,6:F3}",Math.Abs(spline1d.spline1dcalc(ref s, t)-Math.Sin(t))); System.Console.WriteLine(); System.Console.WriteLine(); System.Console.Write("rms error is "); System.Console.Write("{0,6:F3}",rep.rmserror); System.Console.WriteLine(); System.Console.Write("max error is "); System.Console.Write("{0,6:F3}",rep.maxerror); System.Console.WriteLine(); System.Console.Write("S(0) = S(pi) = 0 (exactly)"); System.Console.WriteLine(); System.Console.WriteLine(); } else { System.Console.WriteLine(); System.Console.Write("Something wrong, Info="); System.Console.Write("{0,0:d}",info); } return 0; }
public static bool testspline1d(bool silent) { bool result = new bool(); bool waserrors = new bool(); bool crserrors = new bool(); bool cserrors = new bool(); bool hserrors = new bool(); bool aserrors = new bool(); bool lserrors = new bool(); bool dserrors = new bool(); bool uperrors = new bool(); bool cperrors = new bool(); bool lterrors = new bool(); bool ierrors = new bool(); bool fiterrors = new bool(); double nonstrictthreshold = 0; double threshold = 0; int passcount = 0; double lstep = 0; double h = 0; int maxn = 0; int bltype = 0; int brtype = 0; bool periodiccond = new bool(); int n = 0; int m = 0; int i = 0; int k = 0; int pass = 0; int stype = 0; double[] x = new double[0]; double[] y = new double[0]; double[] yp = new double[0]; double[] w = new double[0]; double[] w2 = new double[0]; double[] y2 = new double[0]; double[] d = new double[0]; double[] xc = new double[0]; double[] yc = new double[0]; int n2 = 0; double[] tmp0 = new double[0]; double[] tmp1 = new double[0]; double[] tmp2 = new double[0]; double[] tmpx = new double[0]; int[] dc = new int[0]; spline1d.spline1dinterpolant c = new spline1d.spline1dinterpolant(); spline1d.spline1dinterpolant c2 = new spline1d.spline1dinterpolant(); int info = 0; int info1 = 0; int info2 = 0; double a = 0; double b = 0; double bl = 0; double br = 0; double t = 0; double sa = 0; double sb = 0; double v = 0; double v1 = 0; double v2 = 0; double l10 = 0; double l11 = 0; double l12 = 0; double l20 = 0; double l21 = 0; double l22 = 0; double p0 = 0; double p1 = 0; double p2 = 0; double s = 0; double ds = 0; double d2s = 0; double s2 = 0; double ds2 = 0; double d2s2 = 0; double vl = 0; double vm = 0; double vr = 0; double err = 0; double tension = 0; double intab = 0; spline1d.spline1dfitreport rep = new spline1d.spline1dfitreport(); spline1d.spline1dfitreport rep2 = new spline1d.spline1dfitreport(); double refrms = 0; double refavg = 0; double refavgrel = 0; double refmax = 0; int i_ = 0; waserrors = false; passcount = 20; lstep = 0.005; h = 0.00001; maxn = 10; threshold = 10000*math.machineepsilon; nonstrictthreshold = 0.00001; lserrors = false; cserrors = false; crserrors = false; hserrors = false; aserrors = false; dserrors = false; cperrors = false; uperrors = false; lterrors = false; ierrors = false; fiterrors = false; // // General test: linear, cubic, Hermite, Akima // for(n=2; n<=maxn; n++) { x = new double[n-1+1]; y = new double[n-1+1]; yp = new double[n-1+1]; d = new double[n-1+1]; for(pass=1; pass<=passcount; pass++) { // // Prepare task: // * X contains abscissas from [A,B] // * Y contains function values // * YP contains periodic function values // a = -1-math.randomreal(); b = 1+math.randomreal(); bl = 2*math.randomreal()-1; br = 2*math.randomreal()-1; for(i=0; i<=n-1; i++) { x[i] = 0.5*(b+a)+0.5*(b-a)*Math.Cos(Math.PI*(2*i+1)/(2*n)); if( i==0 ) { x[i] = a; } if( i==n-1 ) { x[i] = b; } y[i] = Math.Cos(1.3*Math.PI*x[i]+0.4); yp[i] = y[i]; d[i] = -(1.3*Math.PI*Math.Sin(1.3*Math.PI*x[i]+0.4)); } yp[n-1] = yp[0]; for(i=0; i<=n-1; i++) { k = math.randominteger(n); if( k!=i ) { t = x[i]; x[i] = x[k]; x[k] = t; t = y[i]; y[i] = y[k]; y[k] = t; t = yp[i]; yp[i] = yp[k]; yp[k] = t; t = d[i]; d[i] = d[k]; d[k] = t; } } // // Build linear spline // Test for general interpolation scheme properties: // * values at nodes // * continuous function // Test for specific properties is implemented below. // spline1d.spline1dbuildlinear(x, y, n, c); err = 0; for(i=0; i<=n-1; i++) { err = Math.Max(err, Math.Abs(y[i]-spline1d.spline1dcalc(c, x[i]))); } lserrors = lserrors | (double)(err)>(double)(threshold); lconst(a, b, c, lstep, ref l10, ref l11, ref l12); lconst(a, b, c, lstep/3, ref l20, ref l21, ref l22); lserrors = lserrors | (double)(l20/l10)>(double)(1.2); // // Build cubic spline. // Test for interpolation scheme properties: // * values at nodes // * boundary conditions // * continuous function // * continuous first derivative // * continuous second derivative // * periodicity properties // * Spline1DGridDiff(), Spline1DGridDiff2() and Spline1DDiff() // calls must return same results // for(bltype=-1; bltype<=2; bltype++) { for(brtype=-1; brtype<=2; brtype++) { // // skip meaningless combination of boundary conditions // (one condition is periodic, another is not) // periodiccond = bltype==-1 | brtype==-1; if( periodiccond & bltype!=brtype ) { continue; } // // build // if( periodiccond ) { spline1d.spline1dbuildcubic(x, yp, n, bltype, bl, brtype, br, c); } else { spline1d.spline1dbuildcubic(x, y, n, bltype, bl, brtype, br, c); } // // interpolation properties // err = 0; if( periodiccond ) { // // * check values at nodes; spline is periodic so // we add random number of periods to nodes // * we also test for periodicity of derivatives // for(i=0; i<=n-1; i++) { v = x[i]; vm = v+(b-a)*(math.randominteger(5)-2); t = yp[i]-spline1d.spline1dcalc(c, vm); err = Math.Max(err, Math.Abs(t)); spline1d.spline1ddiff(c, v, ref s, ref ds, ref d2s); spline1d.spline1ddiff(c, vm, ref s2, ref ds2, ref d2s2); err = Math.Max(err, Math.Abs(s-s2)); err = Math.Max(err, Math.Abs(ds-ds2)); err = Math.Max(err, Math.Abs(d2s-d2s2)); } // // periodicity between nodes // v = a+(b-a)*math.randomreal(); vm = v+(b-a)*(math.randominteger(5)-2); err = Math.Max(err, Math.Abs(spline1d.spline1dcalc(c, v)-spline1d.spline1dcalc(c, vm))); spline1d.spline1ddiff(c, v, ref s, ref ds, ref d2s); spline1d.spline1ddiff(c, vm, ref s2, ref ds2, ref d2s2); err = Math.Max(err, Math.Abs(s-s2)); err = Math.Max(err, Math.Abs(ds-ds2)); err = Math.Max(err, Math.Abs(d2s-d2s2)); } else { // // * check values at nodes // for(i=0; i<=n-1; i++) { err = Math.Max(err, Math.Abs(y[i]-spline1d.spline1dcalc(c, x[i]))); } } cserrors = cserrors | (double)(err)>(double)(threshold); // // check boundary conditions // err = 0; if( bltype==0 ) { spline1d.spline1ddiff(c, a-h, ref s, ref ds, ref d2s); spline1d.spline1ddiff(c, a+h, ref s2, ref ds2, ref d2s2); t = (d2s2-d2s)/(2*h); err = Math.Max(err, Math.Abs(t)); } if( bltype==1 ) { t = (spline1d.spline1dcalc(c, a+h)-spline1d.spline1dcalc(c, a-h))/(2*h); err = Math.Max(err, Math.Abs(bl-t)); } if( bltype==2 ) { t = (spline1d.spline1dcalc(c, a+h)-2*spline1d.spline1dcalc(c, a)+spline1d.spline1dcalc(c, a-h))/math.sqr(h); err = Math.Max(err, Math.Abs(bl-t)); } if( brtype==0 ) { spline1d.spline1ddiff(c, b-h, ref s, ref ds, ref d2s); spline1d.spline1ddiff(c, b+h, ref s2, ref ds2, ref d2s2); t = (d2s2-d2s)/(2*h); err = Math.Max(err, Math.Abs(t)); } if( brtype==1 ) { t = (spline1d.spline1dcalc(c, b+h)-spline1d.spline1dcalc(c, b-h))/(2*h); err = Math.Max(err, Math.Abs(br-t)); } if( brtype==2 ) { t = (spline1d.spline1dcalc(c, b+h)-2*spline1d.spline1dcalc(c, b)+spline1d.spline1dcalc(c, b-h))/math.sqr(h); err = Math.Max(err, Math.Abs(br-t)); } if( bltype==-1 | brtype==-1 ) { spline1d.spline1ddiff(c, a+100*math.machineepsilon, ref s, ref ds, ref d2s); spline1d.spline1ddiff(c, b-100*math.machineepsilon, ref s2, ref ds2, ref d2s2); err = Math.Max(err, Math.Abs(s-s2)); err = Math.Max(err, Math.Abs(ds-ds2)); err = Math.Max(err, Math.Abs(d2s-d2s2)); } cserrors = cserrors | (double)(err)>(double)(1.0E-3); // // Check Lipschitz continuity // lconst(a, b, c, lstep, ref l10, ref l11, ref l12); lconst(a, b, c, lstep/3, ref l20, ref l21, ref l22); if( (double)(l10)>(double)(1.0E-6) ) { cserrors = cserrors | (double)(l20/l10)>(double)(1.2); } if( (double)(l11)>(double)(1.0E-6) ) { cserrors = cserrors | (double)(l21/l11)>(double)(1.2); } if( (double)(l12)>(double)(1.0E-6) ) { cserrors = cserrors | (double)(l22/l12)>(double)(1.2); } // // compare spline1dgriddiff() and spline1ddiff() results // err = 0; if( periodiccond ) { spline1d.spline1dgriddiffcubic(x, yp, n, bltype, bl, brtype, br, ref tmp1); } else { spline1d.spline1dgriddiffcubic(x, y, n, bltype, bl, brtype, br, ref tmp1); } ap.assert(ap.len(tmp1)>=n); for(i=0; i<=n-1; i++) { spline1d.spline1ddiff(c, x[i], ref s, ref ds, ref d2s); err = Math.Max(err, Math.Abs(ds-tmp1[i])); } if( periodiccond ) { spline1d.spline1dgriddiff2cubic(x, yp, n, bltype, bl, brtype, br, ref tmp1, ref tmp2); } else { spline1d.spline1dgriddiff2cubic(x, y, n, bltype, bl, brtype, br, ref tmp1, ref tmp2); } for(i=0; i<=n-1; i++) { spline1d.spline1ddiff(c, x[i], ref s, ref ds, ref d2s); err = Math.Max(err, Math.Abs(ds-tmp1[i])); err = Math.Max(err, Math.Abs(d2s-tmp2[i])); } cserrors = cserrors | (double)(err)>(double)(threshold); // // compare spline1dconv()/convdiff()/convdiff2() and spline1ddiff() results // n2 = 2*n+math.randominteger(n); tmpx = new double[n2]; for(i=0; i<=n2-1; i++) { tmpx[i] = 0.5*(a+b)+(a-b)*(2*math.randomreal()-1); } err = 0; if( periodiccond ) { spline1d.spline1dconvcubic(x, yp, n, bltype, bl, brtype, br, tmpx, n2, ref tmp0); } else { spline1d.spline1dconvcubic(x, y, n, bltype, bl, brtype, br, tmpx, n2, ref tmp0); } for(i=0; i<=n2-1; i++) { spline1d.spline1ddiff(c, tmpx[i], ref s, ref ds, ref d2s); err = Math.Max(err, Math.Abs(s-tmp0[i])); } if( periodiccond ) { spline1d.spline1dconvdiffcubic(x, yp, n, bltype, bl, brtype, br, tmpx, n2, ref tmp0, ref tmp1); } else { spline1d.spline1dconvdiffcubic(x, y, n, bltype, bl, brtype, br, tmpx, n2, ref tmp0, ref tmp1); } for(i=0; i<=n2-1; i++) { spline1d.spline1ddiff(c, tmpx[i], ref s, ref ds, ref d2s); err = Math.Max(err, Math.Abs(s-tmp0[i])); err = Math.Max(err, Math.Abs(ds-tmp1[i])); } if( periodiccond ) { spline1d.spline1dconvdiff2cubic(x, yp, n, bltype, bl, brtype, br, tmpx, n2, ref tmp0, ref tmp1, ref tmp2); } else { spline1d.spline1dconvdiff2cubic(x, y, n, bltype, bl, brtype, br, tmpx, n2, ref tmp0, ref tmp1, ref tmp2); } for(i=0; i<=n2-1; i++) { spline1d.spline1ddiff(c, tmpx[i], ref s, ref ds, ref d2s); err = Math.Max(err, Math.Abs(s-tmp0[i])); err = Math.Max(err, Math.Abs(ds-tmp1[i])); err = Math.Max(err, Math.Abs(d2s-tmp2[i])); } cserrors = cserrors | (double)(err)>(double)(threshold); } } // // Build Catmull-Rom spline. // Test for interpolation scheme properties: // * values at nodes // * boundary conditions // * continuous function // * continuous first derivative // * periodicity properties // for(bltype=-1; bltype<=0; bltype++) { periodiccond = bltype==-1; // // select random tension value, then build // if( (double)(math.randomreal())>(double)(0.5) ) { if( (double)(math.randomreal())>(double)(0.5) ) { tension = 0; } else { tension = 1; } } else { tension = math.randomreal(); } if( periodiccond ) { spline1d.spline1dbuildcatmullrom(x, yp, n, bltype, tension, c); } else { spline1d.spline1dbuildcatmullrom(x, y, n, bltype, tension, c); } // // interpolation properties // err = 0; if( periodiccond ) { // // * check values at nodes; spline is periodic so // we add random number of periods to nodes // * we also test for periodicity of first derivative // for(i=0; i<=n-1; i++) { v = x[i]; vm = v+(b-a)*(math.randominteger(5)-2); t = yp[i]-spline1d.spline1dcalc(c, vm); err = Math.Max(err, Math.Abs(t)); spline1d.spline1ddiff(c, v, ref s, ref ds, ref d2s); spline1d.spline1ddiff(c, vm, ref s2, ref ds2, ref d2s2); err = Math.Max(err, Math.Abs(s-s2)); err = Math.Max(err, Math.Abs(ds-ds2)); } // // periodicity between nodes // v = a+(b-a)*math.randomreal(); vm = v+(b-a)*(math.randominteger(5)-2); err = Math.Max(err, Math.Abs(spline1d.spline1dcalc(c, v)-spline1d.spline1dcalc(c, vm))); spline1d.spline1ddiff(c, v, ref s, ref ds, ref d2s); spline1d.spline1ddiff(c, vm, ref s2, ref ds2, ref d2s2); err = Math.Max(err, Math.Abs(s-s2)); err = Math.Max(err, Math.Abs(ds-ds2)); } else { // // * check values at nodes // for(i=0; i<=n-1; i++) { err = Math.Max(err, Math.Abs(y[i]-spline1d.spline1dcalc(c, x[i]))); } } crserrors = crserrors | (double)(err)>(double)(threshold); // // check boundary conditions // err = 0; if( bltype==0 ) { spline1d.spline1ddiff(c, a-h, ref s, ref ds, ref d2s); spline1d.spline1ddiff(c, a+h, ref s2, ref ds2, ref d2s2); t = (d2s2-d2s)/(2*h); err = Math.Max(err, Math.Abs(t)); spline1d.spline1ddiff(c, b-h, ref s, ref ds, ref d2s); spline1d.spline1ddiff(c, b+h, ref s2, ref ds2, ref d2s2); t = (d2s2-d2s)/(2*h); err = Math.Max(err, Math.Abs(t)); } if( bltype==-1 ) { spline1d.spline1ddiff(c, a+100*math.machineepsilon, ref s, ref ds, ref d2s); spline1d.spline1ddiff(c, b-100*math.machineepsilon, ref s2, ref ds2, ref d2s2); err = Math.Max(err, Math.Abs(s-s2)); err = Math.Max(err, Math.Abs(ds-ds2)); } crserrors = crserrors | (double)(err)>(double)(1.0E-3); // // Check Lipschitz continuity // lconst(a, b, c, lstep, ref l10, ref l11, ref l12); lconst(a, b, c, lstep/3, ref l20, ref l21, ref l22); if( (double)(l10)>(double)(1.0E-6) ) { crserrors = crserrors | (double)(l20/l10)>(double)(1.2); } if( (double)(l11)>(double)(1.0E-6) ) { crserrors = crserrors | (double)(l21/l11)>(double)(1.2); } } // // Build Hermite spline. // Test for interpolation scheme properties: // * values and derivatives at nodes // * continuous function // * continuous first derivative // spline1d.spline1dbuildhermite(x, y, d, n, c); err = 0; for(i=0; i<=n-1; i++) { err = Math.Max(err, Math.Abs(y[i]-spline1d.spline1dcalc(c, x[i]))); } hserrors = hserrors | (double)(err)>(double)(threshold); err = 0; for(i=0; i<=n-1; i++) { t = (spline1d.spline1dcalc(c, x[i]+h)-spline1d.spline1dcalc(c, x[i]-h))/(2*h); err = Math.Max(err, Math.Abs(d[i]-t)); } hserrors = hserrors | (double)(err)>(double)(1.0E-3); lconst(a, b, c, lstep, ref l10, ref l11, ref l12); lconst(a, b, c, lstep/3, ref l20, ref l21, ref l22); hserrors = hserrors | (double)(l20/l10)>(double)(1.2); hserrors = hserrors | (double)(l21/l11)>(double)(1.2); // // Build Akima spline // Test for general interpolation scheme properties: // * values at nodes // * continuous function // * continuous first derivative // Test for specific properties is implemented below. // if( n>=5 ) { spline1d.spline1dbuildakima(x, y, n, c); err = 0; for(i=0; i<=n-1; i++) { err = Math.Max(err, Math.Abs(y[i]-spline1d.spline1dcalc(c, x[i]))); } aserrors = aserrors | (double)(err)>(double)(threshold); lconst(a, b, c, lstep, ref l10, ref l11, ref l12); lconst(a, b, c, lstep/3, ref l20, ref l21, ref l22); hserrors = hserrors | (double)(l20/l10)>(double)(1.2); hserrors = hserrors | (double)(l21/l11)>(double)(1.2); } } } // // Special linear spline test: // test for linearity between x[i] and x[i+1] // for(n=2; n<=maxn; n++) { x = new double[n-1+1]; y = new double[n-1+1]; // // Prepare task // a = -1; b = 1; for(i=0; i<=n-1; i++) { x[i] = a+(b-a)*i/(n-1); y[i] = 2*math.randomreal()-1; } spline1d.spline1dbuildlinear(x, y, n, c); // // Test // err = 0; for(k=0; k<=n-2; k++) { a = x[k]; b = x[k+1]; for(pass=1; pass<=passcount; pass++) { t = a+(b-a)*math.randomreal(); v = y[k]+(t-a)/(b-a)*(y[k+1]-y[k]); err = Math.Max(err, Math.Abs(spline1d.spline1dcalc(c, t)-v)); } } lserrors = lserrors | (double)(err)>(double)(threshold); } // // Special Akima test: test outlier sensitivity // Spline value at (x[i], x[i+1]) should depend from // f[i-2], f[i-1], f[i], f[i+1], f[i+2], f[i+3] only. // for(n=5; n<=maxn; n++) { x = new double[n-1+1]; y = new double[n-1+1]; y2 = new double[n-1+1]; // // Prepare unperturbed Akima spline // a = -1; b = 1; for(i=0; i<=n-1; i++) { x[i] = a+(b-a)*i/(n-1); y[i] = Math.Cos(1.3*Math.PI*x[i]+0.4); } spline1d.spline1dbuildakima(x, y, n, c); // // Process perturbed tasks // err = 0; for(k=0; k<=n-1; k++) { for(i_=0; i_<=n-1;i_++) { y2[i_] = y[i_]; } y2[k] = 5; spline1d.spline1dbuildakima(x, y2, n, c2); // // Test left part independence // if( k-3>=1 ) { a = -1; b = x[k-3]; for(pass=1; pass<=passcount; pass++) { t = a+(b-a)*math.randomreal(); err = Math.Max(err, Math.Abs(spline1d.spline1dcalc(c, t)-spline1d.spline1dcalc(c2, t))); } } // // Test right part independence // if( k+3<=n-2 ) { a = x[k+3]; b = 1; for(pass=1; pass<=passcount; pass++) { t = a+(b-a)*math.randomreal(); err = Math.Max(err, Math.Abs(spline1d.spline1dcalc(c, t)-spline1d.spline1dcalc(c2, t))); } } } aserrors = aserrors | (double)(err)>(double)(threshold); } // // Differentiation, copy/unpack test // for(n=2; n<=maxn; n++) { x = new double[n-1+1]; y = new double[n-1+1]; // // Prepare cubic spline // a = -1-math.randomreal(); b = 1+math.randomreal(); for(i=0; i<=n-1; i++) { x[i] = a+(b-a)*i/(n-1); y[i] = Math.Cos(1.3*Math.PI*x[i]+0.4); } spline1d.spline1dbuildcubic(x, y, n, 2, 0.0, 2, 0.0, c); // // Test diff // err = 0; for(pass=1; pass<=passcount; pass++) { t = a+(b-a)*math.randomreal(); spline1d.spline1ddiff(c, t, ref s, ref ds, ref d2s); vl = spline1d.spline1dcalc(c, t-h); vm = spline1d.spline1dcalc(c, t); vr = spline1d.spline1dcalc(c, t+h); err = Math.Max(err, Math.Abs(s-vm)); err = Math.Max(err, Math.Abs(ds-(vr-vl)/(2*h))); err = Math.Max(err, Math.Abs(d2s-(vr-2*vm+vl)/math.sqr(h))); } dserrors = dserrors | (double)(err)>(double)(0.001); // // Test copy // unsetspline1d(c2); spline1d.spline1dcopy(c, c2); err = 0; for(pass=1; pass<=passcount; pass++) { t = a+(b-a)*math.randomreal(); err = Math.Max(err, Math.Abs(spline1d.spline1dcalc(c, t)-spline1d.spline1dcalc(c2, t))); } cperrors = cperrors | (double)(err)>(double)(threshold); // // Test unpack // uperrors = uperrors | !testunpack(c, x); // // Test lin.trans. // err = 0; for(pass=1; pass<=passcount; pass++) { // // LinTransX, general A // sa = 4*math.randomreal()-2; sb = 2*math.randomreal()-1; t = a+(b-a)*math.randomreal(); spline1d.spline1dcopy(c, c2); spline1d.spline1dlintransx(c2, sa, sb); err = Math.Max(err, Math.Abs(spline1d.spline1dcalc(c, t)-spline1d.spline1dcalc(c2, (t-sb)/sa))); // // LinTransX, special case: A=0 // sb = 2*math.randomreal()-1; t = a+(b-a)*math.randomreal(); spline1d.spline1dcopy(c, c2); spline1d.spline1dlintransx(c2, 0, sb); err = Math.Max(err, Math.Abs(spline1d.spline1dcalc(c, sb)-spline1d.spline1dcalc(c2, t))); // // LinTransY // sa = 2*math.randomreal()-1; sb = 2*math.randomreal()-1; t = a+(b-a)*math.randomreal(); spline1d.spline1dcopy(c, c2); spline1d.spline1dlintransy(c2, sa, sb); err = Math.Max(err, Math.Abs(sa*spline1d.spline1dcalc(c, t)+sb-spline1d.spline1dcalc(c2, t))); } lterrors = lterrors | (double)(err)>(double)(threshold); } // // Testing integration. // Three tests are performed: // // * approximate test (well behaved smooth function, many points, // integration inside [a,b]), non-periodic spline // // * exact test (integration of parabola, outside of [a,b], non-periodic spline // // * approximate test for periodic splines. F(x)=cos(2*pi*x)+1. // Period length is equals to 1.0, so all operations with // multiples of period are done exactly. For each value of PERIOD // we calculate and test integral at four points: // - 0 < t0 < PERIOD // - t1 = PERIOD-eps // - t2 = PERIOD // - t3 = PERIOD+eps // err = 0; for(n=20; n<=35; n++) { x = new double[n-1+1]; y = new double[n-1+1]; for(pass=1; pass<=passcount; pass++) { // // Prepare cubic spline // a = -1-0.2*math.randomreal(); b = 1+0.2*math.randomreal(); for(i=0; i<=n-1; i++) { x[i] = a+(b-a)*i/(n-1); y[i] = Math.Sin(Math.PI*x[i]+0.4)+Math.Exp(x[i]); } bl = Math.PI*Math.Cos(Math.PI*a+0.4)+Math.Exp(a); br = Math.PI*Math.Cos(Math.PI*b+0.4)+Math.Exp(b); spline1d.spline1dbuildcubic(x, y, n, 1, bl, 1, br, c); // // Test // t = a+(b-a)*math.randomreal(); v = -(Math.Cos(Math.PI*a+0.4)/Math.PI)+Math.Exp(a); v = -(Math.Cos(Math.PI*t+0.4)/Math.PI)+Math.Exp(t)-v; v = v-spline1d.spline1dintegrate(c, t); err = Math.Max(err, Math.Abs(v)); } } ierrors = ierrors | (double)(err)>(double)(0.001); p0 = 2*math.randomreal()-1; p1 = 2*math.randomreal()-1; p2 = 2*math.randomreal()-1; a = -math.randomreal()-0.5; b = math.randomreal()+0.5; n = 2; x = new double[n]; y = new double[n]; d = new double[n]; x[0] = a; y[0] = p0+p1*a+p2*math.sqr(a); d[0] = p1+2*p2*a; x[1] = b; y[1] = p0+p1*b+p2*math.sqr(b); d[1] = p1+2*p2*b; spline1d.spline1dbuildhermite(x, y, d, n, c); bl = Math.Min(a, b)-Math.Abs(b-a); br = Math.Min(a, b)+Math.Abs(b-a); err = 0; for(pass=1; pass<=100; pass++) { t = bl+(br-bl)*math.randomreal(); v = p0*t+p1*math.sqr(t)/2+p2*math.sqr(t)*t/3-(p0*a+p1*math.sqr(a)/2+p2*math.sqr(a)*a/3); v = v-spline1d.spline1dintegrate(c, t); err = Math.Max(err, Math.Abs(v)); } ierrors = ierrors | (double)(err)>(double)(threshold); n = 100; x = new double[n]; y = new double[n]; for(i=0; i<=n-1; i++) { x[i] = (double)i/(double)(n-1); y[i] = Math.Cos(2*Math.PI*x[i])+1; } y[0] = 2; y[n-1] = 2; spline1d.spline1dbuildcubic(x, y, n, -1, 0.0, -1, 0.0, c); intab = spline1d.spline1dintegrate(c, 1.0); v = math.randomreal(); vr = spline1d.spline1dintegrate(c, v); ierrors = ierrors | (double)(Math.Abs(intab-1))>(double)(0.001); for(i=-10; i<=10; i++) { ierrors = ierrors | (double)(Math.Abs(spline1d.spline1dintegrate(c, i+v)-(i*intab+vr)))>(double)(0.001); ierrors = ierrors | (double)(Math.Abs(spline1d.spline1dintegrate(c, i-1000*math.machineepsilon)-i*intab))>(double)(0.001); ierrors = ierrors | (double)(Math.Abs(spline1d.spline1dintegrate(c, i)-i*intab))>(double)(0.001); ierrors = ierrors | (double)(Math.Abs(spline1d.spline1dintegrate(c, i+1000*math.machineepsilon)-i*intab))>(double)(0.001); } // // Test fitting. // for(pass=1; pass<=passcount; pass++) { // // Cubic splines // Ability to handle boundary constraints (1-4 constraints on F, dF/dx). // for(m=4; m<=8; m++) { for(k=1; k<=4; k++) { if( k>=m ) { continue; } n = 100; x = new double[n]; y = new double[n]; w = new double[n]; xc = new double[4]; yc = new double[4]; dc = new int[4]; sa = 1+math.randomreal(); sb = 2*math.randomreal()-1; for(i=0; i<=n-1; i++) { x[i] = sa*math.randomreal()+sb; y[i] = 2*math.randomreal()-1; w[i] = 1+math.randomreal(); } xc[0] = sb; yc[0] = 2*math.randomreal()-1; dc[0] = 0; xc[1] = sb; yc[1] = 2*math.randomreal()-1; dc[1] = 1; xc[2] = sa+sb; yc[2] = 2*math.randomreal()-1; dc[2] = 0; xc[3] = sa+sb; yc[3] = 2*math.randomreal()-1; dc[3] = 1; spline1d.spline1dfitcubicwc(x, y, w, n, xc, yc, dc, k, m, ref info, c, rep); if( info<=0 ) { fiterrors = true; } else { // // Check that constraints are satisfied // for(i=0; i<=k-1; i++) { spline1d.spline1ddiff(c, xc[i], ref s, ref ds, ref d2s); if( dc[i]==0 ) { fiterrors = fiterrors | (double)(Math.Abs(s-yc[i]))>(double)(threshold); } if( dc[i]==1 ) { fiterrors = fiterrors | (double)(Math.Abs(ds-yc[i]))>(double)(threshold); } if( dc[i]==2 ) { fiterrors = fiterrors | (double)(Math.Abs(d2s-yc[i]))>(double)(threshold); } } } } } // // Cubic splines // Ability to handle one internal constraint // for(m=4; m<=8; m++) { n = 100; x = new double[n]; y = new double[n]; w = new double[n]; xc = new double[1]; yc = new double[1]; dc = new int[1]; sa = 1+math.randomreal(); sb = 2*math.randomreal()-1; for(i=0; i<=n-1; i++) { x[i] = sa*math.randomreal()+sb; y[i] = 2*math.randomreal()-1; w[i] = 1+math.randomreal(); } xc[0] = sa*math.randomreal()+sb; yc[0] = 2*math.randomreal()-1; dc[0] = math.randominteger(2); spline1d.spline1dfitcubicwc(x, y, w, n, xc, yc, dc, 1, m, ref info, c, rep); if( info<=0 ) { fiterrors = true; } else { // // Check that constraints are satisfied // spline1d.spline1ddiff(c, xc[0], ref s, ref ds, ref d2s); if( dc[0]==0 ) { fiterrors = fiterrors | (double)(Math.Abs(s-yc[0]))>(double)(threshold); } if( dc[0]==1 ) { fiterrors = fiterrors | (double)(Math.Abs(ds-yc[0]))>(double)(threshold); } if( dc[0]==2 ) { fiterrors = fiterrors | (double)(Math.Abs(d2s-yc[0]))>(double)(threshold); } } } // // Hermite splines // Ability to handle boundary constraints (1-4 constraints on F, dF/dx). // for(m=4; m<=8; m++) { for(k=1; k<=4; k++) { if( k>=m ) { continue; } if( m%2!=0 ) { continue; } n = 100; x = new double[n]; y = new double[n]; w = new double[n]; xc = new double[4]; yc = new double[4]; dc = new int[4]; sa = 1+math.randomreal(); sb = 2*math.randomreal()-1; for(i=0; i<=n-1; i++) { x[i] = sa*math.randomreal()+sb; y[i] = 2*math.randomreal()-1; w[i] = 1+math.randomreal(); } xc[0] = sb; yc[0] = 2*math.randomreal()-1; dc[0] = 0; xc[1] = sb; yc[1] = 2*math.randomreal()-1; dc[1] = 1; xc[2] = sa+sb; yc[2] = 2*math.randomreal()-1; dc[2] = 0; xc[3] = sa+sb; yc[3] = 2*math.randomreal()-1; dc[3] = 1; spline1d.spline1dfithermitewc(x, y, w, n, xc, yc, dc, k, m, ref info, c, rep); if( info<=0 ) { fiterrors = true; } else { // // Check that constraints are satisfied // for(i=0; i<=k-1; i++) { spline1d.spline1ddiff(c, xc[i], ref s, ref ds, ref d2s); if( dc[i]==0 ) { fiterrors = fiterrors | (double)(Math.Abs(s-yc[i]))>(double)(threshold); } if( dc[i]==1 ) { fiterrors = fiterrors | (double)(Math.Abs(ds-yc[i]))>(double)(threshold); } if( dc[i]==2 ) { fiterrors = fiterrors | (double)(Math.Abs(d2s-yc[i]))>(double)(threshold); } } } } } // // Hermite splines // Ability to handle one internal constraint // for(m=4; m<=8; m++) { if( m%2!=0 ) { continue; } n = 100; x = new double[n]; y = new double[n]; w = new double[n]; xc = new double[1]; yc = new double[1]; dc = new int[1]; sa = 1+math.randomreal(); sb = 2*math.randomreal()-1; for(i=0; i<=n-1; i++) { x[i] = sa*math.randomreal()+sb; y[i] = 2*math.randomreal()-1; w[i] = 1+math.randomreal(); } xc[0] = sa*math.randomreal()+sb; yc[0] = 2*math.randomreal()-1; dc[0] = math.randominteger(2); spline1d.spline1dfithermitewc(x, y, w, n, xc, yc, dc, 1, m, ref info, c, rep); if( info<=0 ) { fiterrors = true; } else { // // Check that constraints are satisfied // spline1d.spline1ddiff(c, xc[0], ref s, ref ds, ref d2s); if( dc[0]==0 ) { fiterrors = fiterrors | (double)(Math.Abs(s-yc[0]))>(double)(threshold); } if( dc[0]==1 ) { fiterrors = fiterrors | (double)(Math.Abs(ds-yc[0]))>(double)(threshold); } if( dc[0]==2 ) { fiterrors = fiterrors | (double)(Math.Abs(d2s-yc[0]))>(double)(threshold); } } } } for(m=4; m<=8; m++) { for(stype=0; stype<=1; stype++) { for(pass=1; pass<=passcount; pass++) { if( stype==1 & m%2!=0 ) { continue; } // // cubic/Hermite spline fitting: // * generate "template spline" C2 // * generate 2*N points from C2, such that result of // ideal fit should be equal to C2 // * fit, store in C // * compare C and C2 // sa = 1+math.randomreal(); sb = 2*math.randomreal()-1; if( stype==0 ) { x = new double[m-2]; y = new double[m-2]; for(i=0; i<=m-2-1; i++) { x[i] = sa*i/(m-2-1)+sb; y[i] = 2*math.randomreal()-1; } spline1d.spline1dbuildcubic(x, y, m-2, 1, 2*math.randomreal()-1, 1, 2*math.randomreal()-1, c2); } if( stype==1 ) { x = new double[m/2]; y = new double[m/2]; d = new double[m/2]; for(i=0; i<=m/2-1; i++) { x[i] = sa*i/(m/2-1)+sb; y[i] = 2*math.randomreal()-1; d[i] = 2*math.randomreal()-1; } spline1d.spline1dbuildhermite(x, y, d, m/2, c2); } n = 50; x = new double[2*n]; y = new double[2*n]; w = new double[2*n]; for(i=0; i<=n-1; i++) { // // "if i=0" and "if i=1" are needed to // synchronize interval size for C2 and // spline being fitted (i.e. C). // t = math.randomreal(); x[i] = sa*math.randomreal()+sb; if( i==0 ) { x[i] = sb; } if( i==1 ) { x[i] = sa+sb; } v = spline1d.spline1dcalc(c2, x[i]); y[i] = v+t; w[i] = 1+math.randomreal(); x[n+i] = x[i]; y[n+i] = v-t; w[n+i] = w[i]; } if( stype==0 ) { spline1d.spline1dfitcubicwc(x, y, w, 2*n, xc, yc, dc, 0, m, ref info, c, rep); } if( stype==1 ) { spline1d.spline1dfithermitewc(x, y, w, 2*n, xc, yc, dc, 0, m, ref info, c, rep); } if( info<=0 ) { fiterrors = true; } else { for(i=0; i<=n-1; i++) { v = sa*math.randomreal()+sb; fiterrors = fiterrors | (double)(Math.Abs(spline1d.spline1dcalc(c, v)-spline1d.spline1dcalc(c2, v)))>(double)(threshold); } } } } } for(m=4; m<=8; m++) { for(pass=1; pass<=passcount; pass++) { // // prepare points/weights // sa = 1+math.randomreal(); sb = 2*math.randomreal()-1; n = 10+math.randominteger(10); x = new double[n]; y = new double[n]; w = new double[n]; for(i=0; i<=n-1; i++) { x[i] = sa*math.randomreal()+sb; y[i] = 2*math.randomreal()-1; w[i] = 1; } // // Fit cubic with unity weights, without weights, then compare // if( m>=4 ) { spline1d.spline1dfitcubicwc(x, y, w, n, xc, yc, dc, 0, m, ref info1, c, rep); spline1d.spline1dfitcubic(x, y, n, m, ref info2, c2, rep2); if( info1<=0 | info2<=0 ) { fiterrors = true; } else { for(i=0; i<=n-1; i++) { v = sa*math.randomreal()+sb; fiterrors = fiterrors | (double)(spline1d.spline1dcalc(c, v))!=(double)(spline1d.spline1dcalc(c2, v)); fiterrors = fiterrors | (double)(rep.taskrcond)!=(double)(rep2.taskrcond); fiterrors = fiterrors | (double)(rep.rmserror)!=(double)(rep2.rmserror); fiterrors = fiterrors | (double)(rep.avgerror)!=(double)(rep2.avgerror); fiterrors = fiterrors | (double)(rep.avgrelerror)!=(double)(rep2.avgrelerror); fiterrors = fiterrors | (double)(rep.maxerror)!=(double)(rep2.maxerror); } } } // // Fit Hermite with unity weights, without weights, then compare // if( m>=4 & m%2==0 ) { spline1d.spline1dfithermitewc(x, y, w, n, xc, yc, dc, 0, m, ref info1, c, rep); spline1d.spline1dfithermite(x, y, n, m, ref info2, c2, rep2); if( info1<=0 | info2<=0 ) { fiterrors = true; } else { for(i=0; i<=n-1; i++) { v = sa*math.randomreal()+sb; fiterrors = fiterrors | (double)(spline1d.spline1dcalc(c, v))!=(double)(spline1d.spline1dcalc(c2, v)); fiterrors = fiterrors | (double)(rep.taskrcond)!=(double)(rep2.taskrcond); fiterrors = fiterrors | (double)(rep.rmserror)!=(double)(rep2.rmserror); fiterrors = fiterrors | (double)(rep.avgerror)!=(double)(rep2.avgerror); fiterrors = fiterrors | (double)(rep.avgrelerror)!=(double)(rep2.avgrelerror); fiterrors = fiterrors | (double)(rep.maxerror)!=(double)(rep2.maxerror); } } } } } for(pass=1; pass<=passcount; pass++) { ap.assert(passcount>=2, "PassCount should be 2 or greater!"); // // solve simple task (all X[] are the same, Y[] are specially // calculated to ensure simple form of all types of errors) // and check correctness of the errors calculated by subroutines // // First pass is done with zero Y[], other passes - with random Y[]. // It should test both ability to correctly calculate errors and // ability to not fail while working with zeros :) // n = 4; if( pass==1 ) { v1 = 0; v2 = 0; v = 0; } else { v1 = math.randomreal(); v2 = math.randomreal(); v = 1+math.randomreal(); } x = new double[4]; y = new double[4]; w = new double[4]; x[0] = 0; y[0] = v-v2; w[0] = 1; x[1] = 0; y[1] = v-v1; w[1] = 1; x[2] = 0; y[2] = v+v1; w[2] = 1; x[3] = 0; y[3] = v+v2; w[3] = 1; refrms = Math.Sqrt((math.sqr(v1)+math.sqr(v2))/2); refavg = (Math.Abs(v1)+Math.Abs(v2))/2; if( pass==1 ) { refavgrel = 0; } else { refavgrel = 0.25*(Math.Abs(v2)/Math.Abs(v-v2)+Math.Abs(v1)/Math.Abs(v-v1)+Math.Abs(v1)/Math.Abs(v+v1)+Math.Abs(v2)/Math.Abs(v+v2)); } refmax = Math.Max(v1, v2); // // Test cubic fitting // spline1d.spline1dfitcubic(x, y, 4, 4, ref info, c, rep); if( info<=0 ) { fiterrors = true; } else { s = spline1d.spline1dcalc(c, 0); fiterrors = fiterrors | (double)(Math.Abs(s-v))>(double)(threshold); fiterrors = fiterrors | (double)(Math.Abs(rep.rmserror-refrms))>(double)(threshold); fiterrors = fiterrors | (double)(Math.Abs(rep.avgerror-refavg))>(double)(threshold); fiterrors = fiterrors | (double)(Math.Abs(rep.avgrelerror-refavgrel))>(double)(threshold); fiterrors = fiterrors | (double)(Math.Abs(rep.maxerror-refmax))>(double)(threshold); } // // Test cubic fitting // spline1d.spline1dfithermite(x, y, 4, 4, ref info, c, rep); if( info<=0 ) { fiterrors = true; } else { s = spline1d.spline1dcalc(c, 0); fiterrors = fiterrors | (double)(Math.Abs(s-v))>(double)(threshold); fiterrors = fiterrors | (double)(Math.Abs(rep.rmserror-refrms))>(double)(threshold); fiterrors = fiterrors | (double)(Math.Abs(rep.avgerror-refavg))>(double)(threshold); fiterrors = fiterrors | (double)(Math.Abs(rep.avgrelerror-refavgrel))>(double)(threshold); fiterrors = fiterrors | (double)(Math.Abs(rep.maxerror-refmax))>(double)(threshold); } } // // report // waserrors = (((((((((lserrors | cserrors) | crserrors) | hserrors) | aserrors) | dserrors) | cperrors) | uperrors) | lterrors) | ierrors) | fiterrors; if( !silent ) { System.Console.Write("TESTING SPLINE INTERPOLATION"); System.Console.WriteLine(); // // Normal tests // System.Console.Write("LINEAR SPLINE TEST: "); if( lserrors ) { System.Console.Write("FAILED"); System.Console.WriteLine(); } else { System.Console.Write("OK"); System.Console.WriteLine(); } System.Console.Write("CUBIC SPLINE TEST: "); if( cserrors ) { System.Console.Write("FAILED"); System.Console.WriteLine(); } else { System.Console.Write("OK"); System.Console.WriteLine(); } System.Console.Write("CATMULL-ROM SPLINE TEST: "); if( crserrors ) { System.Console.Write("FAILED"); System.Console.WriteLine(); } else { System.Console.Write("OK"); System.Console.WriteLine(); } System.Console.Write("HERMITE SPLINE TEST: "); if( hserrors ) { System.Console.Write("FAILED"); System.Console.WriteLine(); } else { System.Console.Write("OK"); System.Console.WriteLine(); } System.Console.Write("AKIMA SPLINE TEST: "); if( aserrors ) { System.Console.Write("FAILED"); System.Console.WriteLine(); } else { System.Console.Write("OK"); System.Console.WriteLine(); } System.Console.Write("DIFFERENTIATION TEST: "); if( dserrors ) { System.Console.Write("FAILED"); System.Console.WriteLine(); } else { System.Console.Write("OK"); System.Console.WriteLine(); } System.Console.Write("COPY/SERIALIZATION TEST: "); if( cperrors ) { System.Console.Write("FAILED"); System.Console.WriteLine(); } else { System.Console.Write("OK"); System.Console.WriteLine(); } System.Console.Write("UNPACK TEST: "); if( uperrors ) { System.Console.Write("FAILED"); System.Console.WriteLine(); } else { System.Console.Write("OK"); System.Console.WriteLine(); } System.Console.Write("LIN.TRANS. TEST: "); if( lterrors ) { System.Console.Write("FAILED"); System.Console.WriteLine(); } else { System.Console.Write("OK"); System.Console.WriteLine(); } System.Console.Write("INTEGRATION TEST: "); if( ierrors ) { System.Console.Write("FAILED"); System.Console.WriteLine(); } else { System.Console.Write("OK"); System.Console.WriteLine(); } System.Console.Write("FITTING TEST: "); if( fiterrors ) { System.Console.Write("FAILED"); System.Console.WriteLine(); } else { System.Console.Write("OK"); System.Console.WriteLine(); } if( waserrors ) { System.Console.Write("TEST FAILED"); System.Console.WriteLine(); } else { System.Console.Write("TEST PASSED"); System.Console.WriteLine(); } System.Console.WriteLine(); System.Console.WriteLine(); } // // end // result = !waserrors; return result; }
public static int Main(string[] args) { double[] x = new double[0]; double[] y = new double[0]; int n = 0; int i = 0; int info = 0; spline1d.spline1dinterpolant s = new spline1d.spline1dinterpolant(); double t = 0; spline1d.spline1dfitreport rep = new spline1d.spline1dfitreport(); // // Fitting by unconstrained natural cubic spline // System.Console.Write("FITTING BY UNCONSTRAINED NATURAL CUBIC SPLINE"); System.Console.WriteLine(); System.Console.WriteLine(); System.Console.Write("F(x)=sin(x) function being fitted"); System.Console.WriteLine(); System.Console.Write("[0, pi] interval"); System.Console.WriteLine(); System.Console.Write("M=4 number of basis functions to use"); System.Console.WriteLine(); System.Console.Write("N=100 number of points to fit"); System.Console.WriteLine(); // // Create and fit // n = 100; x = new double[n]; y = new double[n]; for(i=0; i<=n-1; i++) { x[i] = Math.PI*i/(n-1); y[i] = Math.Sin(x[i]); } spline1d.spline1dfitcubic(ref x, ref y, n, 4, ref info, ref s, ref rep); // // Output results // if( info>0 ) { System.Console.WriteLine(); System.Console.Write("OK, we have finished"); System.Console.WriteLine(); System.Console.WriteLine(); System.Console.Write(" x F(x) S(x) Error"); System.Console.WriteLine(); t = 0; while( (double)(t)<(double)(0.999999*Math.PI) ) { System.Console.Write("{0,6:F3}",t); System.Console.Write(" "); System.Console.Write("{0,6:F3}",Math.Sin(t)); System.Console.Write(" "); System.Console.Write("{0,6:F3}",spline1d.spline1dcalc(ref s, t)); System.Console.Write(" "); System.Console.Write("{0,6:F3}",Math.Abs(spline1d.spline1dcalc(ref s, t)-Math.Sin(t))); System.Console.WriteLine(); t = Math.Min(Math.PI, t+0.25); } System.Console.Write("{0,6:F3}",t); System.Console.Write(" "); System.Console.Write("{0,6:F3}",Math.Sin(t)); System.Console.Write(" "); System.Console.Write("{0,6:F3}",spline1d.spline1dcalc(ref s, t)); System.Console.Write(" "); System.Console.Write("{0,6:F3}",Math.Abs(spline1d.spline1dcalc(ref s, t)-Math.Sin(t))); System.Console.WriteLine(); System.Console.WriteLine(); System.Console.Write("rms error is "); System.Console.Write("{0,6:F3}",rep.rmserror); System.Console.WriteLine(); System.Console.Write("max error is "); System.Console.Write("{0,6:F3}",rep.maxerror); System.Console.WriteLine(); } else { System.Console.WriteLine(); System.Console.Write("Something wrong, Info="); System.Console.Write("{0,0:d}",info); } return 0; }
public spline1dfitreport(spline1d.spline1dfitreport obj) { _innerobj = obj; }
public spline1dfitreport() { _innerobj = new spline1d.spline1dfitreport(); }