int main() { double xl = -100.0, xr = 100.0, t = 0.0000001; puts("\nTest 1: x^3 = 0."); printf("xl = %f; xr = %f; tolerance = %f\n", -100.0, 150.0, t); printf("Bisection: x = %f\n", bisection(-100.0, 150.0, t, &cube)); printf("xl = %f; xr = %f; tolerance = %f\n", -0.001, 0.001, t); printf("Secant: x = %f\n", secant(-0.001, 0.001, t, &cube)); puts("\nTest 2: Matrix test (x^j = 10^i)."); for(j = 1; j < 10; j++) for(i = 1; i < 10; i++) { printf("j = %f; i = %f\n", j, i); printf("Bisection: x = %f\n", bisection(xl, xr, t, &poly)); printf("Secant: x = %f\n", secant(xl, xr, t, &poly)); } }
void findgraph (long double a, long double b, long double i, long double error, long double p, long double (*f) (long double, long double), char *name) { long double previous = f (a, p); long double current = f (a, p); unsigned long count = 0; printf ("Starting scan of %s on interval %Lf to %Lf with increment of %Lf\n\n", name, a, b, i); for (; a < b; a += i) { current = f (a, p); if (matchSign (previous, current)) { } else { printf (" Found sign change from %Lf to %Lf\n\n", a - i, a); bisect (a - i, a, error, p, f, name); secant (a - i, a, error, p, f, name); falseposition (a - i, a, error, p, f, name); } previous = current; count++; } printf ("Done scanning %s after %lu iterations\n\n", name, count); }
double root(double fitvalue) { double step = 1.1; double e = 1.0e-12; double x = 0.1; // just so we use secant method double xx, value; int s = (f(x)> 0.0); if (debug>3) printf("# gcore= %g gtail= %g factorcore= %g factortail= %g\n",gcore_g,gtail_g,factorcore_g,factortail_g); value_g=fitvalue; while (x < 1e9) { value = f(x); if (debug>3) printf("%g %g %g\n",x,value,ickingfunk(x)); if (fabs(value) < e) { if (debug >3) printf("Root found at x= %12.9f\n", x); return x; } else if ((value > 0.0) != s) { xx = secant(x/step, x,&f); if (xx != -99.0) // -99 meaning secant method failed return xx; else return xx; } x *= step; } return x; }
double secant(double x_1, double x_2, double (*func)(double)){ double f_x_1 = (*func)(x_1); double f_x_2 = (*func)(x_2); double x_3 = x_2 - f_x_2*((x_2-x_1)/(f_x_2- f_x_1)); printf("%.3f\n", x_3); if(fabs((*func)(x_3) - (double) 0.0) < (1/pow(10.0,12))){return x_3;} secant(x_3,x_2,(*func)); return 9.0; }
double secant(double x_low, double x_high, double x_accuracy, double f_x_low, double f_x_high, double f_accuracy, const T & function, int limit_depth = 500){ theta_assert(std::isfinite(x_low) && std::isfinite(x_high)); theta_assert(x_low <= x_high); theta_assert(std::isfinite(f_x_low) && std::isfinite(f_x_high)); theta_assert(limit_depth > 0); if(f_x_low * f_x_high >= 0) throw std::invalid_argument("secant: function values have the same sign!"); if(std::fabs(f_x_low) <= f_accuracy) return x_low; if(std::fabs(f_x_high) <= f_accuracy) return x_high; const double old_interval_length = x_high - x_low; //calculate intersection point for secant method: double x_intersect = x_low - (x_high - x_low) / (f_x_high - f_x_low) * f_x_low; theta_assert(x_intersect >= x_low); theta_assert(x_intersect <= x_high); if(old_interval_length < x_accuracy){ return x_intersect; } double f_x_intersect = function(x_intersect); double f_mult = f_x_low * f_x_intersect; //fall back to bisection if the new interval would not be much smaller: double new_interval_length = f_mult < 0 ? x_intersect - x_low : x_high - x_intersect; if(new_interval_length > 0.5 * old_interval_length){ x_intersect = 0.5*(x_low + x_high); f_x_intersect = function(x_intersect); f_mult = f_x_low * f_x_intersect; } if(f_mult < 0){ return secant(x_low, x_intersect, x_accuracy, f_x_low, f_x_intersect, f_accuracy, function, limit_depth - 1); } else if(f_mult > 0.0){ return secant(x_intersect, x_high, x_accuracy, f_x_intersect, f_x_high, f_accuracy, function, limit_depth - 1); } //it can actually happen that we have 0.0. In this case, return the x value for // the smallest absolute function value: else{ f_x_intersect = fabs(f_x_intersect); f_x_low = fabs(f_x_low); f_x_high = fabs(f_x_high); if(f_x_low < f_x_high && f_x_low < f_x_intersect) return x_low; if(f_x_high < f_x_intersect) return x_high; return x_intersect; } }
int main() { double p,q,r,s,t,u; while(scanf("%lf %lf %lf %lf %lf %lf", &p, &q, &r, &s, &t, &u) == 6){ secant(p,q,r,s,t,u); } return 0; }
int main(void) { double *x; x = dmallocv(2); x[0] = 3; x[1] = 2; secant(x, 1.e-15, 20); printf("Secant %lf\n", x[0] ); return 0; }
int main () { //findgraph ( 2, 3, .1, .0001, 5, &fsqrt, "Find square Root of 5"); //findgraph (10,500, 5, .0000001, 5487, &fsqrt, "Find square Root of 5487"); findgraph ( 0, 1, .1, .0001, 0, &hw2p1, "hw2p1"); findgraph ( 1, 3.2, .1, .0001, 0, &hw2p2, "hw2p2"); findgraph ( 1, 2, .1, .0001, 0, &hw2p3, "hw2p3"); findgraph (-1, 0, .01, .001, 0, &hw2p4, "hw2p4"); secant (-1, 0, .001, 0, &hw2p4, "hw2p4"); falseposition (-1, 0, .001, 0, &hw2p4, "hw2p4"); findgraph (-1, 0, .01, .00001, 0, &hw2p5, "hw2p5 from -1 to 0"); findgraph ( 0, 1, .01, .00001, 0, &hw2p5, "hw2p5 from 0 to 1"); findgraph (-1 , 1, .1, .00001, 0, &hw2p5, "hw2p5 from 0 to 1"); findpoint (0, 2, 0, 1, .001, 8, &hw2p6, "hw2p6"); // testing the point function //findpoint (0, 2, 1, 1, .001, 8, &hw2p6, "hw2p6"); //findpoint (1, 3, 2, 4, .001, 8, &hw2p6, "hw2p6"); //findpoint (1, 4, 0, 2, .001, 8, &hw2p6, "hw2p6"); //findpoint (1, 8, 18, 0, .001, 8, &hw2p6, "hw2p6"); findgraph (0, 1, .1, .01, 12.4, &hw2p7a, "hw2p7 trough with 12.4 volume"); ///* printf ("finding a range of values for testing.\n"); long double i; for (i=0; i< 1; i=i+.1){ char name[40]; sprintf(name, "hw2p7 %Lf", i); //findgraph (0, 1, .01, .00001, i, &hw2p7, name); hw2p7(i, 0); hw2p7a(i, 0); } //*/ //findgraph (-1, 3, .1, .001, 38, &hw2ptri, "hw2ptri full"); //findgraph (-1, 3, .1, .001, 10, &hw2ptri, "hw2ptri half full"); //findgraph (-1, 3, .1, .001, .1, &hw2ptri, "hw2ptri empty"); //findgraph ( 0, 2, .1, .00000001, 0, &fex, "fex"); }
void testRoot(){ printf("\nRoot finding and minimisation\n"); golden(functionTest3,0,2); golden(functionTest1,3,7); golden(functionTest2,5,7); golden(poly,-0.5,1.0); brute (poly,-1.0,1.0, 0.0001); brute (functionTest1,3,7, 0.0001); secant(poly,0.0,1.0); newton(poly, dpoly, 0.0); regulaFalsi(poly,-1.0,1.0); bisect(poly,-1.0,1.0); fixedPointIteration(cosine,1.0); squareRoot(20); }
int main(int argc, char **argv){ double x0 = 1; double exact = sqrt(5); const unsigned N = 16; double X_search[N], X_NR[N], X_secant[N]; search(&test_function, X_search, x0, 1.0, N); Newton_Rhapson(&test_function, &test_function_deriv, X_NR, x0, N); secant(&test_function, X_secant, x0, N); printf("#iteration search Newton_Rhapson secant"); for(unsigned n = 0;n < N; n++){ printf("\n%u %e %e %e", n, fabs(exact-X_search[n]), fabs(exact-X_NR[n]), fabs(exact-X_secant[n]) ); } return 0; }
int sweep_secant(double (*func)(double x),double xstart,double xstop,double xinc,int nmax,double tol) { double a,b,fa,fb; int retval; xstop = xstop + (xinc * 0.5); a = xstart; fa = (*func)(a); b = a + xinc; while (((xinc > 0.0) && (b < xstop)) || ((xinc < 0.0) && (b > xstop))) { fb = (*func)(b); if ((fa * fb) < 0.0) { /*root bracketed, converge with secant*/ retval = secant(func,a,b,nmax,tol); if (retval > 0) return(retval); } a = b; fa = fb; b = b + xinc; } return(0); }
void Bernsteins::find_bernstein_roots(Bezier bz, unsigned depth, double left_t, double right_t) { debug(std::cout << left_t << ", " << right_t << std::endl); size_t n_crossings = 0; int old_sign = SGN(bz[0]); //std::cout << "w[0] = " << bz[0] << std::endl; int sign; for (size_t i = 1; i < bz.size(); i++) { //std::cout << "w[" << i << "] = " << w[i] << std::endl; sign = SGN(bz[i]); if (sign != 0) { if (sign != old_sign && old_sign != 0) { ++n_crossings; } old_sign = sign; } } //std::cout << "n_crossings = " << n_crossings << std::endl; if (n_crossings == 0) return; // no solutions here if (n_crossings == 1) /* Unique solution */ { //std::cout << "depth = " << depth << std::endl; /* Stop recursion when the tree is deep enough */ /* if deep enough, return 1 solution at midpoint */ if (depth > MAX_DEPTH) { //printf("bottom out %d\n", depth); const double Ax = right_t - left_t; const double Ay = bz.at1() - bz.at0(); solutions.push_back(left_t - Ax*bz.at0() / Ay); return; } double r = secant(bz); solutions.push_back(r*right_t + (1-r)*left_t); return; } /* Otherwise, solve recursively after subdividing control polygon */ Bezier::Order o(bz); Bezier Left(o), Right = bz; double split_t = (left_t + right_t) * 0.5; // If subdivision is working poorly, split around the leftmost root of the derivative if (depth > 2) { debug(std::cout << "derivative mode\n"); Bezier dbz = derivative(bz); debug(std::cout << "initial = " << dbz << std::endl); std::vector<double> dsolutions = dbz.roots(Interval(left_t, right_t)); debug(std::cout << "dsolutions = " << dsolutions << std::endl); double dsplit_t = 0.5; if(!dsolutions.empty()) { dsplit_t = dsolutions[0]; split_t = left_t + (right_t - left_t)*dsplit_t; debug(std::cout << "split_value = " << bz(split_t) << std::endl); debug(std::cout << "spliting around " << dsplit_t << " = " << split_t << "\n"); } std::pair<Bezier, Bezier> LR = bz.subdivide(dsplit_t); Left = LR.first; Right = LR.second; } else { // split at midpoint, because it is cheap Left[0] = Right[0]; for (size_t i = 1; i < bz.size(); ++i) { for (size_t j = 0; j < bz.size()-i; ++j) { Right[j] = (Right[j] + Right[j+1]) * 0.5; } Left[i] = Right[0]; } } debug(std::cout << "Solution is exactly on the subdivision point.\n"); debug(std::cout << Left << " , " << Right << std::endl); Left = reverse(Left); while(Right.order() > 0 and fabs(Right[0]) <= 1e-10) { debug(std::cout << "deflate\n"); Right = Right.deflate(); Left = Left.deflate(); solutions.push_back(split_t); } Left = reverse(Left); if (Right.order() > 0) { debug(std::cout << Left << " , " << Right << std::endl); find_bernstein_roots(Left, depth+1, left_t, split_t); find_bernstein_roots(Right, depth+1, split_t, right_t); } }
double secant (double xold, double xnew, double tolerance, double func()) { double fxold = (*func)(xold), fxnew = (*func)(xnew); if (fabs(fxnew) <= tolerance) return xnew; return secant(xnew, xnew + fxnew * (xold - xnew) / (fxold - fxnew), tolerance, func); }