/************************************************************************* * This function calculates arc length, i.e. length of curve between t=a * and t=b. * * INPUT PARAMETERS: * P - parametric spline interpolant * A,B - parameter values corresponding to arc ends: * B>A will result in positive length returned * B<A will result in negative length returned * * RESULT: * length of arc starting at T=A and ending at T=B. * * * -- ALGLIB PROJECT -- * Copyright 30.05.2010 by Bochkanov Sergey *************************************************************************/ public static double pspline3arclength(ref pspline3interpolant p, double a, double b) { double result = 0; autogk.autogkstate state = new autogk.autogkstate(); autogk.autogkreport rep = new autogk.autogkreport(); double sx = 0; double dsx = 0; double d2sx = 0; double sy = 0; double dsy = 0; double d2sy = 0; double sz = 0; double dsz = 0; double d2sz = 0; autogk.autogksmooth(a, b, ref state); while (autogk.autogkiteration(ref state)) { spline1d.spline1ddiff(ref p.x, state.x, ref sx, ref dsx, ref d2sx); spline1d.spline1ddiff(ref p.y, state.x, ref sy, ref dsy, ref d2sy); spline1d.spline1ddiff(ref p.z, state.x, ref sz, ref dsz, ref d2sz); state.f = apserv.safepythag3(dsx, dsy, dsz); } autogk.autogkresults(ref state, ref result, ref rep); System.Diagnostics.Debug.Assert(rep.terminationtype > 0, "PSpline3ArcLength: internal error!"); return(result); }
/************************************************************************* Test *************************************************************************/ public static bool testautogkunit(bool silent) { bool result = new bool(); double a = 0; double b = 0; autogk.autogkstate state = new autogk.autogkstate(); autogk.autogkreport rep = new autogk.autogkreport(); double v = 0; double exact = 0; double eabs = 0; double alpha = 0; int pkind = 0; double errtol = 0; bool simpleerrors = new bool(); bool sngenderrors = new bool(); bool waserrors = new bool(); simpleerrors = false; sngenderrors = false; waserrors = false; errtol = 10000*AP.Math.MachineEpsilon; // // Simple test: integral(exp(x),+-1,+-2), no maximum width requirements // a = (2*AP.Math.RandomInteger(2)-1)*1.0; b = (2*AP.Math.RandomInteger(2)-1)*2.0; autogk.autogksmooth(a, b, ref state); while( autogk.autogkiteration(ref state) ) { state.f = Math.Exp(state.x); } autogk.autogkresults(ref state, ref v, ref rep); exact = Math.Exp(b)-Math.Exp(a); eabs = Math.Abs(Math.Exp(b)-Math.Exp(a)); if( rep.terminationtype<=0 ) { simpleerrors = true; } else { simpleerrors = simpleerrors | (double)(Math.Abs(exact-v))>(double)(errtol*eabs); } // // Simple test: integral(exp(x),+-1,+-2), XWidth=0.1 // a = (2*AP.Math.RandomInteger(2)-1)*1.0; b = (2*AP.Math.RandomInteger(2)-1)*2.0; autogk.autogksmoothw(a, b, 0.1, ref state); while( autogk.autogkiteration(ref state) ) { state.f = Math.Exp(state.x); } autogk.autogkresults(ref state, ref v, ref rep); exact = Math.Exp(b)-Math.Exp(a); eabs = Math.Abs(Math.Exp(b)-Math.Exp(a)); if( rep.terminationtype<=0 ) { simpleerrors = true; } else { simpleerrors = simpleerrors | (double)(Math.Abs(exact-v))>(double)(errtol*eabs); } // // Simple test: integral(cos(100*x),0,2*pi), no maximum width requirements // a = 0; b = 2*Math.PI; autogk.autogksmooth(a, b, ref state); while( autogk.autogkiteration(ref state) ) { state.f = Math.Cos(100*state.x); } autogk.autogkresults(ref state, ref v, ref rep); exact = 0; eabs = 4; if( rep.terminationtype<=0 ) { simpleerrors = true; } else { simpleerrors = simpleerrors | (double)(Math.Abs(exact-v))>(double)(errtol*eabs); } // // Simple test: integral(cos(100*x),0,2*pi), XWidth=0.3 // a = 0; b = 2*Math.PI; autogk.autogksmoothw(a, b, 0.3, ref state); while( autogk.autogkiteration(ref state) ) { state.f = Math.Cos(100*state.x); } autogk.autogkresults(ref state, ref v, ref rep); exact = 0; eabs = 4; if( rep.terminationtype<=0 ) { simpleerrors = true; } else { simpleerrors = simpleerrors | (double)(Math.Abs(exact-v))>(double)(errtol*eabs); } // // singular problem on [a,b] = [0.1, 0.5] // f2(x) = (1+x)*(b-x)^alpha, -1 < alpha < 1 // for(pkind=0; pkind<=6; pkind++) { a = 0.1; b = 0.5; if( pkind==0 ) { alpha = -0.9; } if( pkind==1 ) { alpha = -0.5; } if( pkind==2 ) { alpha = -0.1; } if( pkind==3 ) { alpha = 0.0; } if( pkind==4 ) { alpha = 0.1; } if( pkind==5 ) { alpha = 0.5; } if( pkind==6 ) { alpha = 0.9; } // // f1(x) = (1+x)*(x-a)^alpha, -1 < alpha < 1 // 1. use singular integrator for [a,b] // 2. use singular integrator for [b,a] // exact = Math.Pow(b-a, alpha+2)/(alpha+2)+(1+a)*Math.Pow(b-a, alpha+1)/(alpha+1); eabs = Math.Abs(exact); autogk.autogksingular(a, b, alpha, 0.0, ref state); while( autogk.autogkiteration(ref state) ) { if( (double)(state.xminusa)<(double)(0.01) ) { state.f = Math.Pow(state.xminusa, alpha)*(1+state.x); } else { state.f = Math.Pow(state.x-a, alpha)*(1+state.x); } } autogk.autogkresults(ref state, ref v, ref rep); if( rep.terminationtype<=0 ) { sngenderrors = true; } else { sngenderrors = sngenderrors | (double)(Math.Abs(v-exact))>(double)(errtol*eabs); } autogk.autogksingular(b, a, 0.0, alpha, ref state); while( autogk.autogkiteration(ref state) ) { if( (double)(state.bminusx)>(double)(-0.01) ) { state.f = Math.Pow(-state.bminusx, alpha)*(1+state.x); } else { state.f = Math.Pow(state.x-a, alpha)*(1+state.x); } } autogk.autogkresults(ref state, ref v, ref rep); if( rep.terminationtype<=0 ) { sngenderrors = true; } else { sngenderrors = sngenderrors | (double)(Math.Abs(-v-exact))>(double)(errtol*eabs); } // // f1(x) = (1+x)*(b-x)^alpha, -1 < alpha < 1 // 1. use singular integrator for [a,b] // 2. use singular integrator for [b,a] // exact = (1+b)*Math.Pow(b-a, alpha+1)/(alpha+1)-Math.Pow(b-a, alpha+2)/(alpha+2); eabs = Math.Abs(exact); autogk.autogksingular(a, b, 0.0, alpha, ref state); while( autogk.autogkiteration(ref state) ) { if( (double)(state.bminusx)<(double)(0.01) ) { state.f = Math.Pow(state.bminusx, alpha)*(1+state.x); } else { state.f = Math.Pow(b-state.x, alpha)*(1+state.x); } } autogk.autogkresults(ref state, ref v, ref rep); if( rep.terminationtype<=0 ) { sngenderrors = true; } else { sngenderrors = sngenderrors | (double)(Math.Abs(v-exact))>(double)(errtol*eabs); } autogk.autogksingular(b, a, alpha, 0.0, ref state); while( autogk.autogkiteration(ref state) ) { if( (double)(state.xminusa)>(double)(-0.01) ) { state.f = Math.Pow(-state.xminusa, alpha)*(1+state.x); } else { state.f = Math.Pow(b-state.x, alpha)*(1+state.x); } } autogk.autogkresults(ref state, ref v, ref rep); if( rep.terminationtype<=0 ) { sngenderrors = true; } else { sngenderrors = sngenderrors | (double)(Math.Abs(-v-exact))>(double)(errtol*eabs); } } // // end // waserrors = simpleerrors | sngenderrors; if( !silent ) { System.Console.Write("TESTING AUTOGK"); System.Console.WriteLine(); System.Console.Write("INTEGRATION WITH GIVEN ACCURACY: "); if( simpleerrors | sngenderrors ) { System.Console.Write("FAILED"); System.Console.WriteLine(); } else { System.Console.Write("OK"); System.Console.WriteLine(); } System.Console.Write("* SIMPLE PROBLEMS: "); if( simpleerrors ) { System.Console.Write("FAILED"); System.Console.WriteLine(); } else { System.Console.Write("OK"); System.Console.WriteLine(); } System.Console.Write("* SINGULAR PROBLEMS (ENDS OF INTERVAL): "); if( sngenderrors ) { 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(); } result = !waserrors; return result; }
/************************************************************************* * Test *************************************************************************/ public static bool testautogkunit(bool silent) { bool result = new bool(); double a = 0; double b = 0; autogk.autogkstate state = new autogk.autogkstate(); autogk.autogkreport rep = new autogk.autogkreport(); double v = 0; double exact = 0; double eabs = 0; double alpha = 0; int pkind = 0; double errtol = 0; bool simpleerrors = new bool(); bool sngenderrors = new bool(); bool waserrors = new bool(); simpleerrors = false; sngenderrors = false; waserrors = false; errtol = 10000 * AP.Math.MachineEpsilon; // // Simple test: integral(exp(x),+-1,+-2), no maximum width requirements // a = (2 * AP.Math.RandomInteger(2) - 1) * 1.0; b = (2 * AP.Math.RandomInteger(2) - 1) * 2.0; autogk.autogksmooth(a, b, ref state); while (autogk.autogkiteration(ref state)) { state.f = Math.Exp(state.x); } autogk.autogkresults(ref state, ref v, ref rep); exact = Math.Exp(b) - Math.Exp(a); eabs = Math.Abs(Math.Exp(b) - Math.Exp(a)); if (rep.terminationtype <= 0) { simpleerrors = true; } else { simpleerrors = simpleerrors | (double)(Math.Abs(exact - v)) > (double)(errtol * eabs); } // // Simple test: integral(exp(x),+-1,+-2), XWidth=0.1 // a = (2 * AP.Math.RandomInteger(2) - 1) * 1.0; b = (2 * AP.Math.RandomInteger(2) - 1) * 2.0; autogk.autogksmoothw(a, b, 0.1, ref state); while (autogk.autogkiteration(ref state)) { state.f = Math.Exp(state.x); } autogk.autogkresults(ref state, ref v, ref rep); exact = Math.Exp(b) - Math.Exp(a); eabs = Math.Abs(Math.Exp(b) - Math.Exp(a)); if (rep.terminationtype <= 0) { simpleerrors = true; } else { simpleerrors = simpleerrors | (double)(Math.Abs(exact - v)) > (double)(errtol * eabs); } // // Simple test: integral(cos(100*x),0,2*pi), no maximum width requirements // a = 0; b = 2 * Math.PI; autogk.autogksmooth(a, b, ref state); while (autogk.autogkiteration(ref state)) { state.f = Math.Cos(100 * state.x); } autogk.autogkresults(ref state, ref v, ref rep); exact = 0; eabs = 4; if (rep.terminationtype <= 0) { simpleerrors = true; } else { simpleerrors = simpleerrors | (double)(Math.Abs(exact - v)) > (double)(errtol * eabs); } // // Simple test: integral(cos(100*x),0,2*pi), XWidth=0.3 // a = 0; b = 2 * Math.PI; autogk.autogksmoothw(a, b, 0.3, ref state); while (autogk.autogkiteration(ref state)) { state.f = Math.Cos(100 * state.x); } autogk.autogkresults(ref state, ref v, ref rep); exact = 0; eabs = 4; if (rep.terminationtype <= 0) { simpleerrors = true; } else { simpleerrors = simpleerrors | (double)(Math.Abs(exact - v)) > (double)(errtol * eabs); } // // singular problem on [a,b] = [0.1, 0.5] // f2(x) = (1+x)*(b-x)^alpha, -1 < alpha < 1 // for (pkind = 0; pkind <= 6; pkind++) { a = 0.1; b = 0.5; if (pkind == 0) { alpha = -0.9; } if (pkind == 1) { alpha = -0.5; } if (pkind == 2) { alpha = -0.1; } if (pkind == 3) { alpha = 0.0; } if (pkind == 4) { alpha = 0.1; } if (pkind == 5) { alpha = 0.5; } if (pkind == 6) { alpha = 0.9; } // // f1(x) = (1+x)*(x-a)^alpha, -1 < alpha < 1 // 1. use singular integrator for [a,b] // 2. use singular integrator for [b,a] // exact = Math.Pow(b - a, alpha + 2) / (alpha + 2) + (1 + a) * Math.Pow(b - a, alpha + 1) / (alpha + 1); eabs = Math.Abs(exact); autogk.autogksingular(a, b, alpha, 0.0, ref state); while (autogk.autogkiteration(ref state)) { if ((double)(state.xminusa) < (double)(0.01)) { state.f = Math.Pow(state.xminusa, alpha) * (1 + state.x); } else { state.f = Math.Pow(state.x - a, alpha) * (1 + state.x); } } autogk.autogkresults(ref state, ref v, ref rep); if (rep.terminationtype <= 0) { sngenderrors = true; } else { sngenderrors = sngenderrors | (double)(Math.Abs(v - exact)) > (double)(errtol * eabs); } autogk.autogksingular(b, a, 0.0, alpha, ref state); while (autogk.autogkiteration(ref state)) { if ((double)(state.bminusx) > (double)(-0.01)) { state.f = Math.Pow(-state.bminusx, alpha) * (1 + state.x); } else { state.f = Math.Pow(state.x - a, alpha) * (1 + state.x); } } autogk.autogkresults(ref state, ref v, ref rep); if (rep.terminationtype <= 0) { sngenderrors = true; } else { sngenderrors = sngenderrors | (double)(Math.Abs(-v - exact)) > (double)(errtol * eabs); } // // f1(x) = (1+x)*(b-x)^alpha, -1 < alpha < 1 // 1. use singular integrator for [a,b] // 2. use singular integrator for [b,a] // exact = (1 + b) * Math.Pow(b - a, alpha + 1) / (alpha + 1) - Math.Pow(b - a, alpha + 2) / (alpha + 2); eabs = Math.Abs(exact); autogk.autogksingular(a, b, 0.0, alpha, ref state); while (autogk.autogkiteration(ref state)) { if ((double)(state.bminusx) < (double)(0.01)) { state.f = Math.Pow(state.bminusx, alpha) * (1 + state.x); } else { state.f = Math.Pow(b - state.x, alpha) * (1 + state.x); } } autogk.autogkresults(ref state, ref v, ref rep); if (rep.terminationtype <= 0) { sngenderrors = true; } else { sngenderrors = sngenderrors | (double)(Math.Abs(v - exact)) > (double)(errtol * eabs); } autogk.autogksingular(b, a, alpha, 0.0, ref state); while (autogk.autogkiteration(ref state)) { if ((double)(state.xminusa) > (double)(-0.01)) { state.f = Math.Pow(-state.xminusa, alpha) * (1 + state.x); } else { state.f = Math.Pow(b - state.x, alpha) * (1 + state.x); } } autogk.autogkresults(ref state, ref v, ref rep); if (rep.terminationtype <= 0) { sngenderrors = true; } else { sngenderrors = sngenderrors | (double)(Math.Abs(-v - exact)) > (double)(errtol * eabs); } } // // end // waserrors = simpleerrors | sngenderrors; if (!silent) { System.Console.Write("TESTING AUTOGK"); System.Console.WriteLine(); System.Console.Write("INTEGRATION WITH GIVEN ACCURACY: "); if (simpleerrors | sngenderrors) { System.Console.Write("FAILED"); System.Console.WriteLine(); } else { System.Console.Write("OK"); System.Console.WriteLine(); } System.Console.Write("* SIMPLE PROBLEMS: "); if (simpleerrors) { System.Console.Write("FAILED"); System.Console.WriteLine(); } else { System.Console.Write("OK"); System.Console.WriteLine(); } System.Console.Write("* SINGULAR PROBLEMS (ENDS OF INTERVAL): "); if (sngenderrors) { 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(); } result = !waserrors; return(result); }
/************************************************************************* This function calculates arc length, i.e. length of curve between t=a and t=b. INPUT PARAMETERS: P - parametric spline interpolant A,B - parameter values corresponding to arc ends: * B>A will result in positive length returned * B<A will result in negative length returned RESULT: length of arc starting at T=A and ending at T=B. -- ALGLIB PROJECT -- Copyright 30.05.2010 by Bochkanov Sergey *************************************************************************/ public static double pspline3arclength(ref pspline3interpolant p, double a, double b) { double result = 0; autogk.autogkstate state = new autogk.autogkstate(); autogk.autogkreport rep = new autogk.autogkreport(); double sx = 0; double dsx = 0; double d2sx = 0; double sy = 0; double dsy = 0; double d2sy = 0; double sz = 0; double dsz = 0; double d2sz = 0; autogk.autogksmooth(a, b, ref state); while( autogk.autogkiteration(ref state) ) { spline1d.spline1ddiff(ref p.x, state.x, ref sx, ref dsx, ref d2sx); spline1d.spline1ddiff(ref p.y, state.x, ref sy, ref dsy, ref d2sy); spline1d.spline1ddiff(ref p.z, state.x, ref sz, ref dsz, ref d2sz); state.f = apserv.safepythag3(dsx, dsy, dsz); } autogk.autogkresults(ref state, ref result, ref rep); System.Diagnostics.Debug.Assert(rep.terminationtype>0, "PSpline3ArcLength: internal error!"); return result; }