Exemplo n.º 1
0
// Calculates the equivalent degrees of freedom of the estimate (assuming large n)
// such that S_estimate ~ S_true chi^2_v / v,
void degrees_of_freedom( double *wk, uint_t nwk, uint_t K, double *v){
    
    //fills v with 2/sum_k(wk^2)  [ = 2K for unity weights ]
    for (uint_t ii=0; ii<nwk; ii++){
        v[ii]=degrees_of_freedom( ii, wk, nwk, K);   
    }
    
}
Exemplo n.º 2
0
Vector<Acceleration, Frame> Ephemeris<Frame>::
ComputeGravitationalAccelerationOnMasslessBody(
    not_null<DiscreteTrajectory<Frame>*> const trajectory,
    Instant const& t) const {
  auto const it = trajectory->Find(t);
  DegreesOfFreedom<Frame> const& degrees_of_freedom = it.degrees_of_freedom();
  return ComputeGravitationalAccelerationOnMasslessBody(
             degrees_of_freedom.position(), t);
}
Exemplo n.º 3
0
void Ephemeris<Frame>::FlowWithFixedStep(
    std::vector<not_null<DiscreteTrajectory<Frame>*>> const& trajectories,
    std::vector<IntrinsicAcceleration> const& intrinsic_accelerations,
    Instant const& t,
    FixedStepParameters const& parameters) {
  VLOG(1) << __FUNCTION__ << " " << NAMED(parameters.step_) << " " << NAMED(t);
  if (empty() || t > t_max()) {
    Prolong(t);
  }

  std::vector<typename ContinuousTrajectory<Frame>::Hint> hints(bodies_.size());
  NewtonianMotionEquation massless_body_equation;
  massless_body_equation.compute_acceleration =
      std::bind(&Ephemeris::ComputeMasslessBodiesTotalAccelerations,
                this,
                std::cref(intrinsic_accelerations), _1, _2, _3, &hints);

  typename NewtonianMotionEquation::SystemState initial_state;
  for (auto const& trajectory : trajectories) {
    auto const trajectory_last = trajectory->last();
    auto const last_degrees_of_freedom = trajectory_last.degrees_of_freedom();
    // TODO(phl): why do we keep rewriting this?  Should we check consistency?
    initial_state.time = trajectory_last.time();
    initial_state.positions.push_back(last_degrees_of_freedom.position());
    initial_state.velocities.push_back(last_degrees_of_freedom.velocity());
  }

  IntegrationProblem<NewtonianMotionEquation> problem;
  problem.equation = massless_body_equation;

#if defined(WE_LOVE_228)
  typename NewtonianMotionEquation::SystemState last_state;
  problem.append_state =
      [&last_state](
          typename NewtonianMotionEquation::SystemState const& state) {
        last_state = state;
      };
#else
  problem.append_state =
      std::bind(&Ephemeris::AppendMasslessBodiesState,
                _1, std::cref(trajectories));
#endif
  problem.t_final = t;
  problem.initial_state = &initial_state;

  parameters.integrator_->Solve(problem, parameters.step_);

#if defined(WE_LOVE_228)
  // The |positions| are empty if and only if |append_state| was never called;
  // in that case there was not enough room to advance the |trajectories|.
  if (!last_state.positions.empty()) {
    AppendMasslessBodiesState(last_state, trajectories);
  }
#endif
}
Exemplo n.º 4
0
// computes the confidence factors
void confidence_factor(double p, double *wk, uint_t nwk, uint_t K, double *Cf){
    
    double v;   // approximate degrees of freedom
    for (uint_t ii=0; ii<nwk; ii++){
        v=degrees_of_freedom(ii,wk,nwk,K);        
        Cf[ii]=confidence_factor(LOWER,p,v);
        Cf[ii+nwk]=confidence_factor(UPPER,p,v);
        
    }
    
}
void DiscreteTrajectory<Frame>::FillSubTreeFromMessage(
    serialization::Trajectory const& message,
    std::vector<DiscreteTrajectory<Frame>**> const& forks) {
  for (auto timeline_it = message.timeline().begin();
       timeline_it != message.timeline().end();
       ++timeline_it) {
    Append(Instant::ReadFromMessage(timeline_it->instant()),
           DegreesOfFreedom<Frame>::ReadFromMessage(
               timeline_it->degrees_of_freedom()));
  }
  Forkable<DiscreteTrajectory, Iterator>::FillSubTreeFromMessage(message,
                                                                 forks);
}
Exemplo n.º 6
0
// This code is derived from Plugin::RenderTrajectory.
std::vector<std::pair<Position<ICRFJ2000Equator>,
                      Position<ICRFJ2000Equator>>> ApplyDynamicFrame(
    not_null<Body const*> const body,
    not_null<DynamicFrame<ICRFJ2000Equator, Rendering>*> const dynamic_frame,
    DiscreteTrajectory<ICRFJ2000Equator>::Iterator const& begin,
    DiscreteTrajectory<ICRFJ2000Equator>::Iterator const& end) {
  std::vector<std::pair<Position<ICRFJ2000Equator>,
                        Position<ICRFJ2000Equator>>> result;

  // Compute the trajectory in the rendering frame.
  DiscreteTrajectory<Rendering> intermediate_trajectory;
  for (auto it = begin; it != end; ++it) {
    intermediate_trajectory.Append(
        it.time(),
        dynamic_frame->ToThisFrameAtTime(it.time())(it.degrees_of_freedom()));
  }

  // Render the trajectory at current time in |Rendering|.
  Instant const& current_time = intermediate_trajectory.last().time();
  DiscreteTrajectory<Rendering>::Iterator initial_it =
      intermediate_trajectory.Begin();
  DiscreteTrajectory<Rendering>::Iterator const intermediate_end =
      intermediate_trajectory.End();
  auto to_rendering_frame_at_current_time =
      dynamic_frame->FromThisFrameAtTime(current_time).rigid_transformation();
  if (initial_it != intermediate_end) {
    for (auto final_it = initial_it;
         ++final_it, final_it != intermediate_end;
         initial_it = final_it) {
      result.emplace_back(to_rendering_frame_at_current_time(
                              initial_it.degrees_of_freedom().position()),
                          to_rendering_frame_at_current_time(
                              final_it.degrees_of_freedom().position()));
    }
  }
  return result;
}
Exemplo n.º 7
0
void confidence_interval( double p, double *S, uint_t N, double *wk, uint_t nwk, uint_t K, double *Sc){
    
    uint_t pp_start=N-nwk;       //temporarily stores quantile information in Sc (ensuring not to be overwritten)
    
    double v;   // approximate degrees of freedom
    for (uint_t ii=0; ii<nwk; ii++){
        v=degrees_of_freedom(ii,wk,nwk,K);        
        Sc[pp_start+ii]=confidence_factor(LOWER,p,v);
        Sc[pp_start+N+ii]=confidence_factor(UPPER,p,v);
        
    }
    
    uint_t ipp;                 //used to calculate index of quantile
    for (uint_t ii=0; ii<N; ii++){
        ipp=ii%nwk;
        Sc[ii]   = Sc[ipp+pp_start]*S[ii];          //lower bound
        Sc[ii+N] = Sc[ipp+pp_start+N]*S[ii];        //upper bound
    }
}
Exemplo n.º 8
0
double mtcpsd<T>::dof(uint_t ii){
 
   return degrees_of_freedom(ii,this->wk, this->info.nwk,this->info.K);
    
}
Exemplo n.º 9
0
void Ephemeris<Frame>::ComputeApsides(
    not_null<MassiveBody const*> const body,
    typename DiscreteTrajectory<Frame>::Iterator const begin,
    typename DiscreteTrajectory<Frame>::Iterator const end,
    DiscreteTrajectory<Frame>& apoapsides,
    DiscreteTrajectory<Frame>& periapsides) {
  not_null<ContinuousTrajectory<Frame> const*> const body_trajectory =
      trajectory(body);
  typename ContinuousTrajectory<Frame>::Hint hint;

  std::experimental::optional<Instant> previous_time;
  std::experimental::optional<DegreesOfFreedom<Frame>>
      previous_degrees_of_freedom;
  std::experimental::optional<Square<Length>> previous_squared_distance;
  std::experimental::optional<Variation<Square<Length>>>
      previous_squared_distance_derivative;

  for (auto it = begin; it != end; ++it) {
    Instant const time = it.time();
    DegreesOfFreedom<Frame> const degrees_of_freedom = it.degrees_of_freedom();
    DegreesOfFreedom<Frame> const body_degrees_of_freedom =
        body_trajectory->EvaluateDegreesOfFreedom(time, &hint);
    RelativeDegreesOfFreedom<Frame> const relative =
        degrees_of_freedom - body_degrees_of_freedom;
    Square<Length> const squared_distance =
        InnerProduct(relative.displacement(), relative.displacement());
    // This is the derivative of |squared_distance|.
    Variation<Square<Length>> const squared_distance_derivative =
        2.0 * InnerProduct(relative.displacement(), relative.velocity());

    if (previous_squared_distance_derivative &&
        Sign(squared_distance_derivative) !=
            Sign(*previous_squared_distance_derivative)) {
      CHECK(previous_time &&
            previous_degrees_of_freedom &&
            previous_squared_distance);

      // The derivative of |squared_distance| changed sign.  Construct a Hermite
      // approximation of |squared_distance| and find its extrema.
      Hermite3<Instant, Square<Length>> const
          squared_distance_approximation(
              {*previous_time, time},
              {*previous_squared_distance, squared_distance},
              {*previous_squared_distance_derivative,
               squared_distance_derivative});
      std::set<Instant> const extrema =
          squared_distance_approximation.FindExtrema();

      // Now look at the extrema and check that exactly one is in the required
      // time interval.  This is normally the case, but it can fail due to
      // ill-conditioning.
      Instant apsis_time;
      int valid_extrema = 0;
      for (auto const& extremum : extrema) {
        if (extremum >= *previous_time && extremum <= time) {
          apsis_time = extremum;
          ++valid_extrema;
        }
      }
      if (valid_extrema != 1) {
        // Something went wrong when finding the extrema of
        // |squared_distance_approximation|. Use a linear interpolation of
        // |squared_distance_derivative| instead.
        apsis_time = Barycentre<Instant, Variation<Square<Length>>>(
            {time, *previous_time},
            {*previous_squared_distance_derivative,
             -squared_distance_derivative});
      }

      // Now that we know the time of the apsis, construct a Hermite
      // approximation of the position of the body, and use it to derive its
      // degrees of freedom.  Note that an extremum of
      // |squared_distance_approximation| is in general not an extremum for
      // |position_approximation|: the distance computed using the latter is a
      // 6th-degree polynomial.  However, approximating this polynomial using a
      // 3rd-degree polynomial would yield |squared_distance_approximation|, so
      // we shouldn't be far from the truth.
      Hermite3<Instant, Position<Frame>> position_approximation(
          {*previous_time, time},
          {previous_degrees_of_freedom->position(),
           degrees_of_freedom.position()},
          {previous_degrees_of_freedom->velocity(),
           degrees_of_freedom.velocity()});
      DegreesOfFreedom<Frame> const apsis_degrees_of_freedom(
          position_approximation.Evaluate(apsis_time),
          position_approximation.EvaluateDerivative(apsis_time));
      if (Sign(squared_distance_derivative).Negative()) {
        apoapsides.Append(apsis_time, apsis_degrees_of_freedom);
      } else {
        periapsides.Append(apsis_time, apsis_degrees_of_freedom);
      }
    }

    previous_time = time;
    previous_degrees_of_freedom = degrees_of_freedom;
    previous_squared_distance = squared_distance;
    previous_squared_distance_derivative = squared_distance_derivative;
  }
}
Exemplo n.º 10
0
bool Ephemeris<Frame>::FlowWithAdaptiveStep(
    not_null<DiscreteTrajectory<Frame>*> const trajectory,
    IntrinsicAcceleration intrinsic_acceleration,
    Instant const& t,
    AdaptiveStepParameters const& parameters,
    std::int64_t const max_ephemeris_steps) {
  Instant const& trajectory_last_time = trajectory->last().time();
  if (trajectory_last_time == t) {
    return true;
  }

  std::vector<not_null<DiscreteTrajectory<Frame>*>> const trajectories =
      {trajectory};
  std::vector<IntrinsicAcceleration> const intrinsic_accelerations =
      {std::move(intrinsic_acceleration)};
  // The |min| is here to prevent us from spending too much time computing the
  // ephemeris.  The |max| is here to ensure that we always try to integrate
  // forward.  We use |last_state_.time.value| because this is always finite,
  // contrary to |t_max()|, which is -∞ when |empty()|.
  Instant const t_final =
      std::min(std::max(last_state_.time.value +
                            max_ephemeris_steps * parameters_.step(),
                        trajectory_last_time + parameters_.step()),
               t);
  Prolong(t_final);

  std::vector<typename ContinuousTrajectory<Frame>::Hint> hints(bodies_.size());
  NewtonianMotionEquation massless_body_equation;
  massless_body_equation.compute_acceleration =
      std::bind(&Ephemeris::ComputeMasslessBodiesTotalAccelerations,
                this,
                std::cref(intrinsic_accelerations), _1, _2, _3, &hints);

  typename NewtonianMotionEquation::SystemState initial_state;
  auto const trajectory_last = trajectory->last();
  auto const last_degrees_of_freedom = trajectory_last.degrees_of_freedom();
  initial_state.time = trajectory_last.time();
  initial_state.positions.push_back(last_degrees_of_freedom.position());
  initial_state.velocities.push_back(last_degrees_of_freedom.velocity());

  IntegrationProblem<NewtonianMotionEquation> problem;
  problem.equation = massless_body_equation;
  problem.append_state =
      std::bind(&Ephemeris::AppendMasslessBodiesState,
                _1, std::cref(trajectories));
  problem.t_final = t_final;
  problem.initial_state = &initial_state;

  AdaptiveStepSize<NewtonianMotionEquation> step_size;
  step_size.first_time_step = problem.t_final - initial_state.time.value;
  CHECK_GT(step_size.first_time_step, 0 * Second)
      << "Flow back to the future: " << problem.t_final
      << " <= " << initial_state.time.value;
  step_size.safety_factor = 0.9;
  step_size.tolerance_to_error_ratio =
      std::bind(&Ephemeris<Frame>::ToleranceToErrorRatio,
                std::cref(parameters.length_integration_tolerance_),
                std::cref(parameters.speed_integration_tolerance_),
                _1, _2);
  step_size.max_steps = parameters.max_steps_;

  auto const outcome = parameters.integrator_->Solve(problem, step_size);
  // TODO(egg): when we have events in trajectories, we should add a singularity
  // event at the end if the outcome indicates a singularity
  // (|VanishingStepSize|).  We should not have an event on the trajectory if
  // |ReachedMaximalStepCount|, since that is not a physical property, but
  // rather a self-imposed constraint.
  return outcome == integrators::TerminationCondition::Done && t_final == t;
}
Exemplo n.º 11
0
int main(int argc, char* argv[]){

  if (argc != 1){
    fprintf( stderr, "Usage: %s\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  int i;

  /* data directory */
  char data_dir[256];
  snprintf(data_dir, 256, "../data/");

  /* load the pointing list */
  char plist_filename[256];
  snprintf(plist_filename, 256, "%stodo_list.ascii.dat", data_dir);

  int N_plist;
  POINTING *plist;
  load_pointing_list(plist_filename, &N_plist, &plist);


  /* Read star data for each pointing */
  for(i = 0; i < N_plist; i++){
    char data_filename[256];
    snprintf(data_filename, 256, "%sstar_%s.ascii.dat", data_dir, plist[i].ID);
    load_data(data_filename, &plist[i].N_data, &plist[i].data);
  }

  fprintf(stderr, "Star data loaded from %s\n", data_dir);

  /* Read model data for each pointing,
     here each file starts with uniformly distributed random */
  for(i = 0; i < N_plist; i++){
    char model_filename[256];
    snprintf(model_filename, 256, "%suniform_%s.ascii.dat", data_dir, plist[i].ID);
    load_data(model_filename, &plist[i].N_model, &plist[i].model);
  }

  fprintf(stderr, "Uniform model data loaded from %s\n", data_dir);

  /* initialize model parameters */
  PARAMETERS params;
  params.N_parameters = 5; 	/* Total number of free paramters. */

  params.thindisk_type = 1;	/* turn on thin disk */
  params.thindisk_r0 = 2.475508;
  params.thindisk_z0 = 0.241209;
  params.thindisk_n0 = 1.0;

  params.thickdisk_type = 1;	/* turn on thick disk */
  params.thickdisk_r0 = 2.417346;
  params.thickdisk_z0 = 0.694395;
  params.thickdisk_n0 = 0.106672;

  params.halo_type = 0; 	/* turn off halo */

  fprintf(stderr, "Set initial parameters..\n");

  int mcmc_steps, efficiency_counter;
  double efficiency;
  MCMC *mcmc_chain;
  double chi2, delta_chi2;
  int dof;

  mcmc_steps = 500000;
  mcmc_chain = calloc(mcmc_steps, sizeof(MCMC));

  FILE *file_chain_realtime;
  file_chain_realtime = fopen("./data/mcmc.dat", "a");

  fprintf(stderr, "Allocate MCMC chain..Max steps = %d \n", mcmc_steps);

  /* set the first element as the initial parameters.
   Then calculate the chi2 for the initial parameters. */
  mcmc_chain[0].params = params;

  set_weights(mcmc_chain[0].params, plist, N_plist);

  /* allocate space for correlation function calculation */
  /* This also does a first time correlation calculation of initial parameters. */
  /* DD pairs may only calculated once here but not later.  */
  correlation_initialize(plist, N_plist);

  /* load the jackknife fractional errors */
  load_errors(plist, N_plist);

  mcmc_chain[0].dof = degrees_of_freedom(plist, N_plist, params);
  mcmc_chain[0].chi2 = chi_square(plist, N_plist);

  fprintf(stderr, "initial: chi2 = %le \n", mcmc_chain[0].chi2);

  fprintf(stderr, "Start MCMC calculation..\n");

  /* Markov chain loop */
  efficiency_counter = 1;
  for(i = 1; i < mcmc_steps; i++){

    /* update new positions in paramter space */
    params = update_parameters(mcmc_chain[i - 1].params);

    /* recalculate weights */
    set_weights(params, plist, N_plist);

    /* recalculate correlation functions */
    calculate_correlation(plist, N_plist);

    /* get chi squares */
    dof = degrees_of_freedom(plist, N_plist, params);

    chi2 = chi_square(plist, N_plist);

    delta_chi2 = chi2 - mcmc_chain[i - 1].chi2;

    fprintf(stderr, "delta_chi2 = %le \n", delta_chi2);

    if(delta_chi2 <= 0.0){
      /* if delta chisquare is smaller then record*/
      mcmc_chain[i].params = params;
      mcmc_chain[i].chi2 = chi2;
      mcmc_chain[i].dof = dof;
      efficiency_counter++;
    }
    else{
      /* if delta chisquare is bigger then use probability to decide */
      /* !!! replace with GSL random generator later !!! */
      double tmp = (double)rand() / (double)RAND_MAX; /* a random number in [0,1] */
      if (tmp < exp(- delta_chi2 / 2.0)){
	mcmc_chain[i].params = params;
	mcmc_chain[i].chi2 = chi2;
	mcmc_chain[i].dof = dof;
	efficiency_counter++;
      }
      else{
	/* record the old position. */
	mcmc_chain[i] = mcmc_chain[i - 1];
      }
    }

    efficiency = (float) efficiency_counter / i;
    /* print out progress */
    /* if(i % (mcmc_steps / 100) == 0){ */
    /*   fprintf(stderr, "MCMC... %d / %d: chi2 = %lf \n", i, mcmc_steps, chi2); */
    /* } */
    fprintf(stderr, "MCMC... %d / %d: efficiency = %lf \n z0_thin = %lf, r0_thin = %lf, z0_thick = %lf, r0_thick = %lf, n0_thick = %lf \n chi2 = %lf, dof = %d, chi2_reduced = %lf \n\n",
	    i, mcmc_steps, efficiency, params.thindisk_z0, params.thindisk_r0, params.thickdisk_z0, params.thickdisk_r0, params.thickdisk_n0, chi2, dof, chi2/dof);

    MCMC tmp_mc;
    PARAMETERS tmp_p;
    tmp_mc = mcmc_chain[i];
    tmp_p = tmp_mc.params;
    // fprintf(stderr, "Made it here\n");
    // fprintf(file_chain_realtime, "%d\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%d\t%lf\n",
	   //  i+50000, tmp_p.thindisk_r0, tmp_p.thindisk_z0, tmp_p.thickdisk_r0, tmp_p.thickdisk_z0, tmp_p.thickdisk_n0,
	   //  tmp_mc.chi2, (int)tmp_mc.dof, tmp_mc.chi2/dof);
    // fprintf(stderr, "Printed to file.\n");
    // if(i % 50 == 0){
    //   fflush(file_chain_realtime);
    // }

  } /* end of mcmc */


  output_mcmc(mcmc_chain, mcmc_steps);

  fprintf(stderr, "End MCMC calculation..\n");

  for(i = 0; i < N_plist; i++){
    free(plist[i].data);
    free(plist[i].model);
    free(plist[i].corr);
  }
  free(plist);

  free(mcmc_chain);

  return EXIT_SUCCESS;

}