26const double absoluteCutOff = 0.0;
27const double effectiveCutOff = 0.0001;
29double calculatePoissonLoss(
double observedCounts,
double predicted) {
30 double retVal = (predicted - observedCounts);
31 retVal += observedCounts * (log(observedCounts) - log(predicted));
53 size_t ny = values->size();
57 for (
size_t i = 0; i < ny; i++) {
58 const double predicted = values->getCalculated(i);
60 if (predicted <= absoluteCutOff) {
61 retVal = std::numeric_limits<double>::infinity();
65 const double observed = values->getFitData(i);
66 if (predicted <= effectiveCutOff) {
67 retVal += (effectiveCutOff - predicted) / predicted;
68 }
else if (observed == 0.0) {
72 retVal += calculatePoissonLoss(observed, predicted);
91 const size_t numParams =
nParams();
108 const size_t numParams = function.
nParams();
109 const size_t numDataPoints = domain.
size();
111 Jacobian jacobian(numDataPoints, numParams);
115 size_t activeParamIndex = 0;
116 double costVal = 0.0;
118 for (
size_t paramIndex = 0; paramIndex < numParams; ++paramIndex) {
122 double determinant = 0.0;
123 for (
size_t i = 0; i < numDataPoints; ++i) {
127 if (calc <= absoluteCutOff) {
128 if (activeParamIndex == 0) {
129 costVal += std::numeric_limits<double>::infinity();
131 determinant += std::numeric_limits<double>::infinity();
135 if (calc <= effectiveCutOff) {
136 if (activeParamIndex == 0) {
137 costVal += (effectiveCutOff - calc) / (calc - absoluteCutOff);
139 double tmp = calc - absoluteCutOff;
140 determinant += jacobian.
get(i, paramIndex) * (absoluteCutOff - effectiveCutOff) / (
tmp *
tmp);
142 }
else if (obs == 0.0) {
143 if (activeParamIndex == 0) {
146 determinant += jacobian.
get(i, paramIndex);
149 if (activeParamIndex == 0) {
150 costVal += calculatePoissonLoss(obs, calc);
152 determinant += jacobian.
get(i, paramIndex) * (1.0 - obs / calc);
156 double der =
m_der.
get(activeParamIndex);
157 m_der.
set(activeParamIndex, der + determinant);
168 size_t numParams = function.
nParams();
169 size_t numDataPoints = domain.
size();
171 Jacobian jacobian(numDataPoints, numParams);
174 size_t activeParamFirstIndex = 0;
175 for (
size_t paramIndex = 0; paramIndex < numParams; ++paramIndex) {
179 size_t activeParamSecondIndex = 0;
182 double scalingFactor = 1e-4;
183 if (parameter != 0.0) {
184 scalingFactor *= parameter;
187 function.
setParameter(paramIndex, parameter + scalingFactor);
188 Jacobian jacobian2(numDataPoints, numParams);
192 for (
size_t j = 0; j <= paramIndex; ++j)
197 for (
size_t k = 0; k < numDataPoints; ++k)
199 double d2 = (jacobian2.
get(k, j) - jacobian.
get(k, j)) / scalingFactor;
203 if (calc <= absoluteCutOff) {
204 d += std::numeric_limits<double>::infinity();
206 if (calc <= effectiveCutOff) {
207 double constrainedCalc = calc - absoluteCutOff;
208 d += d2 * (absoluteCutOff - effectiveCutOff) / (constrainedCalc * constrainedCalc);
209 d += jacobian.
get(k, paramIndex) * jacobian.
get(k, j) * (effectiveCutOff - absoluteCutOff) * 2 /
210 (constrainedCalc * constrainedCalc * constrainedCalc);
211 }
else if (obs == 0.0) {
214 d += d2 * (1.0 - obs / calc);
215 d += jacobian.
get(k, paramIndex) * jacobian.
get(k, j) * obs / (calc * calc);
220 double h =
m_hessian.
get(activeParamFirstIndex, activeParamSecondIndex) +
d;
221 m_hessian.
set(activeParamFirstIndex, activeParamSecondIndex, h);
222 if (activeParamFirstIndex != activeParamSecondIndex) {
223 m_hessian.
set(activeParamSecondIndex, activeParamFirstIndex, h);
226 ++activeParamSecondIndex;
228 ++activeParamFirstIndex;
#define DECLARE_COSTFUNCTION(classname, username)
Macro for declaring a new type of cost functions to be used with the CostFunctionFactory.
#define PARALLEL_CRITICAL(name)
Base class that represents the domain of a function.
virtual size_t size() const =0
Return the number of points in the domain.
A class to store values calculated by a function.
double getFitData(size_t i) const
Get a fitting data value.
double getCalculated(size_t i) const
Get i-th calculated value.
This is an interface to a fitting function - a semi-abstarct class.
virtual void functionDeriv(const FunctionDomain &domain, Jacobian &jacobian)
Derivatives of function with respect to active parameters.
virtual size_t nParams() const =0
Total number of parameters.
bool isActive(size_t i) const
Check if an active parameter i is actually active.
virtual double getParameter(size_t i) const =0
Get i-th parameter.
virtual void setParameter(size_t, const double &value, bool explicitlySet=true)=0
Set i-th parameter.
virtual void function(const FunctionDomain &domain, FunctionValues &values) const =0
Evaluates the function for all arguments in the domain.
Represents the Jacobian in IFitFunction::functionDeriv.
virtual double get(size_t iY, size_t iP)=0
Get the value to a Jacobian matrix element.
A semi-abstract class for a cost function for fitting functions.
size_t nParams() const override
Number of parameters.
API::IFunction_sptr m_function
Shared pointer to the fitting function.
CostFuncPoisson : Implements a cost function for fitting applications using a Poisson measure.
void calculateHessian(API::IFunction &function, const API::FunctionDomain &domain, const API::FunctionValues &values) const
Calculates the Hessian matrix for the addValDerivHessian method.
void addValDerivHessian(API::IFunction_sptr function, API::FunctionDomain_sptr domain, API::FunctionValues_sptr values, bool evalDeriv=true, bool evalHessian=true) const override
Update the cost function, derivatives and hessian by adding values calculated on a domain.
void addVal(API::FunctionDomain_sptr domain, API::FunctionValues_sptr values) const override
Add a contribution to the cost function value from the fitting function evaluated on a particular dom...
void calculateDerivative(API::IFunction &function, const API::FunctionDomain &domain, API::FunctionValues &values) const
Calculates the derivative for the addValDerivHessian method.
void set(size_t i, size_t j, double value)
Set an element.
double get(size_t i, size_t j) const
Get an element.
void zero()
Set all elements to zero.
void resize(const size_t nx, const size_t ny)
Resize the matrix.
void set(const size_t i, const double value)
Set an element.
double get(const size_t i) const
Get an element.
void resize(const size_t n)
Resize the vector.
std::shared_ptr< FunctionValues > FunctionValues_sptr
typedef for a shared pointer
std::shared_ptr< IFunction > IFunction_sptr
shared pointer to the function base class
std::shared_ptr< FunctionDomain > FunctionDomain_sptr
typedef for a shared pointer