Exemplo n.º 1
0
void pp_get_corrected_vals(char *sarName, double *corrected_earth_radius,
                           double *corrected_azimuth_time_per_pixel)
{
    int status;
    int iter = 0, max_iter = 100;
    const gsl_root_fsolver_type *T;
    gsl_root_fsolver *s;
    gsl_function F;
    gsl_error_handler_t *prev;
    struct pp_erfin_params params;

    double nominal_pixsize_azimuth;
    double nadir_radius; /* earth radius at nadir */
    double pp_earth_radius; /* f'd up PP Earth radius from start of swath */
    double seconds_per_azimuth_line; /* PP's real azimuth resolution */
    double lo, hi;  /* starting points for the bisection algorithm */
    struct VFDRECV facdr;

    get_asf_facdr(sarName, &facdr);

    /* Find the PP's earth radius with an iterative search */
    F.function = &getObjective;
    F.params = &params;

    params.npixels=facdr.npixels;
    params.nlines=facdr.nlines;
    params.nominal_pixsize_range=facdr.rapixspc;
    nominal_pixsize_azimuth=facdr.azpixspc;
    nadir_radius=1.0e3*facdr.eradnadr;
    params.satellite_height=1.0e3*(facdr.scalt+facdr.eradnadr);
    params.slant_first=1.0e3*facdr.sltrngfp;
    params.slant_last=1.0e3*facdr.sltrnglp;

    prev = gsl_set_error_handler_off();

    lo = nadir_radius - 2000;
    hi = nadir_radius + 2000;

    T = gsl_root_fsolver_brent;
    s = gsl_root_fsolver_alloc (T);
    gsl_root_fsolver_set (s, &F, lo, hi);

    do {
        ++iter;
        status = gsl_root_fsolver_iterate(s);
        pp_earth_radius = gsl_root_fsolver_root(s);
        status = gsl_root_test_residual(
            getObjective(pp_earth_radius, (void*)&params), 1.0e-4);
    } while (status == GSL_CONTINUE && iter < max_iter);

    if (status == GSL_SUCCESS) {
        //printf("Converged after %d iterations.\n", iter);
        //printf("PP Earth Radius: %.3f m\n",pp_earth_radius);
        //printf("   (for comparison) Nadir Earth Radius: %.3f m\n",nadir_radius);
        *corrected_earth_radius = pp_earth_radius;
    } else {
        asfPrintWarning("Failed to determine PP earth radius!\n"
                        "iter: %d, pp_earth_radius=%.3f, res=%.5f\n"
                        "Proceeding using the nadir radius: %.3f m\n"
                        "Starting points were: lo: %.3f -> %.4f\n"
                        "                      hi: %.3f -> %.4f\n",
                        iter, pp_earth_radius,
                        getObjective(pp_earth_radius, (void*)&params),
                        nadir_radius,
                        lo, getObjective(lo, (void*)&params),
                        hi, getObjective(hi, (void*)&params));
        *corrected_earth_radius = nadir_radius;
    }

    gsl_set_error_handler(prev);

    // Find the PP's per-second azimuth pixel spacing
    seconds_per_azimuth_line=nominal_pixsize_azimuth/facdr.swathvel;
    //printf("PP seconds per azimuth line: %.9f s/line\n",seconds_per_azimuth_line);
    //printf("   (for comparison) PP interpolated lines per second: %.3f lines/s\n",1.0/seconds_per_azimuth_line);
    //printf("   (for comparison) FACDR swath velocity: %.3f m/s\n",facdr.swathvel);

    //double R=pp_earth_radius;
    //double H=params.satellite_height;
    //double HHRR=H*H + R*R;
    //double slant=0.5*(params.slant_first+params.slant_last);
    //double rg_center=R*acos( (HHRR - slant*slant) / (2*H*R));
    //double vs=sqrt(facdr.scxvel*facdr.scxvel + facdr.scyvel*facdr.scyvel + facdr.sczvel*facdr.sczvel);
    //double vsg = vs * pp_earth_radius/params.satellite_height*cos(rg_center/pp_earth_radius);

    //printf("   (for comparison) PP-style recalc velocity: %.3f m/s\n",vsg);

    *corrected_azimuth_time_per_pixel = seconds_per_azimuth_line;

    // Free the solver
    gsl_root_fsolver_free(s);
}
double cnoidalFirstProperties::solve()
{

    int status, maxIter = 1000;
    scalar eps = 1.0e-10, m, mLower = 1.0e-15, mUpper = 1.0 - 1.0e-15;

    const gsl_root_fsolver_type *T;

    gsl_root_fsolver *s;

    gsl_function FlowerBound, F ;

    struct cnoidalFirstParams params = { d_ , H_ , T_ , G_ };

    FlowerBound.function = & lowerMBound_f;
    FlowerBound.params   = & params;

    T = gsl_root_fsolver_bisection;
    s = gsl_root_fsolver_alloc(T);

    gsl_root_fsolver_set(s, &FlowerBound, mLower, mUpper);

    for (int i = 0; i < maxIter; i++)
    {
        gsl_root_fsolver_iterate(s);
        m = gsl_root_fsolver_root(s);

        status = gsl_root_test_residual( lowerMBound_f(m, &params), eps );

        if (status == 0)
        {
            break;
        }
    }

    mLower = m;

    while (true)
    {
        if
        (
            ( cnoidalFirst_f(mLower, &params) < 0.0 &&
              cnoidalFirst_f(mUpper, &params) < 0.0 )
            ||
            ( cnoidalFirst_f(mLower, &params) > 0.0 &&
              cnoidalFirst_f(mUpper, &params)    > 0.0 )
        )
        {
            mLower = 0.999*mLower + 0.001*mUpper;
        }
        else
        {
            break;
        }

        if (Foam::mag(mLower - mUpper) < 10e-8)
        {
            return -1;
        }
    }

    F.function = &cnoidalFirst_f;
    F.params   = &params;

    gsl_root_fsolver_set(s, &F, mLower, mUpper);

    for (int i = 0; i < maxIter; i++)
    {
        gsl_root_fsolver_iterate(s);
        m = gsl_root_fsolver_root(s);

        status = gsl_root_test_residual( cnoidalFirst_f(m, &params), eps );

        if (status == 0)
        {
            break;
        }
    }

    Info << m << endl;


    return m;
}
Exemplo n.º 3
0
Arquivo: root.c Projeto: Fudge/rb-gsl
static VALUE rb_gsl_root_test_residual(VALUE obj, VALUE xl,VALUE eabs)
{
  Need_Float(xl); Need_Float(eabs);
  return INT2FIX(gsl_root_test_residual(NUM2DBL(xl),  NUM2DBL(eabs)));
}