Ejemplo n.º 1
0
double tangent_h(double x, double h, double& y, double yguess)
{
    y = find_y_at_h(x, h,yguess);
    double dx = dfx(x,y);
    double dy = dfx(y,x);
    assert(dy != 0);
    return -dx/dy;
}
Ejemplo n.º 2
0
double find_y_at_h(double x, double h, double yguess)
{
    double y = yguess;
    assert(0.000001*(x*x+y*y)-0.0015*(x+y)+0.7 > 0);
    double fy = f(x, yguess);
    while(fabs(fy-h)>tol){
        double slope = dfx(yguess, x); 
        double deltay = (fy-h) /slope;
        if(fabs(deltay) > 50)
            deltay= deltay >0?50:-50;
        yguess -= deltay;
        fy = f(x, yguess);
    }
    return yguess;
}
Ejemplo n.º 3
0
static VALUE method_newton(VALUE self, VALUE pmts, VALUE exps,
                           VALUE guess, VALUE tolerance, VALUE max_iter) {
    long len = RARRAY_LEN(pmts);
    long max_i = NUM2INT(max_iter);
    long double x0 = NUM2DBL(guess);
    long double x1 = 0.0;
    long double tol = NUM2DBL(tolerance);
    long double err = 1e100;
    VALUE *pmt_p = RARRAY_PTR(pmts);
    VALUE *exp_p = RARRAY_PTR(exps);
    long iter = 0;

    while (err > tol && iter++ < max_i) {
        x1 = x0 - (fx(x0, pmt_p, exp_p, len) / dfx(x0, pmt_p, exp_p, len));
        err = fabs(x1 - x0);
        x0 =  MAX(x1, lower_bound);
    }

    return (err > tol) ? Qnil : rb_float_new(x0);
}
Ejemplo n.º 4
0
//assumption only one maximum, giving two ends, find max
void binary_search(double x1, double y1, double x2, double y2, double& retx, double& rety)
{
    double dydx=(y2-y1)/(x2-x1);
    double df1 = dfx(x1,y1) + dydx * dfx(y1,x1);
    double df2 = dfx(x2, y2)+ dydx * dfx(y2, x2);
    assert(df1 * df2 < 0);
    double xmid = 0, ymid=0;
    while(fabs(x2-x1)> 1e-12){
        xmid = (x1+x2)/2.0;
        ymid = (y1+y2)/2.0;
        double df3 = dfx(xmid, ymid)+dydx*dfx(ymid,xmid);
        if(df3 * df1 > 0){
            x1 = xmid;
            y1 = ymid;
        }else{
            x2 = xmid;
            y2 = ymid;
        }
    }
    retx = (x1+x2)/2;
    rety = (y1+y2)/2;
}
Ejemplo n.º 5
0
int main()
{
   /*   
   {
       double xstart = 1400, ystart = 1400;
       double xfinal = 1561.907083805850789, yfinal = 672.892772938465328;
       int nseg = 1000;
       double retx, rety;
       double dx = (xfinal- xstart)/nseg;
       double dy = (yfinal- ystart)/nseg;
       for(int i = 0; i <= nseg; ++i){
           //binary_search(1400, 1400, 1600, ystart+i*dy, retx, rety);
           printf("%d %30.15f\n", i, f(xstart+dx*i, ystart+i*dy));
       }
       binary_search(xstart, ystart, xfinal, yfinal, retx, rety);
       printf("%30.15f\n", f(retx, rety));
       exit(1);
   }
   */ 
   double PI = 4.0*atan(1.0);
   double ret1, ret2;
   double radius = sqrt(17.0/40)*1000;
   //first find the fmin, minimum height
   binary_search(0,0, 1600, 0, ret1, ret2 );
   double barrierx = ret1;
   double maxh = f(ret1, 0);
   printf("%30.15f, %30.15f %30.15f\n", ret1, f(ret1, 0), dfx(ret1, 0));
   //second, find the path to the barrier
   //double y200 = 0;
   //double x200 = find_tangent(maxh, 300, barrierx, -100,y200 );
   double x200, y200, x1400, y1400, tp;
   find_barrier_200(barrierx, maxh, x200, y200);
   printf("data 200| %30.15f %30.15f %30.15f\n", x200, y200, f(x200, y200)-maxh);
   printf("part2 %30.15f %30.15f %30.15f\n", f(x200, y200)-maxh, tangent_h(x200, maxh, tp, y200), (y200-200)/(x200-200) );
   find_barrier_1400(700, maxh, x1400,y1400);
   // x1400 = find_barrier_eq_h(1410, 1600, maxh, ret1);
   // y1400 = find_y_at_h(x1400, maxh, 1600);
   printf("data 1400 %30.15f %30.15f %30.15f\n", x1400, y1400, f(x1400, y1400)-maxh);
   printf("part 2 %30.15f %30.15f %30.15f\n", f(x1400, y1400)-maxh, tangent_h(x1400, maxh,tp, y1400), (y1400-1400)/(x1400-1400) );
   int nseg = 1000000;
   double y0 = y200;
   double total = sqrt((x200-200)*(x200-200)+(y200-200)*(y200-200));
   total += sqrt((x1400-1400)*(x1400-1400)+(y1400-1400)*(y1400-1400));
   //{
   //    double xstart = 1600, ystart = 900;
   //    double xfinal = 1400, yfinal = 1400;
   //    int nseg = 1000;
   //    double dx = (xfinal- xstart)/nseg;
   //    double dy = (yfinal- ystart)/nseg;
   //    for(int i = 0; i <= nseg; ++i){
   //        printf("%d %30.15f\n", i, f(xstart+i*dx, ystart+i*dy));
   //    }
   //    exit(1);
   //}
   //total += sqrt((x200-barrierx)*(x200-barrierx)+y200*y200);
   double dx = (1561.907083805850789 -x200)/nseg;
   for(unsigned int i=1; i<=nseg;++i){
       double y1 = find_y_at_h(x200+i*dx, maxh, y0);
       //printf("%30.15f %30.15f %30.15f\n", x200+i*dx, y1, f(x200+i*dx, y1));
       double ds = dx*dx+ (y1-y0)*(y1-y0);
       ds= sqrt(ds);
       total += ds;
       y0= y1;
   }
   //printf("------------------");
   nseg = 1000000;
   double x4 = 1561.907083805850789;
   dx = (x4 - x1400)/nseg;  
   y0 = find_y_at_h(x1400, maxh, y1400);

   for(unsigned int i=1; i<= nseg;++i){
       double y1 = find_y_at_h(x1400+i*dx, maxh, y0);
       //printf("%30.15f %30.15f %30.15f\n", x4+i*dx, y1, f(x4+i*dx, y1));
       double ds = dx*dx+ (y1-y0)*(y1-y0);
       ds= sqrt(ds);
       total += ds;
       y0= y1;
   }
   printf("%30.15f\n", total);
}