コード例 #1
0
ファイル: est_popsize.cpp プロジェクト: mjhubisz/argweaver
/* compute first and (optionally) second derivative at particular
   abscissa, using numerical approximations to derivatives if
   necessary.  Allows for bounds.  For use in one-dimensional
   optimizers.  Set deriv2 == NULL to skip second derivative.  Note:
   function value fx is only used in the numerical case (avoids a
   redundant function evaluation) */
void opt_derivs_1d(double *deriv, double *deriv2, double x, double fx,
		   double lb, double ub, double (*f)(double, void*), void *data,
		   double (*compute_deriv)(double x, void *data, double lb,
					   double ub),
		   double (*compute_deriv2)(double x, void *data, double lb,
					    double ub),
		   double deriv_epsilon) {
    double fxeps=-1.0, fx2eps=-1.0;
    int at_ub = (ub - x < BOUNDARY_EPS2); /* at upper bound */

    if (compute_deriv == NULL) {
	if (at_ub) {           /* use backward method if at upper bound */
	    fxeps = f(x - deriv_epsilon, data);
	    *deriv = (fx - fxeps) / deriv_epsilon;
	}
	else {
	    fxeps = f(x + deriv_epsilon, data);
	    *deriv = (fxeps - fx) / deriv_epsilon;
	}
    }
    else
	*deriv = compute_deriv(x, data, lb, ub);

    if (deriv2 == NULL) return;

    if (compute_deriv2 == NULL) {     /* numerical 2nd deriv */
	if (at_ub) {                    /* at upper bound */
	    if (compute_deriv != NULL)    /* exact 1d available */
		*deriv2 = (*deriv - compute_deriv(x - deriv_epsilon, data, lb, ub)) /
		    deriv_epsilon;
	    else {                    /* numerical 1st and second derivs */
		fx2eps = f(x - 2*deriv_epsilon, data);
		*deriv2 = (fx2eps + 2*fxeps - fx) / (deriv_epsilon * deriv_epsilon);
	    }
	}
	else {                       /* not at upper bound */
	    if (compute_deriv != NULL) /* exact 1d available */
		*deriv2 = (compute_deriv(x + deriv_epsilon, data, lb, ub) - *deriv) /
		    deriv_epsilon;
	    else {                    /* numerical 1st and second derivs */
		fx2eps = f(x + 2*deriv_epsilon, data);
		*deriv2 = (fx2eps - 2*fxeps + fx) / (deriv_epsilon * deriv_epsilon);
	    }
	}
    }
    else                          /* exact 2nd deriv */
	*deriv2 = compute_deriv2(x, data, lb, ub);
}
コード例 #2
0
ファイル: TTVFast.c プロジェクト: shadden/PyTTVFast
int TTVFast(double *params,double dt, double Time, double total,int n_plan,CalcTransit *transit,CalcRV *RV_struct, int nRV, int n_events, int input_flag)
{
  n_planets=n_plan;
  int  planet;
  int i, j;
  j=0;
  void jacobi_heliocentric(PhaseState *jacobi, PhaseState *helio, double GMsun, double *GM);
  double dot0,dot1,dot2,rskyA,rskyB,vprojA,vprojB,rsky,vproj,velocity,new_dt;
  double compute_RV(PhaseState *ps);
  double compute_deriv(PhaseState ps,int planet);
  int RV_count = 0;
  int k=0;
  double deriv;
  double  dt2 = dt/2.0;

  if(RV_struct !=NULL){
    RV_count = nRV;
  }

  machine_epsilon = determine_machine_epsilon();
  if(input_flag ==0){
    read_jacobi_planet_elements(params);
  }
  if(input_flag ==1){
    read_helio_planet_elements(params);
  }
  if(input_flag ==2){
    read_helio_cartesian_params(params);
  }
  if(input_flag !=0 && input_flag !=1 && input_flag !=2){
    printf("Input flag must be 0,1, or 2. \n");
    //exit(-1);
    return FAILURE;
  }
  
  copy_system(p, rp);
  compute_corrector_coefficientsTO(dt);
  real_to_mapTO(rp, p);

  for(i = 0;i<n_planets;i++){
  prev_dot[i] = p[i].x*p[i].xd+p[i].y*p[i].yd;
  count[i]=0;

  }

  if (A(p, dt2) != SUCCESS)
  	return FAILURE;

  while(Time < total){
    copy_system(p, p_tmp);
    B(p,dt);
    if( A(p,dt) != SUCCESS)
		return FAILURE;
    Time+=dt;
    /* Calculate RV if necessary */

    if(j <RV_count){
      RVTime = Time+dt2;
      
      if(RVTime>(RV_struct+j)->time && RVTime-dt<(RV_struct+j)->time){
	if(RVTime-(RV_struct+j)->time > (RV_struct+j)->time-(RVTime-dt)){
	  copy_system(p_tmp,p_RV);
	  new_dt= (RV_struct+j)->time-(RVTime-dt);
	  if( A(p,dt) != SUCCESS)
		return FAILURE;
	  velocity = compute_RV(p_RV);
	  (RV_struct+j)->RV =velocity;
	  
	}else{
	  copy_system(p,p_RV);
	  new_dt= (RV_struct+j)->time-RVTime;
	  if( A(p,dt) != SUCCESS)
		return FAILURE;
	  velocity = compute_RV(p_RV);
	  (RV_struct+j)->RV =velocity;
	}
	j++;
      }
    }
    
    /* now look for transits */
    
    for(i = 0;i<n_planets;i++){ /* for each planet */
      curr_dot[i] = p[i].x*p[i].xd+p[i].y*p[i].yd;
      curr_z[i] = p[i].z;
      tplanet=i;
      /* Check Transit Condition*/
      if(prev_dot[tplanet]<0 && curr_dot[tplanet]>0 && curr_z[tplanet]>0){
	bad_transit_flag = 0;
	copy_system(p,p_ahead);
	copy_system(p_tmp,p_behind);    
	if (A(p_ahead,-dt2) != SUCCESS)
		return FAILURE ;
	if (A(p_behind,-dt2) !=SUCCESS)
		return FAILURE ;
	jacobi_heliocentric(p_behind,helioBehind,GMsun,GM);	  
	jacobi_heliocentric(p_ahead,helioAhead,GMsun,GM);
	
	/* Calculate Rsky.Vsky */
	dot2 = helioAhead[tplanet].x*helioAhead[tplanet].xd+helioAhead[tplanet].y*helioAhead[tplanet].yd;
	dot1 = helioBehind[tplanet].x*helioBehind[tplanet].xd+helioBehind[tplanet].y*helioBehind[tplanet].yd;
	
	if(dot1 < 0 && dot2 >0){
	  /* If Rsky.Vsky passed through zero*/
	  TimeA=Time;
	  TimeB = Time-dt;
	  dotA= TimeA+kepler_transit_locator(kc_helio[tplanet],-dt,&helioAhead[tplanet],&temporary);

	  deriv = compute_deriv(temporary,tplanet);

	  if(deriv < 0.0 || temporary.z <0.0 || dotA < TimeB-PI/mm[tplanet] || dotA > TimeA+PI/mm[tplanet]){ /* was the right root found?*/
	    dotA= TimeA+bisection(kc_helio[tplanet],&helioAhead[tplanet],&helioBehind[tplanet],&temporary);
	  }
	  
	  rskyA = sqrt(temporary.x*temporary.x + temporary.y*temporary.y);
	  vprojA = sqrt(temporary.xd*temporary.xd + temporary.yd*temporary.yd);
	  
	  dotB= TimeB+kepler_transit_locator(kc_helio[tplanet],dt,&helioBehind[tplanet],&temporary);

	  deriv = compute_deriv(temporary,tplanet);	  

	  if(deriv < 0.0 || temporary.z <0.0 || dotB < TimeB-PI/mm[tplanet] || dotB > TimeA+PI/mm[tplanet]){ /* was the right root found?*/
	    dotB= TimeB+bisection(kc_helio[tplanet],&helioBehind[tplanet],&helioAhead[tplanet],&temporary);
	  }
	  
	  rskyB = sqrt(temporary.x*temporary.x + temporary.y*temporary.y);
	  vprojB = sqrt(temporary.xd*temporary.xd + temporary.yd*temporary.yd);
	  
	  tdot_result = ((dotB-TimeB)*dotA+(TimeA-dotA)*dotB)/(TimeA-TimeB-dotA+dotB);
	  
	  rsky = ((dotB-TimeB)*rskyA+(TimeA-dotA)*rskyB)/(TimeA-TimeB-dotA+dotB);
	  vproj = ((dotB-TimeB)*vprojA+(TimeA-dotA)*vprojB)/(TimeA-TimeB-dotA+dotB);
	}else{
	  
	  copy_system(helioAhead,helioBehind);
	  copy_system(p,p_ahead);
	  B(p_ahead,dt);
	  if (A(p_ahead,dt2) != SUCCESS)
		return FAILURE;
	  TimeA=Time+dt;
	  TimeB = Time;
	  jacobi_heliocentric(p_ahead,helioAhead,GMsun,GM);
	  dotB= TimeB+kepler_transit_locator(kc_helio[tplanet],dt,&helioBehind[tplanet],&temporary);
	  
	  deriv = compute_deriv(temporary,tplanet);	  
	  
	  if(deriv < 0.0 || temporary.z <0.0 || dotB < TimeB-PI/mm[tplanet] || dotB > TimeA+PI/mm[tplanet]){ /* was the right root found?*/
	    dotB= TimeB+bisection(kc_helio[tplanet],&helioBehind[tplanet],&helioAhead[tplanet],&temporary);
	  }
	  
	  rskyB = sqrt(temporary.x*temporary.x + temporary.y*temporary.y);
	  vprojB = sqrt(temporary.xd*temporary.xd + temporary.yd*temporary.yd);
	  
	  dotA= TimeA+kepler_transit_locator(kc_helio[tplanet],-dt,&helioAhead[tplanet],&temporary);
	  
	  deriv = compute_deriv(temporary,tplanet);	  
	  
	  if(deriv < 0.0 || temporary.z <0.0 || dotA < TimeB-PI/mm[tplanet] || dotA > TimeA+PI/mm[tplanet]){ /* was the right root found?*/
	    dotA= TimeA+bisection(kc_helio[tplanet],&helioAhead[tplanet],&helioBehind[tplanet],&temporary);
	  }
	  
	  rskyA = sqrt(temporary.x*temporary.x + temporary.y*temporary.y);
	  vprojA = sqrt(temporary.xd*temporary.xd + temporary.yd*temporary.yd);
	  
	  tdot_result = ((dotB-TimeB)*dotA+(TimeA-dotA)*dotB)/(TimeA-TimeB-dotA+dotB);
	  rsky =  ((dotB-TimeB)*rskyA+(TimeA-dotA)*rskyB)/(TimeA-TimeB-dotA+dotB);
	  vproj =  ((dotB-TimeB)*vprojA+(TimeA-dotA)*vprojB)/(TimeA-TimeB-dotA+dotB);
	}
	if(k< n_events){
	  
	  if(bad_transit_flag ==0){
	    (transit+k)->planet = tplanet;
	    (transit+k)->epoch = count[tplanet];
	    (transit+k)->time = tdot_result;
	    (transit+k)->rsky = rsky;
	    (transit+k)->vsky = vproj;
	  }else{
	    (transit+k)->planet = tplanet;
	    (transit+k)->epoch = count[tplanet];
	    (transit+k)->time = BAD_TRANSIT;
	    (transit+k)->rsky = BAD_TRANSIT;
	    (transit+k)->vsky = BAD_TRANSIT;
	  }
	  count[tplanet]++;
	  k++;
	}else{
	  printf("Not enough memory allocated for Transit structure: more events triggering as transits than expected. Possibily indicative of larger problem.\n");
	  //exit(-1);
	  return FAILURE;
	}
      }
      
      prev_dot[i]=curr_dot[i];      
    }
  }
  return SUCCESS;
}