Program Listing for File PolynomialEvolution.h¶
↰ Return to documentation for file (/home/kpenev/projects/git/poet/poet_src/unit_tests/shared/PolynomialEvolution.h)
#ifndef __POLYNOMIAL_EVOLUTION_H
#define __POLYNOMIAL_EVOLUTION_H
#include "../Core/Functions.h"
#include "../StellarEvolution/EvolvingStellarQuantity.h"
#include "../StellarEvolution/Interpolator.h"
#include "Common.h"
//#include "../StellarSystem.h"
//#include "../Star.h"
//#include "../Planet.h"
//#include "../OrbitSolver.h"
#include <valarray>
#include <gsl/gsl_roots.h>
//#include "YRECIO.h"
#include <fstream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
namespace StellarEvolution {
class PolynomialEvolutionQuantity : public EvolvingStellarQuantity,
Core::FunctionDerivatives {
private:
std::valarray<double> __poly_coef;
double
__xmin,
__xmax;
mutable double __deriv_x;
std::vector<double> __empty_vector;
public:
PolynomialEvolutionQuantity(
const std::valarray<double> &coefficients,
double range_low,
double range_high,
double derivative_x=NaN
) :
__poly_coef(coefficients),
__xmin(range_low),
__xmax(range_high),
__deriv_x(derivative_x)
{}
void select_interpolation_region(double) const {}
double operator()(double x) const {__deriv_x = x; return order(0);}
double range_low() const {return __xmin;}
double range_high() const {return __xmax;}
virtual const std::vector<double> &discontinuities() const
{return __empty_vector;}
virtual double previous_discontinuity() const {return __xmin;}
virtual double next_discontinuity() const {return __xmax;}
virtual void enable_next_interpolation_region() const
{assert(false);}
const Core::FunctionDerivatives *deriv(double x) const
{return new PolynomialEvolutionQuantity(__poly_coef,
__xmin,
__xmax,
x);}
double order(unsigned deriv_order = 1) const;
friend std::ostream &operator<<(
std::ostream &os,
const PolynomialEvolutionQuantity &track
);
std::string kind() const {return "PolynomialEvolutionQuantity";}
};//End PolynomialEvolutionQuantity class.
class MockStellarEvolution : public StellarEvolution::Interpolator {
private:
std::valarray< std::valarray<double> >
__R,
__Iconv,
__Irad,
__Itot,
__Rcore,
__Mcore,
__Menv,
__Lum;
double __core_formation_age;
public:
MockStellarEvolution(
double core_formation_age = Core::NaN,
const std::valarray< std::valarray<double> > &
R = std::valarray< std::valarray<double> >(),
const std::valarray< std::valarray<double> > &
Iconv = std::valarray< std::valarray<double> >(),
const std::valarray< std::valarray<double> > &
Irad = std::valarray< std::valarray<double> >(),
const std::valarray< std::valarray<double> > &
Rcore = std::valarray< std::valarray<double> >(),
const std::valarray< std::valarray<double> > &
Mcore = std::valarray< std::valarray<double> >(),
const std::valarray< std::valarray<double> > &
Lum = std::valarray< std::valarray<double> >()
);
EvolvingStellarQuantity *operator()(QuantityID quantity,
double mass,
double feh) const;
double core_formation_age() const {return __core_formation_age;}
};
MockStellarEvolution *make_no_evolution(double Rstar = 1.0,
double Iconv = 1.0);
MockStellarEvolution *make_linear_I_evolution();
}//End StellarEvolution namespace.
#if 0
class StarData {
private:
unsigned __num_stars_created;
public:
double mass,
feh,
radius,
age,
conv_spin,
rad_spin,
tidal_Q,
wind_strength,
wind_sat_freq,
coupling_timescale,
Q_trans_width,
disk_lock_w,
disk_lock_time;
PolynomialEvolutionTrack *Lrad_track,
*Lconv_track;
std::valarray<double> evolution_masses,
evolution_ages,
Lrad,
Lconv,
Iconv,
Irad,
Mrad_deriv,
Lconv_deriv,
Lrad_deriv,
Rrad,
all_radii;
std::valarray< std::valarray<double> > r_coef,
Iconv_coef,
Irad_coef,
Mrad_coef,
Rcore_coef;
StarData();
void create_random_star(Star::EvolvingStar **star);
~StarData();
};
class PlanetData {
public:
Star* star;
StarData* sdata;
double mass, radius;
std::valarray<double> ages;
std::valarray<double> semis;
PlanetData() : star(NULL) {
sdata = new StarData();
sdata->create_random_star(&star);
};
void create_random_planet(Planet** planet);
double get_semi(double age);
~PlanetData();
};
class SystemData {
public:
Star* star;
Planet* planet;
StarData* sdata;
PlanetData* pdata;
SystemData() {
//exit(-1);
pdata = new PlanetData();
pdata->create_random_planet(&planet);
star = pdata->star;
sdata = pdata->sdata;
}
void create_random_system(StellarSystem** system) {
/* double min_age = sdata->evolution_ages[0];
double precision = 0.01;
double max_age = star->get_lifetime();
OrbitSolver orb(min_age, max_age, precision,
stellar_system_diff_eq, stellar_system_jacobian);*/
*system = new StellarSystem(*star, *planet, "");
}
};
#endif
namespace StellarEvolution {
PolynomialEvolutionQuantity *exact_track(
const std::valarray< std::valarray<double> > &poly_coef,
double mass,
double low_mass_age_scaling = 0,
double high_mass_age_scaling = 0,
double scale_mass = NaN
);
} //End StellarEvolution namespace.
#if 0
class PolynomialStellarEvolution : public StellarEvolution {
public:
PolynomialStellarEvolution(
const std::valarray<double> &masses,
const std::valarray<double> &ages,
const std::valarray< std::valarray<double> > &r_coef,
const std::valarray< std::valarray<double> > &Iconv_coef,
const std::valarray< std::valarray<double> > &Itot_coef,
const std::valarray< std::valarray<double> > &Mrad_coef,
const std::valarray< std::valarray<double> > &Rcore_coef,
double low_mass_age_scaling,
double high_mass_age_scaling);
};
#endif
class ExponentialPlusFunc : public Core::OneArgumentDiffFunction,
Core::FunctionDerivatives
{
private:
double __scale, __rate, __deriv_x;
Core::OneArgumentDiffFunction *__offset;
public:
ExponentialPlusFunc(Core::OneArgumentDiffFunction *offset,
double scale,
double rate,
double deriv_x = Core::NaN) :
__scale(scale),
__rate(rate),
__deriv_x(deriv_x),
__offset(offset)
{}
double operator()(double x) const
{return (*__offset)(x) + __scale * std::exp(__rate * x);}
const Core::FunctionDerivatives *deriv(double x) const
{return new ExponentialPlusFunc(__offset, __scale, __rate, x);}
double order(unsigned deriv_order = 1) const;
double range_high() const {return __offset->range_high();}
double range_low() const {return __offset->range_low();}
Core::InterpSolutionIterator crossings(double) const
{return Core::InterpSolutionIterator();}
};
class FuncPlusFunc : public Core::OneArgumentDiffFunction,
Core::FunctionDerivatives {
private:
const OneArgumentDiffFunction *__f1, *__f2;
double __deriv_x;
public:
FuncPlusFunc(const OneArgumentDiffFunction *f1,
const OneArgumentDiffFunction *f2,
double deriv_x = Core::NaN) :
__f1(f1), __f2(f2), __deriv_x(deriv_x)
{}
double operator()(double x) const {return (*__f1)(x) + (*__f2)(x);}
const FunctionDerivatives *deriv(double x) const
{return new FuncPlusFunc(__f1, __f2, x);}
double order(unsigned deriv_order = 1) const;
double range_high() const
{return std::min(__f1->range_high(), __f2->range_high());}
double range_low() const
{return std::max(__f1->range_low(), __f2->range_low());}
Core::InterpSolutionIterator crossings(double) const
{return Core::InterpSolutionIterator();}
};
class PiecewiseFunction : public Core::OneArgumentDiffFunction,
Core::FunctionDerivatives{
private:
double __deriv_x, __range_low, __range_high;
std::list<const OneArgumentDiffFunction *> __pieces;
public:
PiecewiseFunction(const std::list<const OneArgumentDiffFunction *>
&pieces = std::list<const OneArgumentDiffFunction *>(),
double deriv_x = Core::NaN);
void add_piece(const OneArgumentDiffFunction *piece);
double operator()(double x) const;
const FunctionDerivatives *deriv(double x) const
{return new PiecewiseFunction(__pieces, x);}
double order(unsigned deriv_order=1) const;
double range_high() const {return __range_high;}
double range_low() const {return __range_low;}
Core::InterpSolutionIterator crossings(double) const
{return Core::InterpSolutionIterator();}
};
class FunctionRatio: public Core::OneArgumentDiffFunction,
Core::FunctionDerivatives {
private:
double __deriv_x;
const OneArgumentDiffFunction *__f1, *__f2;
public:
FunctionRatio(const OneArgumentDiffFunction *f1,
const OneArgumentDiffFunction *f2,
double deriv_x = Core::NaN) :
__deriv_x(deriv_x), __f1(f1), __f2(f2) {}
double operator()(double x) const {return (*__f1)(x) / (*__f2)(x);}
const FunctionDerivatives *deriv(double x) const
{return new FunctionRatio(__f1, __f2, x);}
double order(unsigned deriv_order=1) const;
double range_high() const
{return std::min(__f1->range_high(), __f2->range_high());}
double range_low() const
{return std::max(__f1->range_low(), __f2->range_low());}
Core::InterpSolutionIterator crossings(double) const
{return Core::InterpSolutionIterator();}
};
class FunctionToPower : public Core::OneArgumentDiffFunction,
Core::FunctionDerivatives {
private:
const OneArgumentDiffFunction *__f;
double __power, __deriv_x;
public:
FunctionToPower(const OneArgumentDiffFunction *f,
double power,
double deriv_x = Core::NaN) :
__f(f), __power(power), __deriv_x(deriv_x) {}
double operator()(double x) const
{return std::pow((*__f)(x), __power);}
const FunctionDerivatives *deriv(double x) const
{return new FunctionToPower(__f, __power, x);}
double order(unsigned deriv_order=1) const;
double range_high() const {return __f->range_high();}
double range_low() const {return __f->range_low();}
Core::InterpSolutionIterator crossings(double) const
{return Core::InterpSolutionIterator();}
};
class ScaledFunction : public Core::OneArgumentDiffFunction,
Core::FunctionDerivatives {
private:
const OneArgumentDiffFunction *__f;
double __scale, __deriv_x;
public:
ScaledFunction(const OneArgumentDiffFunction *f,
double scale,
double deriv_x = Core::NaN) :
__f(f), __scale(scale), __deriv_x(deriv_x) {}
double operator()(double x) const
{return __scale*(*__f)(x);}
const FunctionDerivatives *deriv(double x) const
{return new ScaledFunction(__f, __scale, x);}
double order(unsigned deriv_order=1) const;
double range_high() const {return __f->range_high();}
double range_low() const {return __f->range_low();}
Core::InterpSolutionIterator crossings(double) const
{return Core::InterpSolutionIterator();}
};
class LogFunction : public Core::OneArgumentDiffFunction,
Core::FunctionDerivatives {
private:
const OneArgumentDiffFunction *__f;
double __deriv_x;
public:
LogFunction(const OneArgumentDiffFunction *f,
double deriv_x = Core::NaN) :
__f(f), __deriv_x(deriv_x) {}
double operator()(double x) const {return std::log((*__f)(x));}
const FunctionDerivatives *deriv(double x) const
{return new LogFunction(__f, x);}
double order(unsigned deriv_order=1) const;
double range_high() const {return __f->range_high();}
double range_low() const {return __f->range_low();}
Core::InterpSolutionIterator crossings(double) const
{return Core::InterpSolutionIterator();}
};
class CosFunction : public Core::OneArgumentDiffFunction,
Core::FunctionDerivatives {
private:
const OneArgumentDiffFunction *__f;
double __deriv_x;
public:
CosFunction(const OneArgumentDiffFunction *f,
double deriv_x = Core::NaN) :
__f(f), __deriv_x(deriv_x) {}
double operator()(double x) const {return std::cos((*__f)(x));}
const FunctionDerivatives *deriv(double x) const
{return new CosFunction(__f, x);}
double order(unsigned deriv_order=1) const;
double range_high() const {return __f->range_high();}
double range_low() const {return __f->range_low();}
Core::InterpSolutionIterator crossings(double) const
{return Core::InterpSolutionIterator();}
};
#if 0
std::valarray<double> tabulate_track(PolynomialEvolutionTrack *track,
std::valarray<double> ages, unsigned deriv_order=0);
double eval_poly(const std::valarray< std::valarray<double> > &poly_coef,
double mass, double age, double low_mass_age_scaling=0,
double high_mass_age_scaling=0, double scale_mass=NaN);
#endif
double solve(double guess_x,
double abs_precision,
double rel_precision,
double (*f)(double x, void *params),
double (*df) (double x, void *params),
void (*fdf) (double x, void *params, double *f, double *df),
void *params);
#endif