Exemple #1
0
static VALUE rb_gsl_odeiv_step_apply(int argc, VALUE *argv, VALUE obj)
{
  gsl_odeiv_step *s = NULL;
  gsl_odeiv_system *sys = NULL;
  gsl_vector *y = NULL, *yerr = NULL;
  gsl_vector *vtmp1 = NULL, *vtmp2 = NULL;
  double *dydt_in = NULL, *dydt_out = NULL;
  double t, h;
  switch (argc) {
  case 5:
    break;
  case 7:
    if (VECTOR_P(argv[5])) {
      Data_Get_Struct(argv[5], gsl_vector, vtmp2);
      if (vtmp2) dydt_out = vtmp2->data;
    }
    /* no break */
  case 6:
    if (VECTOR_P(argv[4])) {
      Data_Get_Struct(argv[4], gsl_vector, vtmp1);
      if (vtmp1) dydt_in = vtmp1->data;
    }
    break;
  default:
    rb_raise(rb_eArgError, "wrong number of arguments (%d for 5, 6 or 7)", argc);
    break;
  }
  Need_Float(argv[0]); Need_Float(argv[1]);
  CHECK_VECTOR(argv[2]); CHECK_VECTOR(argv[3]);
  CHECK_SYSTEM(argv[argc-1]);
  Data_Get_Struct(obj, gsl_odeiv_step, s);
  t = NUM2DBL(argv[0]);
  h = NUM2DBL(argv[1]);
  Data_Get_Struct(argv[2], gsl_vector, y);
  Data_Get_Struct(argv[3], gsl_vector, yerr);
  Data_Get_Struct(argv[argc-1], gsl_odeiv_system, sys);
  return INT2FIX(gsl_odeiv_step_apply(s, t, h, y->data, yerr->data, 
				      dydt_in, dydt_out, sys));
}
Exemple #2
0
CAMLprim value ml_gsl_odeiv_step_apply(value step, value t, value h, value y,
			      value yerr, value odydt_in, value odydt_out, 
			      value syst)
{
  CAMLparam5(step, syst, y, yerr, odydt_out);
  LOCALARRAY(double, y_copy,  Double_array_length(y)); 
  LOCALARRAY(double, yerr_copy, Double_array_length(yerr)); 
  size_t len_dydt_in = 
    odydt_in == Val_none ? 0 : Double_array_length(Unoption(odydt_in)) ;
  size_t len_dydt_out = 
    odydt_out == Val_none ? 0 : Double_array_length(Unoption(odydt_out)) ;
  LOCALARRAY(double, dydt_in, len_dydt_in); 
  LOCALARRAY(double, dydt_out, len_dydt_out); 
  int status;

  if(len_dydt_in)
    memcpy(dydt_in, Double_array_val(Unoption(odydt_in)), Bosize_val(Unoption(odydt_in)));
  memcpy(y_copy, Double_array_val(y), Bosize_val(y));
  memcpy(yerr_copy, Double_array_val(yerr), Bosize_val(yerr));

  status = gsl_odeiv_step_apply(ODEIV_STEP_VAL(step), 
				Double_val(t), Double_val(h),
				y_copy, yerr_copy, 
				len_dydt_in  ? dydt_in : NULL,
				len_dydt_out ? dydt_out : NULL,
				ODEIV_SYSTEM_VAL(syst));
  /* GSL does not call the error handler for this function */
  if (status)
    GSL_ERROR_VAL ("gsl_odeiv_step_apply", status, Val_unit);

  memcpy(Double_array_val(y), y_copy, sizeof(y_copy));
  memcpy(Double_array_val(yerr), yerr_copy, sizeof(yerr_copy));
  if(len_dydt_out)
    memcpy(Double_array_val(Unoption(odydt_out)), dydt_out, Bosize_val(Unoption(odydt_out)));

  CAMLreturn(Val_unit);
}
void
test_odeiv_stepper (const gsl_odeiv_step_type *T, const gsl_odeiv_system *sys,
		    const double h, const double t, const char desc[],
		    const double ystart[], const double yfin[], 
		    const double relerr)
{
  /* tests stepper T with one fixed length step advance of system sys
     and compares with given values yfin
  */

  double y[MAXEQ] = {0.0};
  double yerr[MAXEQ] = {0.0};
  size_t ne = sys->dimension;
  size_t i;

  gsl_odeiv_step *step = gsl_odeiv_step_alloc (T, ne);

  DBL_MEMCPY (y, ystart, MAXEQ);

  {
    int s = gsl_odeiv_step_apply (step, t, h, y, yerr, 0, 0, sys);
    if (s != GSL_SUCCESS)
      {
	gsl_test(s, "test_odeiv_stepper: %s step_apply returned %d", desc, s);
      }
  }
  
  for (i = 0; i < ne; i++)
    { 
      gsl_test_rel (y[i], yfin[i], relerr, 
		    "%s %s step(%d)",
		    gsl_odeiv_step_name (step), desc,i);
    }

  gsl_odeiv_step_free (step);
}
 inline void do_step( const double dt )
 {
     gsl_odeiv_step_apply ( m_s , m_t , dt , m_x , m_x_err , 0 , 0 , &m_sys );
     //m_t += dt;
 }
Exemple #5
0
/* Wrappers for the evaluation of the system */
static PyObject *
PyGSL_odeiv_step_apply(PyGSL_odeiv_step *self, PyObject *args)
{
    PyObject *result = NULL;
    PyObject *y0_o = NULL, *dydt_in_o = NULL;
    PyArrayObject *volatile y0 = NULL, * volatile yerr = NULL, 
	 *volatile dydt_in = NULL, *volatile dydt_out = NULL,
	 *volatile yout = NULL;

    double t=0, h=0, *volatile dydt_in_d;
    int dimension, r, flag;


    FUNC_MESS_BEGIN();
    assert(PyGSL_ODEIV_STEP_Check(self));
    if(! PyArg_ParseTuple(args, "ddOOO", &t, &h, &y0_o,  &dydt_in_o)){
      return NULL;
    }


    dimension = self->system.dimension;
    y0 = PyGSL_PyArray_PREPARE_gsl_vector_view(y0_o, PyArray_DOUBLE, 1, dimension, 1, NULL);
    if(y0 == NULL) goto fail;


    if (Py_None == dydt_in_o){
	 dydt_in_d = NULL;
    }else{
	 dydt_in = PyGSL_PyArray_PREPARE_gsl_vector_view(dydt_in_o, PyArray_DOUBLE, 1, dimension, 2, NULL);
	 if(dydt_in == NULL) goto fail;
	 dydt_in_d = (double *) dydt_in->data;
    }


    dydt_out = (PyArrayObject *)  PyArray_FromDims(1, &dimension, PyArray_DOUBLE);
    if (dydt_out == NULL) goto fail;

    yerr = (PyArrayObject *) PyArray_FromDims(1, &dimension, PyArray_DOUBLE);
    if(yerr == NULL) goto fail;


    yout = (PyArrayObject *) PyArray_CopyFromObject((PyObject * ) y0, PyArray_DOUBLE, 1, 1);
    if(yout == NULL) goto fail;


    if((flag=setjmp(self->buffer)) == 0){
	  FUNC_MESS("\t\t Setting Jmp Buffer");
    } else {
	  FUNC_MESS("\t\t Returning from Jmp Buffer");
	  goto fail;
    }
    
    r = gsl_odeiv_step_apply(self->step, t, h, 
			     (double *) yout->data, 
			     (double *) yerr->data, 
			     dydt_in_d, 
			     (double *) dydt_out->data, 
			     &(self->system));
    if (GSL_SUCCESS != r){
	PyErr_SetString(PyExc_TypeError, "Error While evaluating gsl_odeiv");
      goto fail;
    }

    FUNC_MESS("    Returnlist create ");
    assert(yout != NULL);
    assert(yerr != NULL);
    assert(dydt_out != NULL);

    result = Py_BuildValue("(OOO)", yout, yerr, dydt_out);

    FUNC_MESS("    Memory free ");
    /* Deleting the arrays */    
    Py_DECREF(y0);           y0 = NULL;
    Py_DECREF(yout);         yout = NULL;
    Py_DECREF(yerr);         yerr = NULL;
    Py_DECREF(dydt_out);     dydt_out = NULL;
    /* This array does not need to exist ... */
    Py_XDECREF(dydt_in);	 dydt_in=NULL;
    
    FUNC_MESS_END();
    return result;

    fail:
    FUNC_MESS("IN Fail");
    Py_XDECREF(y0);
    Py_XDECREF(yout);
    Py_XDECREF(yerr);
    Py_XDECREF(dydt_in);
    Py_XDECREF(dydt_out);
    FUNC_MESS("IN Fail End");   
    return NULL;
}
Exemple #6
0
/* Evolution framework method.
 *
 * Uses an adaptive step control object
 */
int
gsl_odeiv_evolve_apply (gsl_odeiv_evolve * e,
                        gsl_odeiv_control * con,
                        gsl_odeiv_step * step,
                        const gsl_odeiv_system * dydt,
                        double *t, double t1, double *h, double y[])
{
  const double t0 = *t;
  double h0 = *h;
  int step_status;
  int final_step = 0;
  double dt = t1 - t0;  /* remaining time, possibly less than h */

  if (e->dimension != step->dimension)
    {
      GSL_ERROR ("step dimension must match evolution size", GSL_EINVAL);
    }

  if ((dt < 0.0 && h0 > 0.0) || (dt > 0.0 && h0 < 0.0))
    {
      GSL_ERROR ("step direction must match interval direction", GSL_EINVAL);
    }

  /* No need to copy if we cannot control the step size. */

  if (con != NULL)
    {
      DBL_MEMCPY (e->y0, y, e->dimension);
    }

  /* Calculate initial dydt once if the method can benefit. */

  if (step->type->can_use_dydt_in)
    {
      int status = GSL_ODEIV_FN_EVAL (dydt, t0, y, e->dydt_in);

      if (status) 
        {
          return status;
        }
    }

try_step:
    
  if ((dt >= 0.0 && h0 > dt) || (dt < 0.0 && h0 < dt))
    {
      h0 = dt;
      final_step = 1;
    }
  else
    {
      final_step = 0;
    }

  if (step->type->can_use_dydt_in)
    {
      step_status =
        gsl_odeiv_step_apply (step, t0, h0, y, e->yerr, e->dydt_in,
                              e->dydt_out, dydt);
    }
  else
    {
      step_status =
        gsl_odeiv_step_apply (step, t0, h0, y, e->yerr, NULL, e->dydt_out,
                              dydt);
    }

  /* Check for stepper internal failure */

  if (step_status != GSL_SUCCESS) 
    {
      *h = h0;  /* notify user of step-size which caused the failure */
      return step_status;
    }

  e->count++;
  e->last_step = h0;

  if (final_step)
    {
      *t = t1;
    }
  else
    {
      *t = t0 + h0;
    }

  if (con != NULL)
    {
      /* Check error and attempt to adjust the step. */

      double h_old = h0;

      const int hadjust_status 
        = gsl_odeiv_control_hadjust (con, step, y, e->yerr, e->dydt_out, &h0);

      if (hadjust_status == GSL_ODEIV_HADJ_DEC)
        {
          /* Check that the reported status is correct (i.e. an actual
             decrease in h0 occured) and the suggested h0 will change
             the time by at least 1 ulp */

          double t_curr = GSL_COERCE_DBL(*t);
          double t_next = GSL_COERCE_DBL((*t) + h0);

          if (fabs(h0) < fabs(h_old) && t_next != t_curr) 
            {
              /* Step was decreased. Undo step, and try again with new h0. */
              DBL_MEMCPY (y, e->y0, dydt->dimension);
              e->failed_steps++;
              goto try_step;
            }
          else
            {
              h0 = h_old; /* keep current step size */
            }
        }
    }

  *h = h0;  /* suggest step size for next time-step */

  return step_status;
}
static int
gear2_apply (void *vstate,
             size_t dim,
             double t,
             double h,
             double y[],
             double yerr[],
             const double dydt_in[],
             double dydt_out[], const gsl_odeiv_system * sys)
{
  gear2_state_t *state = (gear2_state_t *) vstate;

  state->stutter = 0;

  if (state->primed == 0 || t == state->t_primed || h != state->last_h)
    {
      /* Execute a single-step method to prime the process.  Note that
       * we do this if the step size changes, so frequent step size
       * changes will cause the method to stutter. 
       * 
       * Note that we reuse this method if the time has not changed,
       * which can occur when the adaptive driver is attempting to find
       * an appropriate step-size on its first iteration */

      int status;
      DBL_MEMCPY (state->yim1, y, dim);

      status =
        gsl_odeiv_step_apply (state->primer, t, h, y, yerr, dydt_in, dydt_out,
                              sys);

      /* Make note of step size and indicate readiness for a Gear step. */

      state->primed = 1;
      state->t_primed = t;
      state->last_h = h;
      state->stutter = 1;

      return status;
    }
  else
    {
      /* We have a previous y value in the buffer, and the step
       * sizes match, so we go ahead with the Gear step.
       */

      double *const k = state->k;
      double *const y0 = state->y0;
      double *const y0_orig = state->y0_orig;
      double *const yim1 = state->yim1;
      double *y_onestep = state->y_onestep;

      int s;
      size_t i;

      DBL_MEMCPY (y0, y, dim);

      /* iterative solution */

      if (dydt_out != NULL)
        {
          DBL_MEMCPY (k, dydt_out, dim);
        }

      /* First traverse h with one step (save to y_onestep) */

      DBL_MEMCPY (y_onestep, y, dim);

      s = gear2_step (y_onestep, state, h, t, dim, sys);

      if (s != GSL_SUCCESS)
        {
          return s;
        }

      /* Then with two steps with half step length (save to y) */

      s = gear2_step (y, state, h / 2.0, t, dim, sys);

      if (s != GSL_SUCCESS)
        {
          /* Restore original y vector */
          DBL_MEMCPY (y, y0_orig, dim);
          return s;
        }

      DBL_MEMCPY (y0, y, dim);

      s = gear2_step (y, state, h / 2.0, t + h / 2.0, dim, sys);

      if (s != GSL_SUCCESS)
        {
          /* Restore original y vector */
          DBL_MEMCPY (y, y0_orig, dim);
          return s;
        }

      /* Cleanup update */

      if (dydt_out != NULL)
        {
          s = GSL_ODEIV_FN_EVAL (sys, t + h, y, dydt_out);

          if (s != GSL_SUCCESS)
            {
              /* Restore original y vector */
              DBL_MEMCPY (y, y0_orig, dim);
              return s;
            }
        }

      /* Estimate error and update the state buffer. */

      for (i = 0; i < dim; i++)
        {
          yerr[i] = 4.0 * (y[i] - y_onestep[i]);
          yim1[i] = y0[i];
        }

      /* Make note of step size. */
      state->last_h = h;

      return 0;
    }
}
/**
 * Evolves a post-Newtonian orbit using the Taylor T4 method.
 *
 * See:
 * Michael Boyle, Duncan A. Brown, Lawrence E. Kidder, Abdul H. Mroue,
 * Harald P. Pfeiffer, Mark A. Scheel, Gregory B. Cook, and Saul A. Teukolsky
 * "High-accuracy comparison of numerical relativity simulations with
 * post-Newtonian expansions"
 * <a href="http://arxiv.org/abs/0710.0158v2">arXiv:0710.0158v2</a>.
 */
int XLALSimInspiralTaylorT4PNEvolveOrbit(
		REAL8TimeSeries **v,            /**< post-Newtonian parameter [returned] */
		REAL8TimeSeries **phi,          /**< orbital phase [returned] */
		REAL8 phiRef,                   /**< reference orbital phase (rad) */
		REAL8 deltaT,                   /**< sampling interval (s) */
		REAL8 m1,                       /**< mass of companion 1 (kg) */
		REAL8 m2,                       /**< mass of companion 2 (kg) */
		REAL8 f_min,                    /**< start frequency (Hz) */
		REAL8 fRef,                     /**< reference frequency (Hz) */
		REAL8 lambda1,                  /**< (tidal deformability of body 1)/(mass of body 1)^5 */
		REAL8 lambda2,                  /**< (tidal deformability of body 2)/(mass of body 2)^5 */
		LALSimInspiralTidalOrder tideO, /**< flag to control spin and tidal effects */
		int O                           /**< twice post-Newtonian order */
		)
{
	const UINT4 blocklen = 1024;
	const REAL8 visco = 1./sqrt(6.);
	REAL8 VRef = 0.;
	XLALSimInspiralTaylorT4PNEvolveOrbitParams params;
	expnFuncTaylorT4 expnfunc;
	expnCoeffsTaylorT4 ak;
	expnCoeffsdEnergyFlux akdEF;

	if(XLALSimInspiralTaylorT4Setup(&ak,&expnfunc,&akdEF,m1,m2,lambda1,lambda2,
			tideO,O))
		XLAL_ERROR(XLAL_EFUNC);

	params.func=expnfunc.angacc4;
	params.ak=ak;

	REAL8 E;
	UINT4 j, len, idxRef = 0;
	LIGOTimeGPS tc = LIGOTIMEGPSZERO;
	double y[2];
	double yerr[2];
	const gsl_odeiv_step_type *T = gsl_odeiv_step_rk4;
	gsl_odeiv_step *s;
	gsl_odeiv_system sys;

	/* setup ode system */
	sys.function = XLALSimInspiralTaylorT4PNEvolveOrbitIntegrand;
	sys.jacobian = NULL;
	sys.dimension = 2;
	sys.params = &params;

	/* allocate memory */
	*v = XLALCreateREAL8TimeSeries( "ORBITAL_VELOCITY_PARAMETER", &tc, 0., deltaT, &lalDimensionlessUnit, blocklen );
	*phi = XLALCreateREAL8TimeSeries( "ORBITAL_PHASE", &tc, 0., deltaT, &lalDimensionlessUnit, blocklen );
	if ( !v || !phi )
		XLAL_ERROR(XLAL_EFUNC);

	y[0] = (*v)->data->data[0] = cbrt(LAL_PI*LAL_G_SI*ak.m*f_min)/LAL_C_SI;
	y[1] = (*phi)->data->data[0] = 0.;
	E = expnfunc.energy4(y[0],&akdEF);
	if (XLALIsREAL8FailNaN(E))
		XLAL_ERROR(XLAL_EFUNC);
	j = 0;

	s = gsl_odeiv_step_alloc(T, 2);
	while (1) {
		++j;
		gsl_odeiv_step_apply(s, j*deltaT, deltaT, y, yerr, NULL, NULL, &sys);
		/* ISCO termination condition for quadrupole, 1pN, 2.5pN */
		if ( y[0] > visco ) {
			XLALPrintInfo("XLAL Info - %s: PN inspiral terminated at ISCO\n", __func__);
			break;
		}
		if ( j >= (*v)->data->length ) {
			if ( ! XLALResizeREAL8TimeSeries(*v, 0, (*v)->data->length + blocklen) )
				XLAL_ERROR(XLAL_EFUNC);
			if ( ! XLALResizeREAL8TimeSeries(*phi, 0, (*phi)->data->length + blocklen) )
				XLAL_ERROR(XLAL_EFUNC);
		}
		(*v)->data->data[j] = y[0];
		(*phi)->data->data[j] = y[1];
	}
	gsl_odeiv_step_free(s);

	/* make the correct length */
	if ( ! XLALResizeREAL8TimeSeries(*v, 0, j) )
		XLAL_ERROR(XLAL_EFUNC);
	if ( ! XLALResizeREAL8TimeSeries(*phi, 0, j) )
		XLAL_ERROR(XLAL_EFUNC);

	/* adjust to correct time */
	XLALGPSAdd(&(*v)->epoch, -1.0*j*deltaT);
	XLALGPSAdd(&(*phi)->epoch, -1.0*j*deltaT);

	/* Do a constant phase shift to get desired value of phiRef */
	len = (*phi)->data->length;
	/* For fRef==0, phiRef is phase of last sample */
	if( fRef == 0. )
		phiRef -= (*phi)->data->data[len-1];
	/* For fRef==fmin, phiRef is phase of first sample */
	else if( fRef == f_min )
		phiRef -= (*phi)->data->data[0];
	/* phiRef is phase when f==fRef */
	else
	{
		VRef = pow(LAL_PI * LAL_G_SI*(m1+m2) * fRef, 1./3.) / LAL_C_SI;
		j = 0;
		do {
			idxRef = j;
			j++;
		} while ((*v)->data->data[j] <= VRef);
		phiRef -= (*phi)->data->data[idxRef];
	}
	for (j = 0; j < len; ++j)
		(*phi)->data->data[j] += phiRef;

	return (int)(*v)->data->length;
}
Exemple #9
0
/* Evolution framework method.
 *
 * Uses an adaptive step control object
 */
int
gsl_odeiv_evolve_apply (gsl_odeiv_evolve * e,
                        gsl_odeiv_control * con,
                        gsl_odeiv_step * step,
                        const gsl_odeiv_system * dydt,
                        double *t, double t1, double *h, double y[])
{
  const double t0 = *t;
  double h0 = *h;
  int step_status;
  int final_step = 0;
  double dt = t1 - t0;  /* remaining time, possibly less than h */

  if (e->dimension != step->dimension)
    {
      GSL_ERROR ("step dimension must match evolution size", GSL_EINVAL);
    }

  if ((dt < 0.0 && h0 > 0.0) || (dt > 0.0 && h0 < 0.0))
    {
      GSL_ERROR ("step direction must match interval direction", GSL_EINVAL);
    }

  /* No need to copy if we cannot control the step size. */

  if (con != NULL)
    {
      DBL_MEMCPY (e->y0, y, e->dimension);
    }

  /* Calculate initial dydt once if the method can benefit. */

  if (step->type->can_use_dydt_in)
    {
      int status = GSL_ODEIV_FN_EVAL (dydt, t0, y, e->dydt_in);

      if (status) 
        {
          return status;
        }
    }

try_step:
    
  if ((dt >= 0.0 && h0 > dt) || (dt < 0.0 && h0 < dt))
    {
      h0 = dt;
      final_step = 1;
    }
  else
    {
      final_step = 0;
    }

  if (step->type->can_use_dydt_in)
    {
      step_status =
        gsl_odeiv_step_apply (step, t0, h0, y, e->yerr, e->dydt_in,
                              e->dydt_out, dydt);
    }
  else
    {
      step_status =
        gsl_odeiv_step_apply (step, t0, h0, y, e->yerr, NULL, e->dydt_out,
                              dydt);
    }

  /* Check for stepper internal failure */

  if (step_status != GSL_SUCCESS) 
    {
      return step_status;
    }

  e->count++;
  e->last_step = h0;

  if (final_step)
    {
      *t = t1;
    }
  else
    {
      *t = t0 + h0;
    }

  if (con != NULL)
    {
      /* Check error and attempt to adjust the step. */
      const int hadjust_status 
        = gsl_odeiv_control_hadjust (con, step, y, e->yerr, e->dydt_out, &h0);

      if (hadjust_status == GSL_ODEIV_HADJ_DEC)
        {
          /* Step was decreased. Undo and go back to try again. */
          DBL_MEMCPY (y, e->y0, dydt->dimension);
          e->failed_steps++;
          goto try_step;
        }
    }

  *h = h0;  /* suggest step size for next time-step */

  return step_status;
}
Exemple #10
0
int idmc_traj_ctrajectory_step(idmc_traj_ctrajectory *trajectory) {
    return gsl_odeiv_step_apply(trajectory->step_function, 0, trajectory->step_size,
                                trajectory->var, trajectory->error, NULL, NULL, &trajectory->system);
}
/*This is the main function of the integration program that calls the gsl Runge-Kutta integrator:*/
void integrator(function F, int D, void *params, double x[], double dxdt[], double x0[], double t[], int iters, double s_noise, double abstol, double reltol) {

	/*Temporary variables*/
    double *y = (double*) malloc( sizeof(double)*D ); /*state variable at time t-1 (input) and then at time t(output)*/
    double *dydt_in = (double*) malloc( sizeof(double)*D ); /*rate of change at time point t-1*/
    double *dydt_out= (double*) malloc( sizeof(double)*D ); /*rate of change at time point t*/
    double *yerr = (double*) malloc( sizeof(double)*D );/*error*/
    double t0,tf,tc,dt=(t[1]-t[0])/2,noise;/*initial time point, final time point, current time point, current time step, noise*/
    int j,ii;/*State variable and iteration indexes*/
    int status;/*integrator success flag*/
    
    
    /*Definitions and initializations of gsl integrator necessary inputs and parameters:*/
    
    /*Prepare noise generator*/
    const gsl_rng_type *Q;
    gsl_rng *r;
    gsl_rng_env_setup();
    Q = gsl_rng_default;
    r = gsl_rng_alloc(Q);

    /*Create a stepping function*/
    const gsl_odeiv_step_type *T = gsl_odeiv_step_rkf45;
    gsl_odeiv_step *s  = gsl_odeiv_step_alloc(T, D);
    /*Create an adaptive control function*/
    gsl_odeiv_control *c  = gsl_odeiv_control_y_new(abstol, reltol);
    /*Create the system to be integrated (with NULL jacobian)*/
    gsl_odeiv_system sys = {F, NULL, D, params};
    
    
    /*The integration loop:*/

    /*Initialize*/
    /*Calculate dx/dt for x0*/
    tc=t[0];
    /* initialise dydt_in from system parameters */
    /*GSL_ODEIV_FN_EVAL(&sys, t, y, dydt_in);*/
    GSL_ODEIV_FN_EVAL(&sys, tc, x0, dydt_in);
    for (j=0;j<D;j++) {
        y[j] = x[j] = x0[j];
    }
            
    /*Integration*/
    for (ii=1; ii<iters; ii++) {
        
        /*Call the integrator*/
        /*int gsl_odeiv_step_apply(gsl_odeiv_step * s, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv_system * dydt)*/        
        t0=t[ii-1];
        tf=t[ii];
        tc=t0;
        
        while (tc<tf) {
            
            /*Constraint time step h such as that tc+h<=tf*/
            if (tc+dt>tf) dt=tf-tc;
            
            /*Advance a h time step*/
            status=gsl_odeiv_step_apply(s, tc, dt, y, yerr, dydt_in, dydt_out, &sys);
            if (status != GSL_SUCCESS) break;
            
            /*Modify time sep*/
            gsl_odeiv_control_hadjust(c,s,y,yerr,dydt_in,&dt);

            /*Increase current time*/
            tc += dt;

            /*Add noise*/
            for (j=0;j<D;j++) {
                noise=gsl_ran_gaussian_ziggurat(r, s_noise);
                y[j] += sqrt(dt)*noise;
                //dydt_in[j]+=noise;
            }
        
        }
        
        /*Unpack and store result for this time point*/
       if (status != GSL_SUCCESS) break;
        
        for (j=0;j<D;j++) { 
            
            x[ii*D+j] = y[j];
            dxdt[(ii-1)*D+j] = dydt_in[j];
            
            /*Prepare next step*/
            dydt_in[j] = dydt_out[j];
            
        }
 
    }
    /*Get dxdt for the last time point*/
    for (j=0;j<D;j++) dxdt[(iters-1)*D+j] = dydt_out[j];
        
    
    /*Free dynamically allocated memory*/
    gsl_odeiv_control_free(c);
    printf("c freed\n");
    gsl_odeiv_step_free(s);
    printf("s freed\n");
    gsl_rng_free(r);
    printf("rng freed\n");
    free(yerr);
    printf("yerr freed\n");
    free(dydt_out);
    printf("dydt_out freed\n");
    free(dydt_in);
    printf("dydt_in freed\n");
    free(y);
    printf("y freed\n");

}