double ANACalculatorCoplanarTriple::I(const double qx, const double qz, double & err)
{
	static double result, abserr;

	m_qx = qx;
	m_qz = qz;

	err = 0.0;
	/*here integration over x is performed*/
	for(size_t i = 0; i < m_sampling; ++i)
	{
		result = 0.0;
		abserr = 0.0;
		prepare(m_z1[i]);
		//gsl_integration_qawo_table_set(m_qawo_table, m_frequency, 1, GSL_INTEG_COSINE);
		//gsl_integration_qawf (&m_function, m_a, m_epsabs, m_limit, m_workspace, m_cyclic_workspace, m_qawo_table, &result, &abserr);

		gsl_integration_qagiu (&m_function, m_a, m_epsabs, 1.e-6, m_limit, m_workspace, &result, &abserr);
		m_integrand_values[i] = 2 * result * m_scale;
		err += 2 * abserr;

		//std::cout << m_z1[i] << "\t" << m_integrand_values[i] << std::endl;
	}

	/*here integration over z1 is performed*/
	//double gsl_interp_eval_integ (const gsl_interp * interp, const double xa[], const double ya[], double a, double b, gsl_interp_accel * acc)
	gsl_interp_init (m_interp, m_z1, m_integrand_values, m_sampling);
	result = gsl_interp_eval_integ (m_interp, m_z1, m_integrand_values, m_z1[0], m_z1[m_sampling-1], m_accel);

	return result;
}
Ejemplo n.º 2
0
double interpolate_integral(interp_info *interp, double x_lo, double x_hi) {
    double x_lo_interp;
    double x_hi_interp;
    double x_lo_tmp;
    double x_hi_tmp;
    double x_min;
    double x_max;
    double y_x_min;
    double y_x_max;
    double r_val;
    double alpha;
    int    flag_error = GBP_FALSE;

    x_min   = ((interp_info *)interp)->x[0];
    x_max   = ((interp_info *)interp)->x[((interp_info *)interp)->n - 1];
    y_x_min = ((interp_info *)interp)->y[0];
    y_x_max = ((interp_info *)interp)->y[((interp_info *)interp)->n - 1];

    r_val       = 0.;
    x_lo_interp = x_lo;
    x_hi_interp = x_hi;

    if(x_hi > x_lo) {
        // Extrapolate integral to low-x assuming dI prop. to x^alpha
        if(x_lo < x_min) {
            x_lo_tmp = x_lo;
            x_hi_tmp = GBP_MIN(x_hi, x_min);
            alpha    = interpolate_derivative(interp, ((interp_info *)interp)->x[0]);
            if(alpha < -1. && x_lo_tmp * x_hi_tmp == 0.) {
                fprintf(stderr, "ERROR: integration extrapolation to low-x is divergent! (alpha=%lf)\n", alpha);
                flag_error = GBP_TRUE;
            } else
                r_val += (y_x_min / (alpha + 1.)) * (pow(x_hi_tmp / x_min, alpha + 1.) - pow(x_lo_tmp / x_min, alpha + 1.));
            x_lo_interp = x_min;
        }

        // Extrapolate integral to high-x assuming dI prop. to x^alpha
        if(x_hi > x_max) {
            x_lo_tmp = GBP_MAX(x_max, x_lo);
            x_hi_tmp = x_hi;
            alpha    = interpolate_derivative(interp, ((interp_info *)interp)->x[((interp_info *)interp)->n - 1]);
            if(alpha < 0. && x_lo_tmp * x_hi_tmp == 0.) {
                fprintf(stderr, "ERROR: integration extrapolation to high-x is divergent! (alpha=%lf)\n", alpha);
                flag_error = GBP_TRUE;
            } else
                r_val += (y_x_min / (alpha + 1.)) * (pow(x_hi_tmp / x_min, alpha + 1.) - pow(x_lo_tmp / x_min, alpha + 1.));
            x_hi_interp = x_max;
        }

        r_val += gsl_interp_eval_integ(((interp_info *)interp)->interp,
                                       ((interp_info *)interp)->x,
                                       ((interp_info *)interp)->y,
                                       x_lo_interp,
                                       x_hi_interp,
                                       ((interp_info *)interp)->accel);
    }
    return (r_val);
}
Ejemplo n.º 3
0
double
gsl_spline_eval_integ (const gsl_spline * spline,
                       double a, double b,
                       gsl_interp_accel * acc)
{
  return gsl_interp_eval_integ (spline->interp, 
                                spline->x, spline->y,
                                a, b, acc);
}
Ejemplo n.º 4
0
static VALUE rb_gsl_interp_eval_integ(VALUE obj, VALUE xxa, VALUE yya, 
				      VALUE aa, VALUE bb)
{
  rb_gsl_interp *rgi = NULL;
  double *ptr1 = NULL, *ptr2 = NULL;
  size_t size, stridex, stridey;
  double a, b;
  Need_Float(aa); Need_Float(bb);
  Data_Get_Struct(obj, rb_gsl_interp, rgi);
  ptr1 = get_vector_ptr(xxa, &stridex, &size);
  ptr2 = get_vector_ptr(yya, &stridey, &size);
  a = NUM2DBL(aa);
  b = NUM2DBL(bb);
  return rb_float_new(gsl_interp_eval_integ(rgi->p, ptr1, ptr2, a, b, rgi->a));
}
Ejemplo n.º 5
0
pdf_redshift::pdf_redshift(std::valarray< double >& zSampling, std::valarray< double >& pdz)
{
  
  // Allocate arrays to store pdf samples
  nPoints = zSampling.size();
  x = (double*) malloc(sizeof(double) * nPoints);
  y = (double*) malloc(sizeof(double) * nPoints);
  
  // Copy array data
  for(int i =0; i < nPoints; i++){
      x[i] = zSampling[i];
      y[i] = pdz[i];
  }
  
  interpolator = gsl_interp_alloc(gsl_interp_cspline, nPoints);
  accelerator = gsl_interp_accel_alloc();
  
  gsl_interp_init(interpolator, x, y, nPoints);
  
  // Compute normalization factor
  normalizationFactor = 1.0 / gsl_interp_eval_integ(interpolator, x, y, x[0], x[nPoints-1], accelerator);
}
Ejemplo n.º 6
0
void gamma_spline_reset (GammaSpline *gs, GList * const sd, int mp, int np, gboolean sort) {
	int q=0;
	
	int NB = model->total_bands;
	
	int m,n;
	
	GList * iter = sd;
	const int N = g_list_length(iter);
    
	MatrixElement *firstme = (MatrixElement *) iter->data;
	
	size_t ind[NB];
	
	if (sort) {
    	gsl_sort_index (ind, firstme->energies, 1, NB);
    	m=ind[mp];
    	n=ind[np];  // this breaks the 14 band model!
    }
    else {
    	m=mp;
    	n=np;
    }
		
	double *en = double_array_calloc(N);
	
    while (iter) {
        MatrixElement *me = (MatrixElement *) iter->data;
        gs->k[q]=me->kc;
        
        en[q]=(me->energies[n] - me->energies[m])*3e5/1240.7;
        
        gs->Wxr[q]=creal(me->Wx[m+n*NB]);
        gs->Wxi[q]=cimag(me->Wx[m+n*NB]);
        
        gs->Wyr[q]=creal(me->Wy[m+n*NB]);
        gs->Wyi[q]=cimag(me->Wy[m+n*NB]);
        
        gs->Wzr[q]=creal(me->Wz[m+n*NB]);
        gs->Wzi[q]=cimag(me->Wz[m+n*NB]);
        
        iter=g_list_next(iter);
        q++;
    }
	
    gsl_interp * en_spline;
    gsl_interp_accel * en_accel;
    
  	en_spline = gsl_interp_alloc(gsl_interp_akima,N);
    en_accel = gsl_interp_accel_alloc();
    
	q=gsl_interp_init(en_spline,gs->k,en,N);
    gsl_interp_accel_reset (en_accel);
    
    if (m!=n) {
        gs->phi[0]=0;
        for (q=1;q<N;q++) {
            gs->phi[q]=gs->phi[q-1]+2*M_PI*gsl_interp_eval_integ (en_spline, gs->k, en, gs->k[q-1], gs->k[q], en_accel);
        }
    }
    else {
        for (q=0;q<N;q++) {
            gs->phi[q]=0;
        }
    }
    
    d_free(en);
    
    gsl_interp_free(en_spline);
    gsl_interp_accel_free(en_accel);
	
	q=gsl_interp_init(gs->phi_spline,gs->k,gs->phi,N);
    gsl_interp_accel_reset (gs->phi_accel);
	
	q=gsl_interp_init(gs->wx_spline_re,gs->k,gs->Wxr,N);
    gsl_interp_accel_reset (gs->w_accel);
    
	q=gsl_interp_init(gs->wx_spline_im,gs->k,gs->Wxi,N);
	q=gsl_interp_init(gs->wy_spline_re,gs->k,gs->Wyr,N);
	q=gsl_interp_init(gs->wy_spline_im,gs->k,gs->Wyi,N);
	q=gsl_interp_init(gs->wz_spline_re,gs->k,gs->Wzr,N);
	q=gsl_interp_init(gs->wz_spline_im,gs->k,gs->Wzi,N);
}
Ejemplo n.º 7
0
/* \fcnfh
   Computes optical depth at a given impact parameter, note that b needs
   to be given in units of 'rad' and the result needs to be multiplied by
   the units 'rad' to be real.
   There is no ray bending, refr=constant.
   It can take nrad values of 1 or bigger. However, if 2 is given then
   'ex' and 'rad' need to have a referenceable element at position
   -1; i.e. rad[-1] and ex[-1] need to exist.

   @returns $\frac{tau}{units_{rad}}$ returns optical depth divided by units
                                      of 'rad'
*/
static  PREC_RES
totaltau1(PREC_RES b,		/* impact parameter */
	  PREC_RES *rad,	/* Equispaced radius array */
	  PREC_RES refr,	/* refractivity index */
	  PREC_RES *ex,		/* extinction[rad] */
	  long nrad)		/* number of radii elements */
{
  int rs;
  int i;
  PREC_RES res;
  PREC_RES x3[3],r3[3];

  //Look for closest approach radius
  PREC_RES r0=b/refr;

  //get bin value 'rs' such that r0 is between rad[rs] inclusive
  //and rad[rs+1] exclusive.
  //If we are looking at the outmost layer, then return
  if((rs=binsearch(rad,0,nrad-1,r0))==-5)
    return 0;
  //If some other error occurred
  else if(rs<0)
    transiterror(TERR_CRITICAL,
		 "Closest approach value(%g) is outside sampled radius\n"
		 "range(%g - %g)\n"
		 ,r0,rad[0],rad[nrad-1]);
  //advance the extinction and radius arrays such that the zeroeth
  //element now is the closest sample to the minimum approach from below
  //it.
  rad+=rs;
  ex+=rs;
  nrad-=rs;

  //By parabolic fitting, interpolate the value of extinction at the
  //radius of minimum approach and store it in the sample that
  //corresponded to the closest from below. Store such value and radius,
  //which are to be replaced before returning (\lin{tmpex})
  const PREC_RES tmpex=*ex;
  const PREC_RES tmprad=*rad;
  if(nrad==2) *ex=interp_parab(rad-1,ex-1,r0);
  else *ex=interp_parab(rad,ex,r0);
  *rad=r0;
  if(nrad==2){
    x3[0]=ex[0];
    x3[2]=ex[1];
    x3[1]=(ex[1]+ex[0])/2.0;
    r3[0]=rad[0];
    r3[2]=rad[1];
    r3[1]=(rad[0]+rad[1])/2.0;
    *rad=tmprad;
    *ex=tmpex;
    rad=r3;
    ex=x3;
    nrad++;
  }
  const PREC_RES dr=rad[1]-rad[0];

  //Now convert to s spacing, i.e. distance along the path. Radius needs
  //to be equispaced.
  PREC_RES s[nrad];
  const PREC_RES Dr=rad[2]-rad[1];
  const PREC_RES cte=dr*(dr + 2*r0);
  s[0]=0;

  for(i=1 ; i<nrad ; i++)
    s[i]=sqrt(cte + (i-1)*Dr*(2.0*(r0+dr) + (i-1)*Dr) );

  //Integrate!\par
  //Use spline if GSL is available along with at least 3 points
#ifdef _USE_GSL
  gsl_interp_accel *acc = gsl_interp_accel_alloc ();
  gsl_interp *spl=gsl_interp_alloc(gsl_interp_cspline,nrad);
  gsl_interp_init(spl,s,ex,nrad);
  res=gsl_interp_eval_integ(spl,s,ex,0,s[nrad-1],acc);
  gsl_interp_free(spl);
  gsl_interp_accel_free (acc);
#else
#error non equispaced integration is not implemented without GSL
#endif /* _USE_GSL */

  //replace original value of extinction
  //\linelabel{tmpex}
  *ex=tmpex;
  *rad=tmprad;

  //return
  return 2*(res);
}
Ejemplo n.º 8
0
/* \fcnfh
   Computes most basic modulation scheme, obtained when there is no limb
   darkening or emitted flux.

   @returns modulation obtained
*/
static PREC_RES
modulation1 (PREC_RES *tau,
	     long last,		/* Index of the last poisition it has to
				   be at least 1 */
	     double toomuch,
	     prop_samp *ip,	/* Order is descending */
	     struct geometry *sg)
{
  //general variables
  PREC_RES res;
  double srad=sg->starrad*sg->starradfct;

  //Impact parameter variables
  long ipn=ip->n;
  long ipn1=ipn-1;
  long i;

  const PREC_RES maxtau=tau[last]>toomuch?tau[last]:toomuch;

  PREC_RES rinteg[ipn],ipv[ipn];

  //this function calculates 1 minus the ratio of in-transit over out-of-transit
  //expresion for the simplest case, which is given by (INVALID
  //EXPRESSION FOLLOWING!!)
  //\[
  //M_{\lambda}^{(0)}=
  //\frac{1}{\pi R_M^2}\int_{R<R_M}\ee^{-\tau( b,\xi)} R \dd R\dd\phi
  //\]\par
  //Let's integrate; for each of the planet's layer starting from the
  //outermost until the closest layer
  for(i=0;i<=last;i++){
    ipv[ipn1-i] = ip->v[i] * ip->fct;

    rinteg[ipn1-i] = exp(-tau[i]) * ipv[ipn1-i];
  }
  //fill one more lower part bin with 0. Only two to have a nice ending
  //spline and not unnecessary values.
  last+=1;
  if(last>ipn1) last=ipn1;
  for(;i<=last;i++){
    ipv[ipn1-i]    = ip->v[i] * ip->fct;
    rinteg[ipn1-i] = 0;
  }

  //increment last to represent number of elements now, check that we
  //have enough.
  last++;
  if(last<3)
    transiterror(TERR_CRITICAL,
		 "Condition failed, less than 3 items (only %i) for radial\n"
		 "integration.\n"
		 ,last);

  //integrate in radii
#ifdef _USE_GSL
  gsl_interp_accel *acc = gsl_interp_accel_alloc ();
  gsl_interp *spl=gsl_interp_alloc( gsl_interp_cspline, last );
  gsl_interp_init( spl, ipv+ipn-last, rinteg+ipn-last, last );
  res = gsl_interp_eval_integ( spl, ipv+ipn-last, rinteg+ipn-last,
			       ipv[ipn-last], ipv[ipn1], acc );
  gsl_interp_free(spl);
  gsl_interp_accel_free (acc);

  //or err without GSL
#else
# error computation of modulation() without GSL is not implemented
#endif

  /* TD: Add real unblocked area of the star, considering geometry */
  //substract the total area blocked by the planet. This is from the
  //following
  //\begin{align}
  //1-M=&1-\frac{\int_0^{r_p}\int\ee^{-\tau}\dd \theta r\dd r
  //             +\int_{r_p}^{R_s}\dd A}
  //            {\pi R_s^2}\\%
  //   =&-\frac{\int_0^{r_p}\int\ee^{-\tau}\dd \theta r\dd r
  //           +Area_{planet}}
  //          {\pi R_s^2}
  //   =&-\frac{2\int_0^{r_p}\ee^{-\tau}r\dd r
  //           +r_p^2}
  //          {\pi R_s^2}
  //\end{align}
  res = ipv[ipn1] * ipv[ipn1] - 2.0 * res ;

  //If the planet is going to be transparent with its maximum optical
  //depth given by toomuch then
  if(sg->transpplanet)
    res -= exp(-maxtau) * ipv[ipn-last] * ipv[ipn-last];

  //normalize by the planet
  res *= 1.0 / srad / srad;

  return res;
}
Ejemplo n.º 9
0
/* DEF */
static PREC_RES
eclipse_intens(struct transit *tr,  /* Transit structure                    */
               PREC_RES *tau,       /* Optical depth array                  */
               PREC_RES w,          /* Current wavenumber value             */
               long last,           /* Index where tau == toomuch           */
               double toomuch,      /* Maximum optical depth calculated     */
               prop_samp *rad){     /* Radius array                         */
  /* FINDME: toomuch is not needed as a parameter                           */

  /* General variables:                                                     */
  PREC_RES res;                  /* Result                                  */
  PREC_ATM *temp = tr->atm.t;    /* Temperatures                            */
 
  PREC_RES angle = tr->angles[tr->angleIndex] * DEGREES;   

  /* Takes sampling properties for wavenumber from tr:                      */
  prop_samp *wn = &tr->wns; 
  /* Wavenumber units factor to cgs:                                        */
  double wfct  = wn->fct; 

  /* Radius parameter variables:                                            */
  long rnn  = rad->n;
  long i;

  /* Blackbody function at each layer:                                      */
  PREC_RES B[rnn];

  /* Integration parts:                                                     */
  PREC_RES tauInteg[rnn],  /* Integrand function                            */
           tauIV[rnn];     /* Tau integration variable                      */

  /* Integrate for each of the planet's layer starting from the           
     outermost until the closest layer. 
     The order is opposite since tau starts from the top and 
     radius array starts from the bottom.                                   */

  /* Planck function (erg/s/sr/cm) for wavenumbers:
        B_\nu = 2 h {\bar\nu}^3 c^2 \frac{1}
                {\exp(\frac{h \bar \nu c}{k_B T})-1}                        */
  for(i=0; i <= last; i++){
    tauIV[i] = tau[i];
    B[i] =  (2.0 * H * w * w * w * wfct * wfct * wfct * LS * LS)
          / (exp(H * w * wfct * LS / (KB * temp[rnn-1-i])) - 1.0);
    tauInteg[i] = B[i] * exp(-tau[i]/ cos(angle));
  }

  /* Added 0 at the end when tau reach toomuch, so the spline looks nice    */
  /* Add all other layers to be 0.                                          */
  for(; i<rnn; i++){
    tauInteg[i] = 0;
    /* Geometric progression is used to provide enough elements 
       for integral to work. It does not change the final outcome/result.   */
    tauIV[i] = tauIV[i-1] + 1;
   }

  /* Adding additional 0 layer, plus the last represent number of elements 
     is -1, so we need to add one more. 2 in total.                         */
  last += 2;

  /* If atmosphere is transparent, and at last level tau has not reached 
     tau.toomuch, last is set to max number of layers (rnn, instead of rnn-1
     because we added 2 on the previous step). The code requests never
     to go over it.                                                         */
  if(last > rnn)    
    last = rnn;

  /* Checks if we have enough radii to do spline, at least 3:               */
  if(last < 3)
    transiterror(TERR_CRITICAL, "Less than 3 items (%i given) for radial "
                                "integration.\n", last);

  /* Integrate along tau up to tau = toomuch:                               */
#ifdef _USE_GSL
  gsl_interp_accel *acc = gsl_interp_accel_alloc();
  gsl_interp *spl       = gsl_interp_alloc(gsl_interp_cspline, last);
  gsl_interp_init(spl, tauIV, tauInteg, last);
  res = gsl_interp_eval_integ(spl, tauIV, tauInteg,
                               tauIV[0], tauIV[last-1], acc);
  gsl_interp_free(spl);
  gsl_interp_accel_free (acc);
#else
# error computation of modulation() without GSL is not implemented
#endif

  /* GSL is stupid. I will use a trapezoidal rule for integration instead
     (when I want to run the code in safety mode):                          */
  //res = integ_trapz(tauIV, tauInteg, last);

  //if (fabs(w-2877.00) <= 0.5){
  //  transitprint(1, 2, "\nI(w=%.10g) = %.10g\n", w, res);
  //  for (i=0; i<last; i++)
  //    transitprint(1, 2, "  tau: %.10e   int:%.10e\n", tauIV[i], tauInteg[i]);
  //  double res2 = integ_trapz(tauIV, tauInteg, last-1);
  //  transitprint(1,2, "Trapezoidal integration: %.10e\n", res2);
  //}

  //if (res < 0){
  //if (fabs(w-1844.59) <= 0.005){
  //  double res2 = integ_trapz(tauIV, tauInteg, last-1);
  //  transitprint(1,2, "Trapezoidal integration: %.10e\n", res2);
  //  transitprint(1, 2, "\nI(w=%.10g) = %.10g\n", w, res);
  //  for (i=0; i<last; i++)
  //    transitprint(1, 2, "  tau: %.10e   int:%.10g\n", tauIV[i], tauInteg[i]);
  //}
  return res/cos(angle);
}
Ejemplo n.º 10
0
int main()
{
    std::ifstream ifs;
    ifs.open("halo_mod.dat", std::ifstream::in);
    
    double E_p_array[1000];
    double prob_array[1000];
    
    int i = 0;
    
    while(ifs.good() && i < 1000)
    {
        double E_p;
        double prob;
        ifs >> E_p >> prob;
        
        if(!ifs.good())
        {
            break;
        }
        
        if(i > 0 && E_p <= E_p_array[i-1])
        {
            continue;
        }
        
        E_p_array[i] = E_p;
        prob_array[i] = prob;
        
        i++;
        
    }
    
    std::cout << i << std::endl;
    
    gsl_interp* interp = gsl_interp_alloc(gsl_interp_linear, i);
    
    double E_p_min = E_p_array[0];
    double E_p_max = E_p_array[i-1];
    
    gsl_interp_init(interp, E_p_array, prob_array, i);
    
    gsl_interp_accel* accel = gsl_interp_accel_alloc();
    
    double integral_value = gsl_interp_eval_integ(interp, E_p_array, prob_array, E_p_min, E_p_max, accel);
    
    std::cout << integral_value << std::endl;

    for(int j = 0; j < i; j++)
    {
        prob_array[i] = prob_array[i] / integral_value;
    }
    
    gsl_integration_workspace* w;
    
    w = gsl_integration_workspace_alloc(10000);
    
    param_struct params;
    params.N = i;
    params.interp = interp;
    params.accel = accel;
    params.E_p_array = E_p_array;
    params.prob_array = prob_array;
    
    params.E_p_min = E_p_min;
    params.E_p_max = E_p_max;
    
    gsl_function f;
    f.function = &integral;
        
    f.params = &params;
    
    /*for(int j = 0; j < i; j++)
    {
        double result;
        double error;
        
        double E_p = E_p_array[j];
        
        params.E_p = E_p;
        
        gsl_integration_qag(&f, -3.0 * sigma, 3.0 * sigma, 1e-8, 1e-8, 10000, GSL_INTEG_GAUSS51, w, &result, &error);
        
        double prob = result * 0.02893 + (1.0 - 0.02893) * gaussian(E_p - 7.878);
        
        std::cout << E_p << " " << prob << std::endl;
        
    }*/

    gsl_integration_workspace_free(w);

    gsl_interp_accel_free(accel);
    gsl_interp_free(interp);
    
    
    return 0;
}
static LALSimNeutronStarEOS *eos_alloc_tabular(double *pdat, double *edat,
    size_t ndat)
{
    LALSimNeutronStarEOS *eos;
    LALSimNeutronStarEOSDataTabular *data;
    size_t i;
    double *hdat;
    double *rhodat;
    double integrand_im1, integrand_i, integral;

    eos = LALCalloc(1, sizeof(*eos));
    data = LALCalloc(1, sizeof(*data));

    eos->datatype = LALSIM_NEUTRON_STAR_EOS_DATA_TYPE_TABULAR;
    eos->data.tabular = data;

    /* setup function pointers */
    eos->free = eos_free_tabular;
    eos->e_of_p = eos_e_of_p_tabular;
    eos->h_of_p = eos_h_of_p_tabular;
    eos->e_of_h = eos_e_of_h_tabular;
    eos->p_of_h = eos_p_of_h_tabular;
    eos->rho_of_h = eos_rho_of_h_tabular;
    eos->dedp_of_p = eos_dedp_of_p_tabular;
    eos->v_of_h = eos_v_of_h_tabular;

    /* compute pseudo-enthalpy h from dhdp */
    /* Integrate in log space: 
       dhdp = 1 / [e(p) + p]
       h(p) = h(p0) + \int_p0^p dhdp dp
       h(p) = h(p0) + \int_ln(p0)^ln(p) exp[ln(p) + ln(dhdp)] dln(p)
    */
    double * integrand;
    double * log_pdat;
    log_pdat = XLALCalloc(ndat-1, sizeof(*log_pdat));
    integrand = LALMalloc((ndat-1) * sizeof(*integrand));
    for (i = 0; i < ndat-1; ++i) {
        log_pdat[i] = log(pdat[i+1]);
        integrand[i] = exp(log_pdat[i] + log(1.0 / (edat[i+1] + pdat[i+1])));
    }

    gsl_interp_accel * dhdp_of_p_acc_temp = gsl_interp_accel_alloc();
    gsl_interp * dhdp_of_p_interp_temp = gsl_interp_alloc(gsl_interp_linear, ndat-1);
    gsl_interp_init(dhdp_of_p_interp_temp, log_pdat, integrand, ndat-1);

    hdat = LALMalloc(ndat * sizeof(*hdat));
    hdat[0] = 0.0;
    // Do first point by hand
    hdat[1] = hdat[0] + 0.5 * (1./(pdat[1]+edat[1])) * (pdat[1] - pdat[0]);
    for (i = 1; i < ndat-1; ++i) {
        hdat[i+1] = gsl_interp_eval_integ(dhdp_of_p_interp_temp, log_pdat, integrand,
          log_pdat[0], log_pdat[i], dhdp_of_p_acc_temp);
    }
    gsl_interp_free(dhdp_of_p_interp_temp);
    gsl_interp_accel_free(dhdp_of_p_acc_temp);

    LALFree(log_pdat);
    LALFree(integrand);

    /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
    /*             CALCULATION OF RHO CURRENTLY RETURNS GARBAGE               */
    /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
    /* compute rest-mass density by integrating (trapezoid rule) */
    /* rho_i = rho_{i-1} exp(int_{e_{i-1}}^{e_i} de/(e+p)) */
    rhodat = LALMalloc(ndat * sizeof(*hdat));
    rhodat[0] = 0.0;
    rhodat[1] = edat[1];        /* essentially the same at low density */
    integrand_im1 = 1.0 / (edat[1] + pdat[1]);
    for (i = 2; i < ndat; i++) {
        integrand_i = 1.0 / (edat[i] + pdat[i]);
        integral =
            0.5 * (integrand_im1 + integrand_i) * (edat[i] - edat[i - 1]);
        integrand_im1 = integrand_i;
        rhodat[i] = rhodat[i - 1] * exp(integral);
    }

    data->hdat = hdat;
    data->pdat = pdat;
    data->edat = edat;
    data->rhodat = rhodat;
    data->ndat = ndat;

    eos->pmax = data->pdat[ndat - 1];
    eos->hmax = data->hdat[ndat - 1];

    /* setup interpolation tables */

    data->e_of_p_acc = gsl_interp_accel_alloc();
    data->h_of_p_acc = gsl_interp_accel_alloc();
    data->e_of_h_acc = gsl_interp_accel_alloc();
    data->p_of_h_acc = gsl_interp_accel_alloc();
    data->rho_of_h_acc = gsl_interp_accel_alloc();

    data->e_of_p_interp = gsl_interp_alloc(gsl_interp_cspline, ndat);
    data->h_of_p_interp = gsl_interp_alloc(gsl_interp_cspline, ndat);
    data->e_of_h_interp = gsl_interp_alloc(gsl_interp_cspline, ndat);
    data->p_of_h_interp = gsl_interp_alloc(gsl_interp_cspline, ndat);
    data->rho_of_h_interp = gsl_interp_alloc(gsl_interp_cspline, ndat);

    gsl_interp_init(data->e_of_p_interp, pdat, edat, ndat);
    gsl_interp_init(data->h_of_p_interp, pdat, hdat, ndat);
    gsl_interp_init(data->e_of_h_interp, hdat, edat, ndat);
    gsl_interp_init(data->p_of_h_interp, hdat, pdat, ndat);
    gsl_interp_init(data->rho_of_h_interp, hdat, rhodat, ndat);

    eos->hMinAcausal =
        eos_min_acausal_pseudo_enthalpy_tabular(eos->hmax, eos);

//    printf("%e\n", XLALSimNeutronStarEOSEnergyDensityOfPressureGeometerized(eos->pmax, eos));
//    
//    printf("datatype = %d\n", eos->datatype);
//    printf("pmax = %e\n", eos->pmax);
//    printf("hmax = %e\n", eos->hmax);
//    printf("hMinAcausal = %e\n", eos->hMinAcausal);

    return eos;
}