public barycentricfitreport(lsfit.barycentricfitreport obj) { _innerobj = obj; }
private static void testrationalfitting(ref bool fiterrors) { double threshold = 0; int maxn = 0; int passcount = 0; ratint.barycentricinterpolant b1 = new ratint.barycentricinterpolant(); ratint.barycentricinterpolant b2 = new ratint.barycentricinterpolant(); double[] x = new double[0]; double[] x2 = new double[0]; double[] y = new double[0]; double[] y2 = new double[0]; double[] w = new double[0]; double[] w2 = new double[0]; double[] xc = new double[0]; double[] yc = new double[0]; int[] dc = new int[0]; int n = 0; int m = 0; int i = 0; int k = 0; int pass = 0; double t = 0; double s = 0; double v = 0; double v0 = 0; double v1 = 0; double v2 = 0; int info = 0; int info2 = 0; double xmin = 0; double xmax = 0; double refrms = 0; double refavg = 0; double refavgrel = 0; double refmax = 0; lsfit.barycentricfitreport rep = new lsfit.barycentricfitreport(); lsfit.barycentricfitreport rep2 = new lsfit.barycentricfitreport(); fiterrors = false; // // PassCount number of repeated passes // Threshold error tolerance // LipschitzTol Lipschitz constant increase allowed // when calculating constant on a twice denser grid // passcount = 5; maxn = 15; threshold = 1000000*math.machineepsilon; // // Test rational fitting: // for(pass=1; pass<=passcount; pass++) { for(n=2; n<=maxn; n++) { // // N=M+K fitting (i.e. interpolation) // for(k=0; k<=n-1; k++) { x = new double[n-k]; y = new double[n-k]; w = new double[n-k]; if( k>0 ) { xc = new double[k]; yc = new double[k]; dc = new int[k]; } for(i=0; i<=n-k-1; i++) { x[i] = (double)i/(double)(n-1); y[i] = 2*math.randomreal()-1; w[i] = 1+math.randomreal(); } for(i=0; i<=k-1; i++) { xc[i] = (double)(n-k+i)/(double)(n-1); yc[i] = 2*math.randomreal()-1; dc[i] = 0; } lsfit.barycentricfitfloaterhormannwc(x, y, w, n-k, xc, yc, dc, k, n, ref info, b1, rep); if( info<=0 ) { fiterrors = true; } else { for(i=0; i<=n-k-1; i++) { fiterrors = fiterrors | (double)(Math.Abs(ratint.barycentriccalc(b1, x[i])-y[i]))>(double)(threshold); } for(i=0; i<=k-1; i++) { fiterrors = fiterrors | (double)(Math.Abs(ratint.barycentriccalc(b1, xc[i])-yc[i]))>(double)(threshold); } } } // // Testing constraints on derivatives: // * several M's are tried // * several K's are tried - 1, 2. // * constraints at the ends of the interval // for(m=3; m<=5; m++) { for(k=1; k<=2; k++) { x = new double[n]; y = new double[n]; w = new double[n]; xc = new double[2]; yc = new double[2]; dc = new int[2]; for(i=0; i<=n-1; i++) { x[i] = 2*math.randomreal()-1; y[i] = 2*math.randomreal()-1; w[i] = 1+math.randomreal(); } xc[0] = -1; yc[0] = 2*math.randomreal()-1; dc[0] = 0; xc[1] = 1; yc[1] = 2*math.randomreal()-1; dc[1] = 0; lsfit.barycentricfitfloaterhormannwc(x, y, w, n, xc, yc, dc, k, m, ref info, b1, rep); if( info<=0 ) { fiterrors = true; } else { for(i=0; i<=k-1; i++) { ratint.barycentricdiff1(b1, xc[i], ref v0, ref v1); fiterrors = fiterrors | (double)(Math.Abs(v0-yc[i]))>(double)(threshold); } } } } } } for(m=2; m<=8; m++) { for(pass=1; pass<=passcount; pass++) { // // General fitting // // interpolating function through M nodes should have // greater RMS error than fitting it through the same M nodes // n = 100; x2 = new double[n]; y2 = new double[n]; w2 = new double[n]; xmin = math.maxrealnumber; xmax = -math.maxrealnumber; for(i=0; i<=n-1; i++) { x2[i] = 2*Math.PI*math.randomreal(); y2[i] = Math.Sin(x2[i]); w2[i] = 1; xmin = Math.Min(xmin, x2[i]); xmax = Math.Max(xmax, x2[i]); } x = new double[m]; y = new double[m]; for(i=0; i<=m-1; i++) { x[i] = xmin+(xmax-xmin)*i/(m-1); y[i] = Math.Sin(x[i]); } ratint.barycentricbuildfloaterhormann(x, y, m, 3, b1); lsfit.barycentricfitfloaterhormannwc(x2, y2, w2, n, xc, yc, dc, 0, m, ref info, b2, rep); if( info<=0 ) { fiterrors = true; } else { // // calculate B1 (interpolant) RMS error, compare with B2 error // v1 = 0; v2 = 0; for(i=0; i<=n-1; i++) { v1 = v1+math.sqr(ratint.barycentriccalc(b1, x2[i])-y2[i]); v2 = v2+math.sqr(ratint.barycentriccalc(b2, x2[i])-y2[i]); } v1 = Math.Sqrt(v1/n); v2 = Math.Sqrt(v2/n); fiterrors = fiterrors | (double)(v2)>(double)(v1); fiterrors = fiterrors | (double)(Math.Abs(v2-rep.rmserror))>(double)(threshold); } // // compare weighted and non-weighted // n = 20; x = new double[n]; y = new double[n]; w = new double[n]; for(i=0; i<=n-1; i++) { x[i] = 2*math.randomreal()-1; y[i] = 2*math.randomreal()-1; w[i] = 1; } lsfit.barycentricfitfloaterhormannwc(x, y, w, n, xc, yc, dc, 0, m, ref info, b1, rep); lsfit.barycentricfitfloaterhormann(x, y, n, m, ref info2, b2, rep2); if( info<=0 | info2<=0 ) { fiterrors = true; } else { // // calculate B1 (interpolant), compare with B2 // compare RMS errors // t = 2*math.randomreal()-1; v1 = ratint.barycentriccalc(b1, t); v2 = ratint.barycentriccalc(b2, t); fiterrors = fiterrors | (double)(v2)!=(double)(v1); 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 errors correctness // lsfit.barycentricfitfloaterhormann(x, y, 4, 2, ref info, b1, rep); if( info<=0 ) { fiterrors = true; } else { s = ratint.barycentriccalc(b1, 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); } } }
public barycentricfitreport() { _innerobj = new lsfit.barycentricfitreport(); }