50#define G_LIKELIHOOD "GObservation::likelihood(GModels&, GVector*,"\
51 " GMatrixSparse*, double*)"
52#define G_MODEL1 "GObservation::model(GModels&, GEvent&, GVector*)"
53#define G_MODEL2 "GObservation::model(GModels&, GMatrixSparse*)"
54#define G_EVENTS "GObservation::events()"
55#define G_NPRED "GObservation::npred(GModel&)"
56#define G_NPRED_SPEC "GObservation::npred_spec(GModel&, GTime&)"
65#define G_LN_ENERGY_INT
66#define G_MODEL_COLUMN_FILL
67#define G_MODEL_SPARSE_VECTOR
68#define G_LIKELIHOOD_SPARSE_VECTOR
180 std::string msg =
"No events allocated for observation.";
201 std::string msg =
"No events allocated for observation.";
274 std::string msg =
"Invalid statistic \""+
statistic+
"\". Unbinned "
275 "optimization requires \"POISSON\" or \"CSTAT\" "
303 std::string msg =
"Invalid statistic \""+
statistic+
"\". Binned "
304 "optimization requires \"POISSON\", \"CSTAT\", "
305 "\"GAUSSIAN\" or \"CHI2\" statistic.";
347 bool use_grad = (gradients != NULL);
355 grad_size = gradients->
size();
364 for (
int i = 0; i < models.
size(); ++i) {
367 const GModel* mptr = models[i];
375 model += mptr->
eval(event, *
this, use_grad);
381 #if defined(G_RANGE_CHECK)
382 if (igrad+mptr->
size() > grad_size) {
383 std::string msg =
"Vector has not enough elements to "
384 "store the model parameter gradients. "+
386 "requested while vector only contains "+
401 for (
int index = 0; index < npars; ++index) {
412 (*gradients)[igrad+ipar] =
416 (*gradients)[igrad+ipar] =
421 (*gradients)[igrad+ipar] = 0.0;
432 for (
int ipar = 0; ipar < mptr->
size(); ++ipar) {
440 (*gradients)[igrad+ipar] =
444 (*gradients)[igrad+ipar] =
449 (*gradients)[igrad+ipar] = 0.0;
461 igrad += mptr->
size();
496 bool use_grad = (gradients != NULL);
503 #if defined(G_MODEL_SPARSE_VECTOR)
517 int ncolumns = (nevents > 0) ? models.
npars() : 0;
518 if (gradients->
columns() != ncolumns) {
520 "columns in gradient matrix differs from expected "
522 "specify compatible arguments.";
527 int nrows = (ncolumns > 0) ? nevents : 0;
528 if (gradients->
rows() != nrows) {
530 "rows in gradient matrix differs from expected "
532 "specify compatible arguments.";
537 #if defined(G_MODEL_COLUMN_FILL)
544 for (
int i = 0; i < models.
size(); ++i) {
547 const GModel* mptr = models[i];
559 values += mptr->
eval(*
this, NULL);
565 else if (nevents > 0) {
574 values += mptr->
eval(*
this, &grads);
588 for (
int index = 0; index < npars; ++index) {
610 #if defined(G_MODEL_COLUMN_FILL)
613 gradients->
column(igrad+ipar, grad);
626 for (
int ipar = 0; ipar < mptr->
size(); ++ipar) {
639 #if defined(G_DEBUG_VECTOR_MODEL_GRADIENTS)
642 for (
int k = 0; k < nevents; ++k) {
643 if (grad[k] != 0.0 || num_grad[k] != 0.0) {
644 std::cout <<
"ipar=" << ipar;
645 std::cout <<
" par=" << par.
name();
646 std::cout <<
" k=" << k;
647 std::cout <<
" ana=" << grad[k];
648 std::cout <<
" num=" << num_grad[k];
649 std::cout << std::endl;
660 #if defined(G_MODEL_COLUMN_FILL)
663 gradients->
column(igrad+ipar, grad);
677 igrad += mptr->
size();
684 #if defined(G_MODEL_COLUMN_FILL)
739 #if defined(G_RANGE_CHECK)
740 if (gradients != NULL) {
741 if (models.
npars() != gradients->
size()) {
742 std::string msg =
"Model parameter gradients vector size "+
745 " model parameters. Please specify a gradients "
746 "vector with the appropriate size.";
757 if (gradients != NULL) {
762 for (
int i = 0; i < models.
size(); ++i) {
765 const GModel* mptr = models[i];
776 if (gradients != NULL) {
777 for (
int k = 0; k < mptr->
size(); ++k) {
779 (*gradients)[igrad+k] =
npred_grad(*mptr, par);
786 igrad += mptr->
size();
846 if (
model.is_constant()) {
865 for (
int i = 0; i <
events()->
gti().size(); ++i) {
868 double tstart =
events()->
gti().tstart(i).secs();
869 double tstop =
events()->
gti().tstop(i).secs();
872 if (tstop <= tstart) {
873 std::string msg =
"Start time "+
875 " is past the stop time "+
877 " for Good Time Interval "+
879 "that all Good Time Intervals have start "
880 "times that are earlier than the stop "
918 const GEvent& event)
const
1048 gradients = (fs1 - fs2) / h;
1065 gradients = (fs1 - fs2) / h;
1080 gradients = 0.5 * (fs1 - fs2) / h;
1217 std::string cache_id =
id() +
":" +
name;
1245 std::string
id =
model.name() +
":" + par.
name();
1275 bool in_stack =
false;
1278 std::string
id =
model.name() +
":" + par.
name();
1405 double* npred)
const
1412 int npars = gradients->
size();
1415 int* inx =
new int[npars];
1416 double* values =
new double[npars];
1421 double npred_value = this->
npred(models, &wrk_grad);
1424 value += npred_value;
1425 *
npred += npred_value;
1426 *gradients += wrk_grad;
1429 GVector model_vector = this->
model(models, &wrk_matrix);
1435 for (
int i = 0; i < nevents; ++i) {
1443 double model = model_vector[i];
1456 for (
int ipar = 0; ipar < npars; ++ipar) {
1466 value -= std::log(
model);
1474 double fb = 1.0 /
model;
1475 double fa = fb /
model;
1476 for (
int jdev = 0; jdev < ndev; ++jdev) {
1479 register int jpar = inx[jdev];
1480 double g = wrk_grad[jpar];
1481 double fa_i = fa * g;
1484 (*gradients)[jpar] -= fb * g;
1487 register int* ipar = inx;
1489 for (
register int idev = 0; idev < ndev; ++idev, ++ipar) {
1490 values[idev] = fa_i * wrk_grad[*ipar];
1501 if (values != NULL)
delete [] values;
1502 if (inx != NULL)
delete [] inx;
1538 double* npred)
const
1544 #if defined(G_OPT_DEBUG)
1547 int n_small_model = 0;
1548 int n_zero_data = 0;
1549 int n_exclude_data = 0;
1550 double sum_data = 0.0;
1551 double sum_model = 0.0;
1552 double init_value = value;
1557 int npars = gradients->
size();
1560 int* inx =
new int[npars];
1561 double* values =
new double[npars];
1562 #if defined(G_LIKELIHOOD_SPARSE_VECTOR)
1563 double* grads =
new double[npars];
1566 #if defined(G_LIKELIHOOD_SPARSE_VECTOR)
1573 GVector model_vector = this->
model(models, &wrk_matrix);
1579 for (
int i = 0; i < nevents; ++i) {
1587 #if defined(G_OPT_DEBUG)
1596 double data = bin->
counts();
1600 #if defined(G_OPT_DEBUG)
1607 double model = model_vector[i] * bin->
size();
1611 #if defined(G_OPT_DEBUG)
1618 #if defined(G_OPT_DEBUG)
1633 double binsize = bin->
size();
1634 #if defined(G_LIKELIHOOD_SPARSE_VECTOR)
1635 for (
int ipar = 0; ipar < wrk_grad.
elements(); ++ipar) {
1637 grads[ipar] = wrk_grad.
data(ipar);
1639 grads[ipar] *= binsize;
1640 inx[ndev] = wrk_grad.
inx(ipar);
1645 for (
int ipar = 0; ipar < npars; ++ipar) {
1648 wrk_grad[ipar] *= binsize;
1672 double fb = data /
model;
1673 double fc = (1.0 - fb);
1674 double fa = fb /
model;
1677 for (
int jdev = 0; jdev < ndev; ++jdev) {
1680 register int jpar = inx[jdev];
1681 #if defined(G_LIKELIHOOD_SPARSE_VECTOR)
1682 double g = grads[jdev];
1684 double g = wrk_grad[jpar];
1686 double fa_i = fa * g;
1689 (*gradients)[jpar] += fc * g;
1692 #if defined(G_LIKELIHOOD_SPARSE_VECTOR)
1693 for (
register int idev = 0; idev < ndev; ++idev) {
1694 values[idev] = fa_i * grads[idev];
1697 register int* ipar = inx;
1698 for (
register int idev = 0; idev < ndev; ++idev, ++ipar) {
1699 values[idev] = fa_i * wrk_grad[*ipar];
1714 #if defined(G_OPT_DEBUG)
1728 register int* ipar = inx;
1729 #if defined(G_LIKELIHOOD_SPARSE_VECTOR)
1730 for (
register int idev = 0; idev < ndev; ++idev, ++ipar) {
1731 (*gradients)[*ipar] += grads[idev];
1734 for (
register int idev = 0; idev < ndev; ++idev, ++ipar) {
1735 (*gradients)[*ipar] += wrk_grad[*ipar];
1744 #if defined(G_LIKELIHOOD_SPARSE_VECTOR)
1745 if (grads != NULL)
delete [] grads;
1747 if (values != NULL)
delete [] values;
1748 if (inx != NULL)
delete [] inx;
1751 #if defined(G_OPT_DEBUG)
1752 std::cout <<
"Number of bins: " << n_bins << std::endl;
1753 std::cout <<
"Number of bins used for computation: " << n_used << std::endl;
1754 std::cout <<
"Number of bins excluded from data: " << n_exclude_data << std::endl;
1755 std::cout <<
"Number of bins excluded due to small model: " << n_small_model << std::endl;
1756 std::cout <<
"Number of bins with zero data: " << n_zero_data << std::endl;
1757 std::cout <<
"Sum of data: " << sum_data << std::endl;
1758 std::cout <<
"Sum of model: " << sum_model << std::endl;
1759 std::cout <<
"Initial statistic: " << init_value << std::endl;
1760 std::cout <<
"Statistic: " << value-init_value << std::endl;
1798 double* npred)
const
1805 int npars = gradients->
size();
1808 int* inx =
new int[npars];
1809 double* values =
new double[npars];
1810 #if defined(G_LIKELIHOOD_SPARSE_VECTOR)
1811 double* grads =
new double[npars];
1814 #if defined(G_LIKELIHOOD_SPARSE_VECTOR)
1821 GVector model_vector = this->
model(models, &wrk_matrix);
1827 for (
int i = 0; i < nevents; ++i) {
1839 double data = bin->
counts();
1847 double sigma = bin->
error();
1855 double model = model_vector[i] * bin->
size();
1871 double binsize = bin->
size();
1872 #if defined(G_LIKELIHOOD_SPARSE_VECTOR)
1873 for (
int ipar = 0; ipar < wrk_grad.
elements(); ++ipar) {
1875 grads[ipar] = wrk_grad.
data(ipar);
1877 grads[ipar] *= binsize;
1878 inx[ndev] = wrk_grad.
inx(ipar);
1883 for (
int ipar = 0; ipar < npars; ++ipar) {
1886 wrk_grad[ipar] *= binsize;
1894 double weight = 1.0 / (sigma * sigma);
1897 double fa = data -
model;
1898 value += 0.5 * (fa * fa * weight);
1906 for (
int jdev = 0; jdev < ndev; ++jdev) {
1909 register int jpar = inx[jdev];
1910 #if defined(G_LIKELIHOOD_SPARSE_VECTOR)
1911 double fa_i = grads[jdev] * weight;
1913 double fa_i = wrk_grad[jpar] * weight;
1917 (*gradients)[jpar] -= fa * fa_i;
1920 #if defined(G_LIKELIHOOD_SPARSE_VECTOR)
1921 for (
register int idev = 0; idev < ndev; ++idev) {
1922 values[idev] = fa_i * grads[idev];
1925 register int* ipar = inx;
1926 for (
register int idev = 0; idev < ndev; ++idev, ++ipar) {
1927 values[idev] = fa_i * wrk_grad[*ipar];
1939 #if defined(G_LIKELIHOOD_SPARSE_VECTOR)
1940 if (grads != NULL)
delete [] grads;
1942 if (values != NULL)
delete [] values;
1943 if (inx != NULL)
delete [] inx;
2005 m_par->factor_value(x);
2008 double npred = m_parent->npred(*m_model);
2027 return (m_parent->npred_spec(*m_model, time));
2068 const GTime& obsTime)
const
2071 static const int iter = 8;
2074 double result = 0.0;
2080 for (
int i = 0; i < ebounds.
size(); ++i) {
2083 double emin = ebounds.
emin(i).
MeV();
2084 double emax = ebounds.
emax(i).
MeV();
2097 #if defined(G_LN_ENERGY_INT)
2098 emin = std::log(emin);
2099 emax = std::log(emax);
2101 result += integral.
romberg(emin, emax);
2108 #if defined(G_NAN_CHECK)
2110 std::cout <<
"*** ERROR: GObservation::npred_spec:";
2111 std::cout <<
" NaN/Inf encountered";
2112 std::cout <<
" (result=" << result;
2113 std::cout <<
")" << std::endl;
2135 #if defined(G_LN_ENERGY_INT)
2136 double expx = std::exp(x);
2143 double value = m_model->npred(eng, *m_time, *m_parent);
2146 #if defined(G_NAN_CHECK)
2147 double value_out = value;
2151 #if defined(G_LN_ENERGY_INT)
2156 #if defined(G_NAN_CHECK)
2158 std::cout <<
"*** ERROR: GObservation::npred_spec_kern::eval";
2159 std::cout <<
"(x=" << x <<
"): ";
2160 std::cout <<
" NaN/Inf encountered";
2161 std::cout <<
" (value=" << value;
2162 std::cout <<
" (value_out=" << value_out;
2163 #if defined(G_LN_ENERGY_INT)
2164 std::cout <<
" exp(x)=" << expx;
2166 std::cout <<
")" << std::endl;
GDerivative class interface definition.
Abstract event bin base class definition.
Abstract event bin container class interface definition.
Abstract event atom container class interface definition.
Exception handler interface definition.
Integration class interface definition.
Sparse matrix class definition.
Abstract data model base class interface definition.
Model parameter class interface definition.
Sky model class interface definition.
Abstract model base class interface definition.
Model container class definition.
const double minerr
Minimum statistical error.
const double minmod
Minimum model value.
Abstract observation base class interface definition.
Abstract response base class definition.
Sparce vector class interface definition.
Vector class interface definition.
Numerical derivatives class.
double left_difference(const double &x, const double &h)
Returns gradient computed from left-sided function difference.
double right_difference(const double &x, const double &h)
Returns gradient computed from right-sided function difference.
double difference(const double &x, const double &h)
Returns gradient computed from symmetric function difference.
Energy boundaries container class.
const GEnergy & emax(void) const
Return maximum energy of all intervals.
int size(void) const
Return number of energy boundaries.
const GEnergy & emin(void) const
Return minimum energy of all intervals.
Class that handles energies in a unit independent way.
double MeV(void) const
Return energy in MeV.
Abstract interface for the event bin class.
virtual double error(void) const =0
Return error in number of counts.
virtual double counts(void) const =0
virtual double size(void) const =0
Abstract event bin container class.
Abstract event atom container class.
Abstract interface for the event classes.
Abstract event container class.
virtual double number(void) const =0
void gti(const GGti >i)
Set Good Time Intervals.
void ebounds(const GEbounds &ebounds)
Set energy boundaries.
virtual int size(void) const =0
virtual GEvents * clone(void) const =0
Clones object.
GIntegral class interface definition.
double romberg(std::vector< double > bounds, const int &order=5)
Perform Romberg integration.
void fixed_iter(const int &iter)
Set fixed number of iterations.
const int & rows(void) const
Return number of matrix rows.
const int & columns(void) const
Return number of matrix columns.
Sparse matrix class interface definition.
virtual GVector column(const int &column) const
Extract column as vector from matrix.
GMatrixSparse transpose(void) const
Return transposed matrix.
void stack_destroy(void)
Destroy matrix stack.
virtual void add_to_column(const int &column, const GVector &vector)
Add vector column into matrix.
void stack_init(const int &size=0, const int &entries=0)
Initialises matrix filling stack.
void column_to_vector(const int &column, GVector *vector) const
Extract matrix into vector.
void colfill_set_column(const int &column, const GVector &vector)
Set column for column filling.
void colfill_flush(void)
Flush column filling memory into sparse matrix.
void colfill_init(void) const
Initialise memory for column filling.
const bool & has_eval_indices(void) const
Signals that parameter indices updated by eval() method were set.
bool is_valid(const std::string &instruments, const std::string &ids) const
Verifies if model is valid for a given instrument and identifier.
int size(void) const
Return number of parameters in model.
virtual double eval(const GEvent &event, const GObservation &obs, const bool &gradients=false) const =0
const std::vector< int > & eval_indices(void) const
Return vector of parameter indices updated by eval() method.
int size(void) const
Return number of models in container.
int npars(void) const
Return number of model parameters in container.
GModelPar * m_par
Model parameter.
const GModel * m_model
Model.
const GObservation * m_parent
Observation.
double eval(const double &x)
Model function evaluation for gradient computation.
const GEvent * m_event
Event.
double eval(const double &x)
Npred function evaluation for gradient computation.
double eval(const double &x)
Integration kernel for npred() method.
double eval(const double &x)
Integration kernel for npred_spec() method.
Abstract observation base class.
std::string m_statistic
Optimizer statistic.
virtual double ontime(void) const =0
const std::string & statistic(void) const
Return optimizer statistic.
virtual double npred(const GModels &models, GVector *gradients=NULL) const
Return total number (and optionally gradients) of predicted counts for all models.
virtual double model(const GModels &models, const GEvent &event, GVector *gradients=NULL) const
Return model value and (optionally) gradients.
void copy_members(const GObservation &obs)
Copy class members.
const std::string & id(void) const
Return observation identifier.
virtual double likelihood(const GModels &models, GVector *gradients, GMatrixSparse *curvature, double *npred) const
Compute likelihood function.
const std::string & name(void) const
Return observation name.
virtual double nobserved(void) const
Return total number of observed events.
virtual bool use_event_for_likelihood(const int &index) const
Check whether bin should be used for likelihood analysis.
virtual ~GObservation(void)
Destructor.
GObservation(void)
Void constructor.
virtual double likelihood_poisson_unbinned(const GModels &models, GVector *gradients, GMatrixSparse *curvature, double *npred) const
Evaluate log-likelihood function for Poisson statistic and unbinned analysis (version with working ar...
virtual GEvents * events(void)
Return events.
virtual double likelihood_gaussian_binned(const GModels &models, GVector *gradients, GMatrixSparse *curvature, double *npred) const
Evaluate log-likelihood function for Gaussian statistic and binned analysis (version with working arr...
void computed_gradient(const GModel &model, const GModelPar &par) const
Signals that an analytical gradient was computed for a model parameter.
virtual const GResponse * response(void) const =0
bool has_gradient(const GModel &model, const GModelPar &par) const
Check whether a model parameter has an analytical gradient.
void init_members(void)
Initialise class members.
virtual double likelihood_poisson_binned(const GModels &models, GVector *gradients, GMatrixSparse *curvature, double *npred) const
Evaluate log-likelihood function for Poisson statistic and binned analysis (version with working arra...
virtual double npred_spec(const GModel &model, const GTime &obsTime) const
Integrates spatially integrated Npred kernel spectrally.
virtual double grad_step_size(const GModelPar &par) const
Return gradient step size for a given model parameter.
virtual GObservation & operator=(const GObservation &obs)
Assignment operator.
std::vector< std::string > m_pars_with_gradients
GEvents * m_events
Pointer to event container.
virtual std::string instrument(void) const =0
void free_members(void)
Delete class members.
virtual void remove_response_cache(const std::string &name)
Remove response cache for specific model.
std::string m_name
Observation name.
virtual double npred_grad(const GModel &model, const GModelPar &par) const
Returns parameter gradient of Npred.
virtual double model_grad(const GModel &model, const GModelPar &par, const GEvent &event) const
Returns parameter gradient of model for a given event.
std::string m_id
Observation identifier.
const double & factor_max(void) const
Return parameter maximum factor boundary.
const double & factor_value(void) const
Return parameter factor value.
bool is_free(void) const
Signal if parameter is free.
bool has_min(void) const
Signal if parameter has minimum boundary.
const double & factor_gradient(void) const
Return parameter factor gradient.
bool has_max(void) const
Signal if parameter has maximum boundary.
const double & factor_min(void) const
Return parameter minimum factor boundary.
const std::string & name(void) const
Return parameter name.
Abstract instrument response base class.
const double & secs(void) const
Return time in seconds in native reference (TT)
const int & inx(const int &index) const
Return inx for sparse vector element.
const double & data(const int &index) const
Return value for sparse vector element.
const int & elements(void) const
Return number of elements in sparse vector.
const int & size(void) const
Return size of vector.
bool is_infinite(const double &x)
Signal if argument is infinite.
bool is_notanumber(const double &x)
Signal if argument is not a number.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
std::string toupper(const std::string &s)
Convert string to upper case.