Exemplo n.º 1
0
int InterpolaVPR_GSL::interpola_VPR(const float* vpr, int hvprmax, int livmin)
{
    LOG_CATEGORY("radar.vpr");
    static const unsigned N = 10;
    const gsl_multifit_fdfsolver_type *T;
    gsl_multifit_fdfsolver *s;
    int status;
    unsigned int i;
    const size_t n = N;
    const size_t p = 5;
    char file_vprint[512];
    gsl_matrix *covar = gsl_matrix_alloc (p, p);
    double a[5];
    struct data d(N);
    gsl_multifit_function_fdf f;
    double x_init[5] = { 4, 0.2, 3. , 1.4, -0.4 };
    gsl_vector_view x = gsl_vector_view_array (x_init, p);

    //////////////////////////////////////////////////////////////////////////////
    int ier_int=0;
    double xint,yint;
    /* punti interessanti per inizializzare parametri*/
    int  in1=(int)((hvprmax-TCK_VPR/2)/TCK_VPR); //indice del massimo
    int  in2=(int)((hvprmax+HALF_BB)/TCK_VPR); //indice del massimo + 500 m
    int  in3=in2+1;
    int  in4=in2+5; //indice del massimo + 1000 m
    if (in4 > NMAXLAYER-1) {
        ier_int=1;
        return ier_int;
    }

    B=vpr[in1]-vpr[in2];
    E=hvprmax/1000.;
    G=0.25;
    C=vpr[in2-1];
    F=vpr[in4]<vpr[in3]?(vpr[in4]-vpr[in3])/((in4-in3)*TCK_VPR/1000.):0.;
    // fprintf(stderr, "const unsigned NMAXLAYER=%d;\n", NMAXLAYER);
    // fprintf(stderr, "float vpr[] = {");
    // for (unsigned i = 0; i < NMAXLAYER; ++i)
    //     fprintf(stderr, "%s%f", i==0?"":",", (double)vpr[i]);
    // fprintf(stderr, "};\n");

    x_init[0]= a[0]=B;
    x_init[1]= a[1]=E;
    x_init[2]= a[2]=G;
    x_init[3]= a[3]=C;
    x_init[4]= a[4]=F;


    /////////////////////////////////////////////////////////////////////////////////////////////////////////

    f.f = &expb_f;
    f.df = &expb_df;
    f.fdf = &expb_fdf;
    f.n = n;
    f.p = p;
    f.params = &d;

    /* This is the data to be fitted */

    for (i = 0; i < n; i++)
    {
        d.t[i]= ((hvprmax-1000.)>livmin)? (i*TCK_VPR+(hvprmax-800)-TCK_VPR)/1000. : (livmin+i*TCK_VPR)/1000.;
        d.y[i]= ((hvprmax-1000.)>livmin)? vpr[i+(int)(((hvprmax-800)-TCK_VPR)/TCK_VPR)] : vpr[i+(int)(livmin/TCK_VPR)];
        d.sigma[i] = 0.5;
    };

    T = gsl_multifit_fdfsolver_lmsder;
    s = gsl_multifit_fdfsolver_alloc (T, n, p);
    gsl_multifit_fdfsolver_set (s, &f, &x.vector);

    //print_state (0, s);
    bool found = false;
    for (unsigned iter = 0; !found && iter < 500; ++iter)
    {
        //fprintf(stderr, "Iter %d\n", iter);
        //d.print();
        int status = gsl_multifit_fdfsolver_iterate (s);
        if (status != 0)
        {
            LOG_ERROR("gsl_multifit_fdfsolver_iterate: %s", gsl_strerror(status));
            return 1;
        }

        //print_state (iter, s);

        status = gsl_multifit_test_delta (s->dx, s->x,
                1e-4, 1e-4);
        switch (status)
        {
            case GSL_SUCCESS: found = true; break;
            case GSL_CONTINUE: break;
            default:
                LOG_ERROR("gsl_multifit_test_delta: %s", gsl_strerror(status));
                return 1;
        }
    }

#if GSL_MAJOR_VERSION == 2
    // Use of GSL 2.0 taken from https://sft.its.cern.ch/jira/browse/ROOT-7776
    gsl_matrix* J = gsl_matrix_alloc(s->fdf->n, s->fdf->p);
    gsl_multifit_fdfsolver_jac(s, J);
    gsl_multifit_covar(J, 0.0, covar);
#else
    gsl_multifit_covar(s->J, 0.0, covar);
#endif

#define FIT(i) gsl_vector_get(s->x, i)
#define ERR(i) sqrt(gsl_matrix_get(covar,i,i))

    { 
        double chi = gsl_blas_dnrm2(s->f);
        double dof = n - p;
        double c = GSL_MAX_DBL(1, chi / sqrt(dof)); 

        // printf("chisq/dof = %g\n",  pow(chi, 2.0) / dof);

        // printf ("B      = %.5f +/- %.5f\n", FIT(0), c*ERR(0));
        // printf ("E = %.5f +/- %.5f\n", FIT(1), c*ERR(1));
        // printf ("G     = %.5f +/- %.5f\n", FIT(2), c*ERR(2));
        // printf ("C = %.5f +/- %.5f\n", FIT(3), c*ERR(3));
        // printf ("F     = %.5f +/- %.5f\n", FIT(4), c*ERR(4));
    }

    B = a[0] = FIT(0);
    E = a[1] = FIT(1);
    G = a[2] = FIT(2);
    C = a[3] = FIT(3);
    F = a[4] = FIT(4);

    gsl_multifit_fdfsolver_free (s);
    gsl_matrix_free (covar);

    /////////////////////////////////////////////////////////

    if (testfit(a) == 1)
        return 1;

    for (i=1; i<=N; i++)
    {
        xint=(i*TCK_VPR-TCK_VPR/2)/1000.;
        yint= lineargauss(xint, a);
        vpr_int[i-1] = yint;
    }

    return 0;
}
Exemplo n.º 2
0
int main(int argc, char **argv[])
{
	testfit();
	exit(0);
}
Exemplo n.º 3
0
/*
   comstart interpola_VPR
   idx interpola il profilo verticale tramite una funzione lingauss
   interpola il profilo verticale tramite una funzione gaussiana + lineare del tipo

   y= B*exp(-((x-E)/G)^2)+C+Fx

   usa la funzione mrqmin delle numerical recipes in C: tutti i vettori passati a mrqmin devono essere allocati e deallcocati usando le funzioni di NR (vector, matrix, free_vector, free_matrix.. etc) che definiscono vettori con indice a partire da 1.
   NB gli ndata dati considerati partono da 1000 m sotto il massimo (in caso il massimo sia più basso di 1000 m partono da 0 m)
   A ogni iterazione si esegue un test sui parametri. Se ritorna 1 si torna ai valori dell'iterazione precedente.
   A fine interpolazione si verifica che il chisquare non superi una soglia prefissata, in tal caso ritorna 1 e interpol. fallisce.

   INIZIALIZZAZIONE PARAMETRI:
   a[1]=B=vpr(liv del massimo)-vpr(liv. del massimo+500m);
   a[2]=E= quota liv. massimo vpr (in KM);
   a[3]=G=semiampiezza BB (quota liv .massimo- quota massimo decremento vpr nei 600 m sopra il massimo ) in KM;
   a[4]=C=vpr(liv massimo + 700 m);
   a[5]=F=coeff. angolare segmento con estremi nel vpr ai livelli max+900m e max+1700m, se negativo =0.;


   float a[ma], int ma: vettore parametri e n0 parametri
   float *x, *y:  quote in KM e valori del vpr usati per l'interpolazione
   float *sig,alamda : vettore dev st. e variabile che decrementa al convergere delle iterazioni
   float *dyda: vettore derivate rispetto ai parametri
   float B,E,C,G,F:  parametri da ottimizzare, first guess
   float chisq; scarto quadratico
   int i,in1,in2,in3,in4,*ia,ifit,ii,ndati_ok,k;
   int ndata=15;  numero di dati considerati
   float **covar,**alpha; matrice ovarianze, matrice alpha

   comend
*/
int InterpolaVPR_NR::interpola_VPR(const float* vpr, int hvprmax, int livmin)
{
    LOG_CATEGORY("radar.vpr");
    static const unsigned npar=5;
    float *x, *y,*sig,alamda,y1=0,*dyda,xint,qdist,*abest;
    float chisq=100.;
    float chisqold=0.0;
    float chisqin=0.0;
    int i,in1,in2,in3,in4,*ia,ifit,ii,ndati_nok,k,ier_int;
    //int ma=5;
    int ndata=10;
    float **covar;
    float **alpha;
    FILE *file;

    float *a=vector(1,npar);
    for (i=1;i<=npar;i++){
        a[i]=NODATAVPR;
    }

    LOG_INFO("sono in interpola_vpr");
    ier_int=0;

    in1=(hvprmax-TCK_VPR/2)/TCK_VPR; //indice del massimo
    in2=(hvprmax+HALF_BB)/TCK_VPR; //indice del massimo + 500 m
    in3=in2+1;
    in4=in2+5; //indice del massimo + 1000 m
    LOG_INFO("in1 in2 %i %i %f %f",in1,in2,vpr[in1],vpr[in2]);

    if (in4 > NMAXLAYER-1) {
        ier_int=1;
        return ier_int;
    }

    /* inizializzazione vettore parametri */
    abest=vector(1,npar);
    x=vector(1,ndata);
    y=vector(1,ndata);
    sig=vector(1,ndata);
    ia=ivector(1,npar);
    covar=matrix(1,npar,1,npar);
    alpha=matrix(1,npar,1,npar);

    for (k=in1+2; k<=in3; k++)
    {
        ier_int=0;

        dyda=vector(1,npar);
        a[1]=B=vpr[in1]-vpr[in2];
        a[2]=E=hvprmax/1000.;
          a[3]=G=(k-in1-0.5)*TCK_VPR/1000.;
          //  a[3]= G=0.25;
        a[4]=C=vpr[in2];
        a[5]=F=vpr[in4]<vpr[in3]?(vpr[in4]-vpr[in3])/((in4-in3)*TCK_VPR/1000.):0.;
        //fprintf(stderr, "k:%d, a1:%f a2:%f a3:%f a4:%f a5:%f\n", k, a[1], a[2], a[3], a[4], a[5]);

        alamda=-0.01;

        for (i=1;i<=npar;i++) ia[i]=1;
        qdist=0;
        ii=1;
        ndati_nok=0;

        for (i=1; i<=ndata; i++)
        {
            sig[ii]=0.5;
            x[ii]= ((hvprmax-1000.)>livmin)? (i*TCK_VPR+(hvprmax-800)-TCK_VPR)/1000. : (livmin+(i-1)*TCK_VPR)/1000.;
            y[ii]= ((hvprmax-1000.)>livmin)? vpr[i+((hvprmax-800)-TCK_VPR)/TCK_VPR] : vpr[i-1+livmin/TCK_VPR];
            // x[ii]= ((hvprmax-800.)>livmin)? (i*TCK_VPR+(hvprmax-600)-TCK_VPR)/1000. : (livmin+(i-1)*TCK_VPR)/1000.;
            //y[ii]= ((hvprmax-800.)>livmin)? vpr[i+((hvprmax-600)-TCK_VPR)/TCK_VPR] : vpr[i-1+livmin/TCK_VPR];
            lineargauss(x[ii], a, &y1, dyda, ndata);
            qdist=(y1-y[ii])*(y1-y[ii]);
            //fprintf(stderr, "i:%d, ii:%d, xii:%f, yii:%f, y1:%f, qdist:%f, chisqin:%f\n", i, ii, x[ii], y[ii], y1, qdist, chisqin);
            if (sqrt(qdist) < DIST_MAX)
            {
                ii+=1;
                chisqin=qdist+chisqin;
            }
            else
                ndati_nok=ndati_nok+1;

            if    ( ndati_nok > 2  )
            {
                LOG_WARN("  first guess troppo lontano dai punti , interpolazione fallisce");
                ier_int=1;
                break;
            }
        }

        if (!ier_int)
        {
            LOG_INFO("\n alamda %f   chisqin % f a[1]  % f a[2] % f a[3]  % f a[4]  % f a[5]  % f", alamda,chisqin,a[1], a[2], a[3],a[4],a[5]);
            //fprintf(stderr, "i    t    y    sigma\n");
            //for (unsigned i = 1; i <= ndata; ++i)
                //fprintf(stderr, "%2d %.2f %.2f %.2f\n", i, x[i], y[i], sig[i]);
            ifit=0;
            while (fabs(chisq-chisqold) > DCHISQTHR && ifit < 1)
            {
                chisqold=chisq;
                B=a[1];
                E=a[2];
                G=a[3];
                C=a[4];
                F=a[5];
                mrqmin(x, y, sig, ndata, a, ia, npar, covar, alpha, &chisq, &lineargauss, &alamda);
                LOG_INFO("alamda %f   chisq % f a[1]  % f a[2] % f a[3]  % f a[4]  % f a[5]  % f", alamda,chisq,a[1], a[2], a[3],a[4],a[5]);
                ifit=testfit(a,chisq,chisqin);  /*test sul risultato del fit */
                if (ifit)
                {/*test sul risultato del fit */
                    a[1]=B; /*test sul risultato del fit */
                    a[2]=E; /*test sul risultato del fit */
                    a[3]=G; /*test sul risultato del fit */
                    a[4]=C; /*test sul risultato del fit */
                    a[5]=F; /*test sul risultato del fit */
                    chisq=chisqin;
                }
            }


            if (chisq < chisqfin)
            {
                chisqfin=chisq;
                for (i=1;i<=npar;i++) abest[i]=a[i];
            }
        }
    }

    for (i=1; i<=ndata-ndati_nok; i++)
    {
        lineargauss(x[i], abest, &y1, dyda, ndata);
        rmsefin=rmsefin+  (y[i]-y1)*(y[i]-y1) ;
    }
    rmsefin=sqrt(rmsefin/(float)((ndata-ndati_nok)*(ndata-ndati_nok)));
    LOG_INFO("RMSEFIN %f", rmsefin );


    if (chisqfin>CHISQ_MAX)
    {
        ier_int=1;
    }
    else {
        // Calcola il profilo interpolato
        for (i=1;i<=npar;i++) a[i]=abest[i];
        for (i=1; i<=NMAXLAYER; i++)
        {
            xint=(i*TCK_VPR-TCK_VPR/2)/1000.;
            lineargauss(xint, a, &y1, dyda, ndata);
            vpr_int[i-1] = y1;
        }
    }
    B=a[1];
    E=a[2];
    G=a[3];
    C=a[4];
    F=a[5];
    free_vector(dyda,1,npar);
    free_vector(abest,1,npar);
    free_ivector(ia,1,npar);
    free_vector(x,1,ndata);
    free_vector(y,1,ndata);
    free_vector(sig,1,ndata);
    free_matrix(alpha,1,ndata,1,ndata);
    free_matrix(covar,1,ndata,1,ndata);
    free_vector(a,1,npar);

    return ier_int;
}
Exemplo n.º 4
0
int main(int argc, char* argv[]) {
  // a function to do L-M minimization and return H coronal parameters
  // from spacecraft data

  //set up the input variables: name of file to fit against, and optional fitting parameters
  string obsname;
  bool userIPH=FALSE;
  double IPHb=0.0;
  bool usercal=FALSE;
  double cal=1.0;
  bool usertemp=FALSE;
  double Texo=1.0;
  bool userdens=FALSE;
  double nexo=1.0;
  bool printsim=FALSE;
  bool simulate_IPH=FALSE;
  bool forcesim=FALSE;
  
  for (int i = 1; i < argc; i++)  /* Skip argv[0] (program name). */
    {
      if (strcmp(argv[i], "-b") == 0)  /* Process optional arguments. */
        {
	  userIPH=TRUE;
	  /*
	   * Increment 'i' again (twice total) so that you don't
	   * check these arguments the next time through the loop.
	   */
	  i++;
	  IPHb = atof(argv[i]);  /* Convert string to int. */
	}
      else if (strcmp(argv[i], "-c") == 0)
        {
	  usercal=TRUE;
	  i++;
	  cal = atof(argv[i]);
	  std::cout << "Fixing calibration factor at " << cal << " .\n";
	  std::cout << std::endl;
        }
      else if (strcmp(argv[i], "-T") == 0)
        {
	  usertemp=TRUE;
	  i++;
	  Texo = atof(argv[i]);
	  std::cout << "Fixing temperature at " << Texo << " K.\n";
	  std::cout << std::endl;
        }
      else if (strcmp(argv[i], "-n") == 0)
        {
	  userdens=TRUE;
	  i++;
	  nexo = atof(argv[i]);
	  std::cout << "Fixing density at " << nexo << " / cm3.\n";
	  std::cout << std::endl;
        }
      else if (strcmp(argv[i], "-simIPH") == 0)
        {
	  simulate_IPH=TRUE;
        }
      else if (strcmp(argv[i], "-forcesim") == 0)
        {
	  forcesim=TRUE;
        }
      else if (strcmp(argv[i], "-p") == 0)
        {
	  printsim=TRUE;
	}
      else
	{
	  //get the observation to perform analysis on from the function call:
	  obsname=argv[i];
	  std::cout << "Observation under analysis is: " << obsname << std::endl;	  
        }
    }

  if (userIPH) {
    if (simulate_IPH) {
      std::cout << "Fixing background IPH multiplier at " << IPHb << " .\n";
      std::cout << std::endl;
    } else {
      std::cout << "Fixing background IPH at " << IPHb << " kR.\n";
      std::cout << std::endl;
    }
  } else {
    if (simulate_IPH) {
      IPHb=1.0;
    } else {
      IPHb=0.0;
    }
  }
  if (!usercal) {
    cal=1.0;
  }


  corona_simulator sim;
  std::cout << "Proceeding with interpolated computation.\n";
  sim.obs_import(obsname,simulate_IPH);//load the observation

  //here's an initial parameter guess:
  VecDoub parms(4);///mmm delicious parms
  parms[0]=30000.0;parms[1]=350.0;parms[2]=0.45;parms[3]=1.0;

  //this sets it up:
  Fitmrq testfit(sim.obs_vec,sim.I_obs,sim.DI_obs,parms,sim);

  //if the user specified values, fix this to the user value:
  if (userdens) {
    testfit.hold(0,nexo);
  }
  if (usertemp) {
    testfit.hold(1,Texo);
  }
  if (userIPH) {
    testfit.hold(2,IPHb);
  }
  if (usercal) {
    testfit.hold(3,cal);
  }
  
  //now do the fit, which updates all the contained objects:
  testfit.fit();

  //get the escape flux for these parameters
  double lambdac = G*mMars*mH/(kB*testfit.a[1]*rexo);
  double vth = std::sqrt(2*kB*parms[1]/mH);
  double escflux = testfit.a[0]*vth/(2*std::sqrt(pi))
                           *(1+lambdac)*std::exp(-lambdac);

  
  //print out the results:
  std::cout << "\nHere's the result of the fitting routine:\n"
	    << "Chi-squared is: " << testfit.chisq
	    << " on " << sim.nobs-parms.size() << " DOF."<< std::endl;

  std::cout << "\nBest fit model parameters are: \n";
  for (int i = 0; i < testfit.a.size(); i++)
    std::cout << testfit.a[i] << ",\t";
  std::cout << "\b\b\n";

  std::cout << "\nComputed escape flux is: \n";
  std::cout << escflux << std::endl;
    
  std::cout << "\nFormal fit parameter covariance matrix is as follows: \n";
  for (int i = 0; i < testfit.a.size(); i++) {
    std::cout << " [ ";
    for (int j = 0; j < testfit.a.size(); j++) {
      std::cout.width(10);
      std::cout << testfit.covar[i][j] << ",\t";
    }
    std::cout << "\b\b ]" << std::endl;
  }

  if (printsim) { //print out the simulated values at the best fit
    double I_calc[sim.nobs];
    
    for (int i = 0; i < sim.nobs; i++) {
      I_calc[i] = testfit.a[3]*sim.interp_iobs(sim.obs_vec[i],
					       testfit.a[0],
					       testfit.a[1],
					       testfit.a[2]);
    }

    //print out the results:
    std::cout << "\nHere's the best fit:\n"
	      << "\nI_calc = [ ";
    for (int i = 0; i < sim.nobs-1; i++)
      std::cout << I_calc[i] << ", ";
    std::cout << I_calc[sim.nobs-1] << " ]\n";

    if (simulate_IPH) {
      std::cout << "\nHere's the computed and scaled IPH vector:\n"
		<< "\nIPH = [ ";
      for (int i = 0; i < sim.nobs-1; i++)
	std::cout << testfit.a[3]*testfit.a[2]*sim.IPHb_model[i] << ", ";
      std::cout << testfit.a[3]*testfit.a[2]*sim.IPHb_model[sim.nobs-1] << " ]\n";
    }
    
  }

  std::cout << std::endl << "\n\nYou have reached the end of the program!\nGoodbye.\n\n";

  return 0; 
}