Пример #1
0
double PowerSpec_Tabulated::power(double k, int Type)
{
  double logk = log10(k*scale);
  double transfer;

  if(logk < ktransfer_table[0] || logk > ktransfer_table[NTransferTable - 1])
    return 0;

  if(logk < kmatter_table[0] || logk > kmatter_table[NPowerTable - 1])
    return 0;

  //If a type is requested that isn't defined, assume we want the total matter power.
  if (Type > N_TYPES_TAB-1 || Type < 0)
      transfer = 1;
  else
      transfer = gsl_interp_eval(trans_interp[Type], ktransfer_table, transfer_table[Type], logk, trans_interp_accel[Type]);
  /* Sometimes, due to numerical roundoff in CAMB, the massive neutrino transfer function will become
   * slightly negative. Set it to close to zero in this case.*/
  if(transfer < 0 && Type==2 && transfer > -1e-6){
      transfer = 1e-14;
  }

  double logP = gsl_interp_eval(pmat_interp, kmatter_table, pmatter_table, logk, pmat_interp_accel);
  double P = pow(10.0, logP) * pow(scale, 3) * transfer;
  assert(P >= 0);
  return P;
}
Пример #2
0
void makedisk(bool randspin)
{
  int i;
  bodyptr bp;
  double m, r, v, phi;
  matrix xmat, zmat;
  vector tmpv;

  for (i = 0; i < ndisk; i++) {			// loop initializing bodies
    bp = NthBody(disk, i);			// set ptr to body number i
    m = mdtab[NTAB-1] * ((double) i + 0.5) / ndisk;
    r = gsl_interp_eval(rm_spline, mdtab, rdtab, m, NULL);
    v = gsl_interp_eval(vr_spline, rdtab, vctab, r, NULL);
    phi = xrandom(0.0, 2 * M_PI);
    Pos(bp)[0] = r * sin(phi);
    Pos(bp)[1] = r * cos(phi);
    Pos(bp)[2] = 0.0;
    Vel(bp)[0] = v * cos(phi);
    Vel(bp)[1] = - v * sin(phi);
    Vel(bp)[2] = 0.0;
    pickshell(AuxVec(bp), NDIM, 1.0);
    if (randspin) {
      xmatrix(xmat, acos(AuxVec(bp)[2]));
      zmatrix(zmat, atan2(AuxVec(bp)[0], AuxVec(bp)[1]));
      MULMV(tmpv, xmat, Pos(bp));
      MULMV(Pos(bp), zmat, tmpv);
      MULMV(tmpv, xmat, Vel(bp));
      MULMV(Vel(bp), zmat, tmpv);
    }
  }
}
Пример #3
0
complex double * gamma_spline_V(GammaSpline *gs, GList * const sd, double kc, int component)
{
    if (!gstimer) {
        gstimer = g_timer_new();
        g_timer_start(gstimer);
    }
    else g_timer_continue(gstimer);
    
    int NB = model->total_bands;
    
    complex double * V = complex_double_array_calloc (NB*NB);
    
    size_t m, n;

    for (m=0;m<NB;m++) {
        for (n=0;n<NB;n++) {
            gamma_spline_reset(gs,sd,m,n,FALSE);
            if (component==0) {
                V[m+n*NB]=gsl_interp_eval(gs->wx_spline_re,gs->k,gs->Wxr,kc,gs->w_accel)+I*gsl_interp_eval(gs->wx_spline_im,gs->k,gs->Wxi,kc,gs->w_accel);
            }
            else if (component==1) {
                V[m+n*NB]=gsl_interp_eval(gs->wy_spline_re,gs->k,gs->Wyr,kc,gs->w_accel)+I*gsl_interp_eval(gs->wy_spline_im,gs->k,gs->Wyi,kc,gs->w_accel);
            }
            else if (component==2) {
                V[m+n*NB]=gsl_interp_eval(gs->wz_spline_re,gs->k,gs->Wzr,kc,gs->w_accel)+I*gsl_interp_eval(gs->wz_spline_im,gs->k,gs->Wzi,kc,gs->w_accel);
            }
        }
    }
    g_timer_stop(gstimer);
    return V;
}
Пример #4
0
Gamma * gamma_spline_calc_little_gamma (GammaSpline *gs, double * omega) { // without the one over omega
    if (!gstimer) {
        gstimer = g_timer_new();
        g_timer_start(gstimer);
    }
    else g_timer_continue(gstimer);

    int q=0;
	double kc;
    int Nkc = 16384;
    Gamma * g = gamma_new (Nkc);
    
    double dkc=2*KCMAX/Nkc;
    double denom=pow(KCMAX,4);
	for (kc=-KCMAX+dkc;kc<KCMAX;kc=kc+dkc) {
	    complex double a = gsl_interp_eval(gs->wx_spline_re,gs->k, gs->Wxr, kc,gs->w_accel)+I*gsl_interp_eval(gs->wx_spline_im,gs->k,gs->Wxi,kc,gs->w_accel);
	    double b = gsl_interp_eval_deriv(gs->phi_spline,gs->k, gs->phi, kc,gs->phi_accel);
	    omega[q]=b;
	    double damp = exp(-4*pow(fabs(kc),4)/denom);
	    
	    g->x[q]=a*damp;
	    
	    complex double c = gsl_interp_eval(gs->wy_spline_re,gs->k,gs->Wyr,kc,gs->w_accel)+I*gsl_interp_eval(gs->wy_spline_im,gs->k,gs->Wyi,kc,gs->w_accel);
	    g->y[q]=c*damp;
	    
	    complex double d = gsl_interp_eval(gs->wz_spline_re,gs->k,gs->Wzr,kc,gs->w_accel)+I*gsl_interp_eval(gs->wz_spline_im,gs->k,gs->Wzi,kc,gs->w_accel);
	    g->z[q]=d*damp;
	    
	    q++;
	}
    g_timer_stop(gstimer);
    
	return g;
}
Пример #5
0
cmpl
disp_sample_table_n_value(const disp_t *disp, double lam)
{
    const struct disp_sample_table *dt = & disp->disp.sample_table;
    if (lam <= get_wavelength(dt, 0)) {
        return get_n(dt, 0) - get_k(dt, 0) * I;
    } else if (lam >= get_wavelength(dt, dt->len - 1)) {
        return get_n(dt, dt->len - 1) - get_k(dt, dt->len - 1) * I;
    }
    double nx = gsl_interp_eval(dt->interp_n, wavelength_const_array(dt), n_const_array(dt), lam, dt->accel);
    double kx = gsl_interp_eval(dt->interp_k, wavelength_const_array(dt), k_const_array(dt), lam, dt->accel);
    return nx - kx * I;
}
Пример #6
0
double integrand(double mass, void *params) {
  double radius = gsl_interp_eval(interp_radius, arr_mass, arr_radius, mass, acc_radius);
  double temp   = gsl_interp_eval(interp_temp, arr_mass, arr_temp, mass, acc_temp);
  double dens   = gsl_interp_eval(interp_dens, arr_mass, arr_dens, mass, acc_dens);
  double m_mu   = gsl_interp_eval(interp_m_mu, arr_mass, arr_m_mu, mass, acc_m_mu);

  real f = -mass/radius;
  real de_therm = 1.5*uK*temp/m_mu/uM_U + 
    uA_RAD*pow(temp, 4.0)/dens;
  de_therm *= 1.0/(uG*uMSUN/uRSUN);

  return (f + de_therm);
}
Пример #7
0
// -----------------------------------------------------------------------------
double hand_anim_get(double x)
{
	DEBUGLOGB;

	double interpY = 0;

#ifdef _USEGSL
#ifdef _USEGSL_STATIC

	interpY = gsl_interp_eval(g_curveTerp, g_curvePtsX, g_curvePtsY, x, g_curveAccl);

#else // _USEGSL_STATIC

	if( g_pLLibok )
	{
		interpY = g_gsl_interp_eval(g_curveTerp, g_curvePtsX, g_curvePtsY, x, g_curveAccl);
	}
	else
	{
		interpY = g_curvePtsY[0];
		for( size_t p = 1; p < g_curvePtsN; p++ )
		{
			if( g_curvePtsX[p] >= x )
			{
				double a =    g_curvePtsS[p];
				double X = (x-g_curvePtsX[p-1]);
				double b =    g_curvePtsY[p-1];
				interpY  =  a*X+b;
				break;
			}
		}
	}

#endif // _USEGSL_STATIC
#else  // _USEGSL
#ifdef _USESPLINE

	interpY = g_curve(x);

#else

	interpY = g_curvePtsY[0];
	for( size_t p  = 1; p < g_curvePtsN; p++ )
	{
		if( g_curvePtsX[p] >= x )
		{
			double a =    g_curvePtsS[p];
			double X = (x-g_curvePtsX[p-1]);
			double b =    g_curvePtsY[p-1];
			interpY  =  a*X+b;
			break;
		}
	}

#endif // _USESPLINE
#endif // _USEGSL

	DEBUGLOGE;
	return interpY;
}
static double eos_h_of_p_tabular(double p, LALSimNeutronStarEOS * eos)
{
    double h;
    h = gsl_interp_eval(eos->data.tabular->h_of_p_interp,
        eos->data.tabular->pdat, eos->data.tabular->hdat, p,
        eos->data.tabular->h_of_p_acc);
    return h;
}
static double eos_p_of_h_tabular(double h, LALSimNeutronStarEOS * eos)
{
    double p;
    p = gsl_interp_eval(eos->data.tabular->p_of_h_interp,
        eos->data.tabular->hdat, eos->data.tabular->pdat, h,
        eos->data.tabular->p_of_h_acc);
    return p;
}
static double eos_e_of_h_tabular(double h, LALSimNeutronStarEOS * eos)
{
    double e;
    e = gsl_interp_eval(eos->data.tabular->e_of_h_interp,
        eos->data.tabular->hdat, eos->data.tabular->edat, h,
        eos->data.tabular->e_of_h_acc);
    return e;
}
static double eos_rho_of_h_tabular(double h, LALSimNeutronStarEOS * eos)
{
    double rho;
    rho =
        gsl_interp_eval(eos->data.tabular->rho_of_h_interp,
        eos->data.tabular->hdat, eos->data.tabular->rhodat, h,
        eos->data.tabular->rho_of_h_acc);
    return rho;
}
Пример #12
0
double
gsl_spline_eval (const gsl_spline * spline,
                 double x,
                 gsl_interp_accel * a)
{
  return gsl_interp_eval (spline->interp, 
                          spline->x, spline->y,
                          x, a);
}
Пример #13
0
void csinterp(double x[], double y[], double nx[], double ny[], int m, int n) {
	int i;
	gsl_interp *workspace;
	/* type of Interpolation: Cubic Spline */
	workspace = gsl_interp_alloc(gsl_interp_cspline, m);
	gsl_interp_init(workspace, x, y, m); /* Initialize worksp */
	for(i = 0; i < n; i++)
		ny[i] = gsl_interp_eval(workspace, x, y, nx[i], NULL);
	gsl_interp_free(workspace); /* free memory */
}
Пример #14
0
double smoothing_integrand(double x, void *params) {
  struct smoothing_params *p = (struct smoothing_params* )params;
  double y;
  if      (x < 0)                   y = p->arr_y[0];
  else if (x >= p->arr_x[p->n-1])   y = p->arr_y[p->n-1];
  else                              y = gsl_interp_eval(p->int_y, p->arr_x, p->arr_y, x, p->acc_y);
  
  real   wk = smoothing_kernel(p->x - x, p->h);
  return y * wk;
}
Пример #15
0
 DoubleReal TransformationModelInterpolated::evaluate(const DoubleReal value)
 const
 {
   if ((value < x_[0]) || (value > x_[size_ - 1]))     // extrapolate
   {
     return lm_->evaluate(value);
   }
   // interpolate:
   const double * x_start = &(x_[0]), * y_start = &(y_[0]);
   return gsl_interp_eval(interp_, x_start, y_start, value, acc_);
 }
Пример #16
0
Gamma * gamma_spline_calc_gamma (const GammaSpline *gs, double epsilon) {
	//int q=0;
	double kc;
    int Nkc = Nkc_from_epsilon(epsilon);
    Gamma * g = gamma_new (Nkc);
    double dkc=2*KCMAX/Nkc;
    double denom=pow(KCMAX,4);
    
    int q=Nkc/2;   /* we do this in a funny order to keep phase oscillations out of the spectrum */
	for (kc=-KCMAX+dkc;kc<KCMAX;kc=kc+dkc) {
	    complex double a = gsl_interp_eval(gs->wx_spline_re,gs->k,gs->Wxr,kc,gs->w_accel)+I*gsl_interp_eval(gs->wx_spline_im,gs->k,gs->Wxi,kc,gs->w_accel);
	    complex double b = cexp(-4*pow(fabs(kc),4)/denom+I*gsl_interp_eval(gs->phi_spline,gs->k,gs->phi,kc,gs->phi_accel)/epsilon);
	    g->x[q]= a*b;
	    
	    a = gsl_interp_eval(gs->wy_spline_re,gs->k,gs->Wyr,kc,gs->w_accel)+I*gsl_interp_eval(gs->wy_spline_im,gs->k,gs->Wyi,kc,gs->w_accel);
	    g->y[q]=a*b;
	    
	    a = gsl_interp_eval(gs->wz_spline_re,gs->k,gs->Wzr,kc,gs->w_accel)+I*gsl_interp_eval(gs->wz_spline_im,gs->k,gs->Wzi,kc,gs->w_accel);
	    
	    g->z[q]=a*b;
	    
	    q++;
	    if (q==Nkc)
	        q=0;
	}
	return g;
}
Пример #17
0
int findzofA(double Gmu, double alpha)
{
  double lnz_min = log(1e-20), lnz_max = log(1e10), dlnz =0.05;
  size_t numz       = floor( (lnz_max - lnz_min)/dlnz );
  int i,j;
  cs_cosmo_functions_t cosmofns;
  double *fz,*z;
  double a;
  gsl_interp *zofa_interp; 
  gsl_interp_accel *acc_zofa = gsl_interp_accel_alloc(); 

  cosmofns = XLALCSCosmoFunctionsAlloc( exp( lnz_min ), dlnz, numz );

  zofa_interp = gsl_interp_alloc (gsl_interp_linear, cosmofns.n);

  fz   = calloc( cosmofns.n, sizeof( *fz ) ); 
  z   = calloc( cosmofns.n, sizeof( *z ) ); 
  
  /* first compute the function that relates A and z */
  /* invert order; b/c fz is a monotonically decreasing func of z */
  j=0;
  for ( i = cosmofns.n-1 ; i >=  0; i-- )
    {
      z[j]=cosmofns.z[i];
      fz[j] = pow(cosmofns.phit[i],2.0/3.0) * pow(1+z[j],-1.0/3.0) / cosmofns.phiA[i];
      j=j+1;
    }

  gsl_interp_init (zofa_interp, fz, z, cosmofns.n);

  /* now compute the amplitudes (suitably multiplied) that are equal to fz for some z*/
  for ( j = 0; j < Namp; j++ )
    {
      a = amp[j] * pow(H0,-1.0/3.0) * pow(alpha,-2.0/3.0) / Gmu;
      zofA[j] = gsl_interp_eval (zofa_interp, fz, z, a, acc_zofa );
/*       fprintf(stdout,"%e %e %e\n", amp[j],a, zofA[j]); */
    }

  XLALCSCosmoFunctionsFree( cosmofns );
  free(fz);
  free(z);
  gsl_interp_free (zofa_interp);
  gsl_interp_accel_free(acc_zofa);

  return 0;
  
}
Пример #18
0
double integral(double x, void* params)
{
    param_struct* p = (param_struct*) params;
    double E_p = p->E_p;
    
    
    
    if(E_p + x < p->E_p_min || E_p + x > p->E_p_max)
    {
        return 0.0;
    }
    
    double pdf_prob = gsl_interp_eval(p->interp, p->E_p_array, p->prob_array, E_p + x, p->accel);
    double gauss_prob = gaussian(x);
    
    return pdf_prob * gauss_prob;
}
Пример #19
0
double NonlinearProperty::interp(const double strain)
{
    double d;

    if (strain < m_strain.first()) {
        d = m_varied.first();
    } else if (strain > m_strain.last()) {
        d = m_varied.last();
    } else if (m_strain.size() == 1) {
        // Interpolater won't be intialized
        d = m_varied.first();
    } else {
        if (!m_interp)
            initialize();

        d = gsl_interp_eval(m_interp, m_strain.data(), m_varied.data(), strain, m_acc);
    }

    return d;
}
Пример #20
0
double MfCumulative::M(const double nM)
{
  return gsl_interp_eval(interp, nM_array, M_array, nM, acc);
}
Пример #21
0
static PyObject *cs_gamma_findzofA(PyObject *self, PyObject *args)
{
  PyArrayObject *Numpy_amp;
  PyObject *Numpy_zofA;
  double Gmu, alpha, *zofA, *amp;
  unsigned long int Namp;
  (void)self;	/* silence unused parameter warning */

  double z_min = 1e-20, z_max = 1e10;
  double dlnz = 0.05;
  unsigned numz = floor( (log(z_max) - log(z_min)) / dlnz );
  unsigned long int i;
  cs_cosmo_functions_t cosmofns;
  double *fz,*z;
  double a;
  gsl_interp *zofa_interp;
  gsl_interp_accel *acc_zofa = gsl_interp_accel_alloc();

  if (!PyArg_ParseTuple(args, "ddO!", &Gmu, &alpha, &PyArray_Type, &Numpy_amp))
    return NULL;

  Numpy_amp = PyArray_GETCONTIGUOUS(Numpy_amp);
  if(!Numpy_amp)
    return NULL;
  Namp = PyArray_DIM(Numpy_amp, 0);
  amp = PyArray_DATA(Numpy_amp);

  {
  npy_intp dims[1] = {Namp};
  Numpy_zofA = PyArray_SimpleNew(1, dims, NPY_DOUBLE);
  }
  zofA = PyArray_DATA((PyArrayObject *) Numpy_zofA);

  cosmofns = XLALCSCosmoFunctionsAlloc( z_min, dlnz, numz );

  zofa_interp = gsl_interp_alloc (gsl_interp_linear, cosmofns.n);

  fz = calloc( cosmofns.n, sizeof( *fz ) );
  z = calloc( cosmofns.n, sizeof( *z ) );

  /* first compute the function that relates A and z */
  /* invert order; b/c fz is a monotonically decreasing func of z */
  for ( i = cosmofns.n ; i > 0; i-- )
    {
      unsigned long int j = cosmofns.n - i;
      z[j] = cosmofns.z[i-1];
      fz[j] = pow(cosmofns.phit[i-1], 2.0/3.0) * pow(1+z[j], -1.0/3.0) / cosmofns.phiA[i-1];
    }

  gsl_interp_init (zofa_interp, fz, z, cosmofns.n);

  /* now compute the amplitudes (suitably multiplied) that are equal to fz for some z*/
  for ( i = 0; i < Namp; i++ )
    {
      a = amp[i] * pow(H0,-1.0/3.0) * pow(alpha,-2.0/3.0) / Gmu;
      /* evaluate z(fz) at fz=a */
      zofA[i] = gsl_interp_eval (zofa_interp, fz, z, a, acc_zofa );
      if(gsl_isnan(zofA[i])) {
        Py_DECREF(Numpy_zofA);
        Numpy_zofA = NULL;
        break;
      }
    }

  XLALCSCosmoFunctionsFree( cosmofns );
  Py_DECREF(Numpy_amp);
  free(fz);
  free(z);
  gsl_interp_free (zofa_interp);
  gsl_interp_accel_free(acc_zofa);

  return Numpy_zofA;
}
Пример #22
0
/* Take in an array of cdbs */
int cdb_read_aggregate_records(cdb_t **cdbs, int num_cdbs, cdb_request_t *request,
    uint64_t *driver_num_recs, cdb_record_t **records, cdb_range_t *range) {

    uint64_t i = 0;
    int ret    = CDB_SUCCESS;
    cdb_record_t *driver_records = NULL;
    *driver_num_recs = 0;

    if (cdbs[0] == NULL) {
        return CDB_ESANITY;
    }

    /* The first cdb is the driver */
    ret = _cdb_read_records(cdbs[0], request, driver_num_recs, &driver_records);

    if (ret != CDB_SUCCESS) {
        fprintf(stderr, "Bailed on: %s\n", cdbs[0]->filename);
        free(driver_records);
        return ret;
    }

    if ((*records = calloc(*driver_num_recs, RECORD_SIZE)) == NULL) {
        free(driver_records);
        return CDB_ENOMEM;
    }

    if (*driver_num_recs <= 1) {
        free(driver_records);
        return CDB_EINTERPD;
    }

    double *driver_x_values   = calloc(*driver_num_recs, sizeof(double));
    double *driver_y_values   = calloc(*driver_num_recs, sizeof(double));
    double *follower_x_values = calloc(*driver_num_recs, sizeof(double));
    double *follower_y_values = calloc(*driver_num_recs, sizeof(double));

    for (i = 0; i < *driver_num_recs; i++) {
        (*records)[i].time  = driver_x_values[i] = driver_records[i].time;
        (*records)[i].value = driver_y_values[i] = driver_records[i].value;
    }

    /* initialize and allocate the gsl objects  */
    gsl_interp_accel *accel = gsl_interp_accel_alloc();
    gsl_interp *interp = gsl_interp_alloc(gsl_interp_linear, *driver_num_recs);

    /* Allows 0.0 to be returned as a valid yi */
    gsl_set_error_handler_off();

    gsl_interp_init(interp, driver_x_values, driver_y_values, *driver_num_recs);

    for (i = 1; i < num_cdbs; i++) {

        uint64_t j = 0;
        uint64_t follower_num_recs = 0;

        cdb_record_t *follower_records = NULL;

        ret = _cdb_read_records(cdbs[i], request, &follower_num_recs, &follower_records);

        /* Just bail, free all allocations below and let the error bubble up */
        if (follower_num_recs != 0) {

            for (j = 0; j < *driver_num_recs; j++) {

                /* Check for out of bounds */
                if (j >= follower_num_recs) {
                    break;
                }

                follower_x_values[j] = follower_records[j].time;
                follower_y_values[j] = follower_records[j].value;
            }

            for (j = 0; j < *driver_num_recs; j++) {

                double yi = gsl_interp_eval(interp, follower_x_values, follower_y_values, driver_x_values[j], accel);

                if (isnormal(yi)) {
                    (*records)[j].value += yi;
                }
            }
        }

        ret = CDB_SUCCESS;

        free(follower_records);
    }

    if (ret == CDB_SUCCESS && *driver_num_recs > 0) {
        /* Compute all the statistics for this range */
        range->start_time = request->start;
        range->end_time   = request->end;

        _compute_statistics(range, driver_num_recs, *records);
    }

    free(driver_x_values);
    free(driver_y_values);
    free(follower_x_values);
    free(follower_y_values);

    gsl_interp_free(interp);
    gsl_interp_accel_free(accel);
    free(driver_records);

    return ret;
}
Пример #23
0
/* \fcnfh
   Interpolates 'src' into 'res' according to the new dimensions, first
   interpolates the second dimension and then the first. The result is
   added to whatever it is already existent in 'res'

   Return: 0 on success                                                 */
int
bicubicinterpolate(double **res, /* target array [t1][t2]  */
                   double **src, /* Source array [x1][x2]  */
                   double *x1,   /* Source first array     */
                   long nx1,     /* Size of x1             */
                   double *x2,   /* Source second array    */
                   long nx2,     /* Size of x2             */
                   double *t1,   /* Requested fisrt array  */
                   long nt1,     /* Size of t1             */
                   double *t2,   /* Requested second array */
                   long nt2){    /* Size of t2             */
  long i, j; /* Auxiliary for indices        */
  /* First and last values of source arrays: */
  double fx1=x1[0], fx2=x2[0], lx1=x1[nx1-1], lx2=x2[nx2-1];
  long lj=nt2, fj=0;
  long li=nt1, fi=0;

#ifndef _USE_GSL
#error We cannot spline interpolate without GSL to obtain CIA opacities
#endif

  /* Return if sampling regions don't match: */
  if(t1[0]>lx1 || t1[nt1-1]<fx1 || t2[0]>lx2 || t2[nt2-1]<fx2)
    return 0;

  /* Find indices where requested array values are within source boundaries
     (i.e., do not extrapolate):                                            */
  while(t1[fi++]<fx1);
  fi--;

  for(i=0; i<li; i++)
    if(t1[i]>lx1)
      li = i;

  while(t2[fj++]<fx2);
  fj--;

  for(j=0; j<lj; j++)
    if(t2[j]>lx2)
      lj = j;

  double **f2 = (double **)malloc(nt2    *sizeof(double *));
  f2[0]       = (double  *)malloc(nt2*nx1*sizeof(double  ));
  for(i=1; i<nt2; i++)
    f2[i] = f2[0] + i*nx1;
  gsl_interp_accel *acc;
  gsl_interp       *spl;

  for(i=0; i<nx1; i++){
    acc = gsl_interp_accel_alloc();
    spl = gsl_interp_alloc(gsl_interp_cspline, nx2);
    gsl_interp_init(spl, x2, src[i], nx2);
    for(j=fj; j<lj; j++)
      f2[j][i] = gsl_interp_eval(spl, x2, src[i], t2[j], acc);
    gsl_interp_free(spl);
    gsl_interp_accel_free(acc);
  }

  for(j=fj; j<lj; j++){
    acc = gsl_interp_accel_alloc();
    spl = gsl_interp_alloc(gsl_interp_cspline, nx1);
    gsl_interp_init(spl, x1, f2[j], nx1);
    for(i=fi; i<li; i++)
      res[i][j] += gsl_interp_eval(spl, x1, f2[j], t1[i], acc);
    gsl_interp_free(spl);
    gsl_interp_accel_free(acc);
  }

  free(f2[0]);
  free(f2);

  return 0;
}