17#include "analysis/OrcaKinFit/BaseHardConstraint.h"
18#include <framework/logging/Logger.h>
32 namespace OrcaKinFit {
39 double dgdpi[BaseDefs::MAXINTERVARS];
40 for (
unsigned int i = 0; i <
fitobjects.size(); ++i) {
44 foi->addTo1stDerivatives(M, idim, dgdpi,
getGlobalNum(), getVarBasis());
87 double d2GdPidPj[BaseDefs::MAXINTERVARS * BaseDefs::MAXINTERVARS];
94 auto* dPidAk =
new double[n * BaseDefs::MAXPAR * BaseDefs::MAXINTERVARS];
95 bool* dPidAkval =
new bool[n];
97 for (
int i = 0; i < n; ++i) dPidAkval[i] =
false;
101 double d2GdPdAl[
static_cast<int>(BaseDefs::MAXINTERVARS) * BaseDefs::MAXPAR];
103 double d2GdAkdAl[BaseDefs::MAXPAR * BaseDefs::MAXPAR] = {0};
107 int* parglobal =
new int[BaseDefs::MAXPAR * n];
109 for (
int i = 0; i < n; ++i) {
112 for (
int klocal = 0; klocal < foi->
getNPar(); ++klocal) {
113 parglobal [BaseDefs::MAXPAR * i + klocal] = foi->
getGlobalParNum(klocal);
118 for (
int i = 0; i < n; ++i) {
121 for (
int j = 0; j < n; ++j) {
126 foi->getDerivatives(dPidAk + i * (
static_cast<int>(BaseDefs::MAXPAR) * BaseDefs::MAXINTERVARS),
127 static_cast<int>(BaseDefs::MAXPAR) * BaseDefs::MAXINTERVARS);
131 foj->getDerivatives(dPidAk + j * (
static_cast<int>(BaseDefs::MAXPAR) * BaseDefs::MAXINTERVARS),
132 static_cast<int>(BaseDefs::MAXPAR) * BaseDefs::MAXINTERVARS);
142 for (
int llocal = 0; llocal < foj->
getNPar(); ++llocal) {
143 for (
int ii = 0; ii < BaseDefs::MAXINTERVARS; ++ii) {
144 int ind1 = BaseDefs::MAXINTERVARS * ii;
145 int ind2 = (
static_cast<int>(BaseDefs::MAXPAR) * BaseDefs::MAXINTERVARS) * j + BaseDefs::MAXINTERVARS * llocal;
146 double& r = d2GdPdAl[BaseDefs::MAXINTERVARS * llocal + ii];
147 r = d2GdPidPj[ ind1] * dPidAk[ ind2];
148 r += d2GdPidPj[++ind1] * dPidAk[++ind2];
149 r += d2GdPidPj[++ind1] * dPidAk[++ind2];
150 r += d2GdPidPj[++ind1] * dPidAk[++ind2];
159 for (
int klocal = 0; klocal < foi->
getNPar(); ++klocal) {
160 for (
int llocal = 0; llocal < foj->
getNPar(); ++llocal) {
161 int ind1 = BaseDefs::MAXINTERVARS * llocal;
162 int ind2 = (
static_cast<int>(BaseDefs::MAXPAR) * BaseDefs::MAXINTERVARS) * i + BaseDefs::MAXINTERVARS * klocal;
163 double& r = d2GdAkdAl[BaseDefs::MAXPAR * klocal + llocal];
164 r = d2GdPdAl[ ind1] * dPidAk[ ind2];
165 r += d2GdPdAl[++ind1] * dPidAk[++ind2];
166 r += d2GdPdAl[++ind1] * dPidAk[++ind2];
167 r += d2GdPdAl[++ind1] * dPidAk[++ind2];
171 for (
int klocal = 0; klocal < foi->
getNPar(); ++klocal) {
172 int kglobal = parglobal [BaseDefs::MAXPAR * i + klocal];
173 for (
int llocal = 0; llocal < foj->
getNPar(); ++llocal) {
174 int lglobal = parglobal [BaseDefs::MAXPAR * j + llocal];
175 M [idim * kglobal + lglobal] += lambda * d2GdAkdAl[BaseDefs::MAXPAR * klocal + llocal];
190 double dgdpi[BaseDefs::MAXINTERVARS];
191 for (
int i = 0; i < n; ++i) {
195 foi->addTo2ndDerivatives(M, idim, lambda, dgdpi, getVarBasis());
206 double dgdpi[BaseDefs::MAXINTERVARS];
207 for (
unsigned int i = 0; i <
fitobjects.size(); ++i) {
219 double dgdpi[BaseDefs::MAXINTERVARS];
221 for (
unsigned int i = 0; i <
fitobjects.size(); ++i) {
225 error2 += foi->getError2(dgdpi, getVarBasis());
228 return std::sqrt(std::abs(error2));
236 for (pw = w; pw < w + idim; * (pw++) = 0);
239 for (pw = w, pp = p; pw < w + idim; result += *(pp++) * *(pw++));
246 if (val == 0)
return mu * std::fabs(
dirDer(p, w, idim, 1));
247 else if (val > 0)
return mu *
dirDer(p, w, idim, 1);
248 else return -mu *
dirDer(p, w, idim, 1);
252 void BaseHardConstraint::test1stDerivatives()
254 B2INFO(
"BaseConstraint::test1stDerivatives for " <<
getName());
256 for (
double& i : y) i = 0;
258 double eps = 0.00001;
259 for (
unsigned int ifo = 0; ifo <
fitobjects.size(); ++ifo) {
262 for (
int ilocal = 0; ilocal < fo->
getNPar(); ++ilocal) {
264 double calc = y[iglobal];
266 B2INFO(
"fo: " << fo->
getName() <<
" par " << ilocal <<
"/"
268 <<
") calc: " << calc <<
" - num: " << num <<
" = " << calc - num);
273 void BaseHardConstraint::test2ndDerivatives()
275 B2INFO(
"BaseConstraint::test2ndDerivatives for " <<
getName());
276 const int idim = 100;
277 auto* M =
new double[idim * idim];
278 for (
int i = 0; i < idim * idim; ++i) M[i] = 0;
281 B2INFO(
"eps=" << eps);
283 for (
unsigned int ifo1 = 0; ifo1 <
fitobjects.size(); ++ifo1) {
286 for (
unsigned int ifo2 = ifo1; ifo2 <
fitobjects.size(); ++ifo2) {
289 for (
int ilocal1 = 0; ilocal1 < fo1->getNPar(); ++ilocal1) {
290 int iglobal1 = fo1->getGlobalParNum(ilocal1);
291 for (
int ilocal2 = (ifo1 == ifo2 ? ilocal1 : 0); ilocal2 < fo2->getNPar(); ++ilocal2) {
292 int iglobal2 = fo2->getGlobalParNum(ilocal2);
293 double calc = M[idim * iglobal1 + iglobal2];
295 B2INFO(
"fo1: " << fo1->getName() <<
" par " << ilocal1 <<
"/"
296 << iglobal1 <<
" (" << fo1->getParamName(ilocal1)
297 <<
"), fo2: " << fo2->getName() <<
" par " << ilocal2 <<
"/"
298 << iglobal2 <<
" (" << fo2->getParamName(ilocal2)
299 <<
") calc: " << calc <<
" - num: " << num <<
" = " << calc - num);
317 double result = (v1 - v2) / (2 * eps);
323 int ifo2,
int ilocal2,
double eps2)
327 if (ifo1 == ifo2 && ilocal1 == ilocal2) {
330 double save = fo->
getParam(ilocal1);
336 result = (v1 + v2 - 2 * v0) / (eps1 * eps1);
343 double save1 = fo1->
getParam(ilocal1);
344 double save2 = fo2->
getParam(ilocal2);
345 fo1->
setParam(ilocal1, save1 + eps1);
346 fo2->
setParam(ilocal2, save2 + eps2);
348 fo2->
setParam(ilocal2, save2 - eps2);
350 fo1->
setParam(ilocal1, save1 - eps1);
352 fo2->
setParam(ilocal2, save2 + eps2);
354 result = (v11 + v22 - v12 - v21) / (4 * eps1 * eps2);
361 void BaseHardConstraint::printFirstDerivatives()
const
364 B2INFO(
"BaseHardConstraint::printFirstDerivatives " <<
fitobjects.size());
366 double dgdpi[BaseDefs::MAXINTERVARS];
367 for (
unsigned int i = 0; i <
fitobjects.size(); ++i) {
371 B2INFO(
"first derivs for obj " << i <<
" : ");
372 for (
double j : dgdpi)
380 void BaseHardConstraint::printSecondDerivatives()
const
383 double d2GdPidPj[BaseDefs::MAXINTERVARS * BaseDefs::MAXINTERVARS];
387 for (
int i = 0; i < n; ++i) {
390 for (
int j = 0; j < n; ++j) {
395 B2INFO(
"second derivs for objs " << i <<
" " << j);
398 for (
int k1 = 0; k1 < BaseDefs::MAXINTERVARS; k1++) {
399 for (
int k2 = 0; k2 < BaseDefs::MAXINTERVARS; k2++) {
400 B2INFO(d2GdPidPj[k++] <<
" ");
virtual const char * getName() const
Returns the name of the constraint.
virtual int getNPar() const =0
Get total number of parameters of this FitObject.
virtual const char * getParamName(int ilocal) const =0
Get name of parameter ilocal.
virtual bool setParam(int ilocal, double par_, bool measured_, bool fixed_=false)
Set value and measured flag of parameter i; return: significant change.
virtual int getGlobalParNum(int ilocal) const
Get global parameter number of parameter ilocal.
virtual const char * getName() const
Get object's name.
virtual double getParam(int ilocal) const
Get current value of parameter ilocal.
virtual int addToGlobalChi2DerVector(double *y, int idim) const
Add derivatives of chi squared to global derivative vector.
virtual int getGlobalNum() const
Accesses position of constraint in global constraint list.
virtual double getValue() const override=0
Returns the value of the constraint.
FitObjectContainer fitobjects
The FitObjectContainer.
virtual void add1stDerivativesToMatrix(double *M, int idim) const
Adds first order derivatives to global covariance matrix M.
virtual double getError() const override
Returns the error on the value of the constraint.
virtual void addToGlobalChi2DerVector(double *y, int idim, double lambda) const
Add lambda times derivatives of chi squared to global derivative vector.
virtual double dirDerAbs(double *p, double *w, int idim, double mu=1)
Calculate directional derivative for abs(c)
virtual double dirDer(double *p, double *w, int idim, double mu=1)
Calculate directional derivative.
virtual ~BaseHardConstraint() override
Virtual destructor.
virtual bool secondDerivatives(int i, int j, double *derivatives) const =0
Second derivatives with respect to the meta-variables of Fit objects i and j; result false if all der...
virtual bool firstDerivatives(int i, double *derivatives) const =0
First derivatives with respect to the meta-variables of Fit objects i; result false if all derivative...
virtual void add2ndDerivativesToMatrix(double *M, int idim, double lambda) const
Adds second order derivatives to global covariance matrix M.
virtual double num2ndDerivative(int ifo1, int ilocal1, double eps1, int ifo2, int ilocal2, double eps2)
Evaluates numerically the 2nd derivative w.r.t. 2 parameters.
virtual double num1stDerivative(int ifo, int ilocal, double eps)
Evaluates numerically the 1st derivative w.r.t. a parameter.
Abstract base class for different kinds of events.