Jpp 21.0.0-rc.1-88-g0130508c4
the software that should make you happy
Loading...
Searching...
No Matches
JFIT::JGradient Struct Reference

Conjugate gradient fit. More...

#include <JGradient.hh>

Inheritance diagram for JFIT::JGradient:
std::vector< JModifier_t >

Public Member Functions

 JGradient (const size_t Nmax=std::numeric_limits< size_t >::max(), const size_t Nextra=0, const double epsilon=1.0e-4, const int debug=3)
 Constructor.
 
template<class T >
double operator() (const T &getChi2)
 Fit.
 
template<class T >
void operator() (std::ostream &out, const T &getChi2, const std::vector< double > &xs) const
 Make scan at current position.
 

Public Attributes

size_t Nmax
 maximum number of iterations
 
size_t Nextra
 maximum number of extra steps
 
double epsilon
 epsilon
 
int debug
 debug
 
bool absolute = false
 absolute chi2
 
bool normalise = false
 normalise gradient
 
size_t numberOfIterations
 

Private Member Functions

template<class T >
double evaluate (const T &getChi2)
 Evaluate gradient.
 
void move (const double factor)
 Move.
 
template<class T >
void scan (std::ostream &out, const T &getChi2, const std::vector< double > &xs, std::vector< double > &ys) const
 Scan.
 

Private Attributes

std::vector< double > gradient
 

Detailed Description

Conjugate gradient fit.

Definition at line 74 of file JGradient.hh.

Constructor & Destructor Documentation

◆ JGradient()

JFIT::JGradient::JGradient ( const size_t Nmax = std::numeric_limits<size_t>::max(),
const size_t Nextra = 0,
const double epsilon = 1.0e-4,
const int debug = 3 )
inline

Constructor.

The number of iterations and epsilon refer to the number of steps and the distance to the minimum, respectively.
The number of extra steps can be used to overcome a possible hurdle on the way.

Parameters
Nmaxmaximum number of iterations
Nextramaximum number of extra steps
epsilonepsilon
debugdebug

Definition at line 89 of file JGradient.hh.

92 :
93 Nmax (Nmax),
94 Nextra (Nextra),
96 debug (debug)
97 {}
size_t Nmax
maximum number of iterations
Definition JGradient.hh:295
double epsilon
epsilon
Definition JGradient.hh:297
size_t Nextra
maximum number of extra steps
Definition JGradient.hh:296

Member Function Documentation

◆ operator()() [1/2]

template<class T >
double JFIT::JGradient::operator() ( const T & getChi2)
inline

Fit.

The template parameter should provide for the following function operator.

   double operator()(int option);

The value of the option corresponds to the following cases.

  • 0 => step wise improvement of the chi2;
  • 1 => evaluation of the chi2 before the determination of the gradient of the chi2; and
  • 2 => evaluation of the derivative of the chi2 to each fit parameter.
Parameters
getChi2chi2 function
Returns
chi2

Definition at line 116 of file JGradient.hh.

117 {
118 using namespace std;
119 using namespace JPP;
120
121 vector<double> chi2(5, numeric_limits<double>::max());
122
123 if (this->empty()) {
124 return numeric_limits<double>::max();
125 }
126
127 chi2[0] = this->evaluate(getChi2);
128
129 const size_t N = this->size();
130
131 vector<double> H(N);
132 vector<double> G(N);
133
134 for (size_t i = 0; i != N; ++i) {
135 G[i] = -1.0 * gradient[i];
136 H[i] = G[i];
137 gradient[i] = H[i];
138 }
139
141
143
144 DEBUG("chi2[0] " << setw(4) << numberOfIterations << ' ' << FIXED(12,5) << chi2[0] << endl);
145
146 // minimise chi2 in direction of gradient
147
148 chi2[1] = chi2[0];
149 chi2[2] = chi2[1];
150
151 size_t m = 0;
152
153 for (double ds = 1.0; ds > 1.0e-3; ) {
154
155 this->move(+1.0 * ds);
156
157 chi2[3] = getChi2(0);
158
159 DEBUG("chi2[3] " << setw(4) << m << ' ' << FIXED(12,5) << chi2[3] << ' ' << FIXED(12,5) << ds << endl);
160
161 if (chi2[3] < chi2[2]) {
162
163 chi2[1] = chi2[2];
164 chi2[2] = chi2[3];
165
166 m = 0;
167
168 continue;
169 }
170
171 if (ds == 1.0) {
172
173 if (m == 0) {
174 chi2[4] = chi2[3];
175 }
176
177 if (m != Nextra) {
178
179 ++m;
180
181 continue;
182
183 } else {
184
185 for ( ; m != 0; --m) {
186 this->move(-1.0 * ds);
187 }
188
189 chi2[3] = chi2[4];
190 }
191 }
192
193 this->move(-1.0 * ds);
194
195 if (chi2[2] < chi2[3]) {
196
197 // final step based on parabolic interpolation through following points
198 //
199 // x1 = -1 * ds -> chi2[1]
200 // x2 = 0 * ds -> chi2[2]
201 // x3 = +1 * ds -> chi2[3]
202
203 const double f21 = chi2[2] - chi2[1]; // f(x2) - f(x1)
204 const double f23 = chi2[2] - chi2[3]; // f(x2) - f(x3)
205
206 const double xs = 0.5 * (f21 - f23) / (f23 + f21);
207
208 this->move(+1.0 * xs * ds);
209
210 chi2[3] = getChi2(0);
211
212 if (chi2[3] < chi2[2]) {
213
214 chi2[2] = chi2[3];
215
216 } else {
217
218 this->move(-1.0 * xs * ds);
219
220 chi2[2] = getChi2(0);
221 }
222
223 DEBUG("chi2[2] " << setw(4) << numberOfIterations << ' ' << FIXED(12,5) << chi2[2] << ' ' << SCIENTIFIC(12,5) << ds << endl);
224
225 break;
226
227 } else {
228
229 ds *= 0.5;
230 }
231 }
232
233 if (fabs(chi2[2] - chi2[0]) < epsilon * (absolute ? 1.0 : 0.5 * (fabs(chi2[0]) + fabs(chi2[2])))) {
234
235 chi2[0] = chi2[2];
236
237 break;
238 }
239
240 chi2[0] = this->evaluate(getChi2);
241
242 double gg = 0.0;
243 double dgg = 0.0;
244
245 for (size_t i = 0; i != N; ++i){
246 gg += G[i]*G[i];
247 dgg += (gradient[i] + G[i]) * gradient[i];
248 }
249
250 if (gg == 0.0) {
251 break;
252 }
253
254 dgg /= gg;
255
256 for (size_t i = 0; i != N; ++i){
257 G[i] = -1.0 * gradient[i];
258 H[i] = G[i] + dgg * H[i];
259 gradient[i] = H[i];
260 }
261 }
262
263 DEBUG("chi2[0] " << setw(4) << numberOfIterations << ' ' << FIXED(12,5) << chi2[0] << endl);
264
265 return chi2[0];
266 }
#define DEBUG(A)
Message macros.
Definition JMessage.hh:62
double getChi2(const double P)
Get chi2 corresponding to given probability.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary data structure for floating point format specification.
Definition JManip.hh:448
void move(const double factor)
Move.
Definition JGradient.hh:383
std::vector< double > gradient
Definition JGradient.hh:439
bool absolute
absolute chi2
Definition JGradient.hh:300
double evaluate(const T &getChi2)
Evaluate gradient.
Definition JGradient.hh:312
size_t numberOfIterations
Definition JGradient.hh:303
Auxiliary data structure for floating point format specification.
Definition JManip.hh:488

◆ operator()() [2/2]

template<class T >
void JFIT::JGradient::operator() ( std::ostream & out,
const T & getChi2,
const std::vector< double > & xs ) const
inline

Make scan at current position.

Parameters
outoutput stream
getChi2chi2 function
xsset of steps

Definition at line 277 of file JGradient.hh.

278 {
279 using namespace std;
280
281 out << "scan: ";
282
283 for (const auto& i : *this) {
284 out << i.name << ' ';
285 }
286
287 out << "chi2" << endl;
288
290
291 scan(out, getChi2, xs, ys);
292 }
void scan(std::ostream &out, const T &getChi2, const std::vector< double > &xs, std::vector< double > &ys) const
Scan.
Definition JGradient.hh:406

◆ evaluate()

template<class T >
double JFIT::JGradient::evaluate ( const T & getChi2)
inlineprivate

Evaluate gradient.

Returns
chi2

Definition at line 312 of file JGradient.hh.

313 {
314 using namespace std;
315 using namespace JPP;
316
317 const size_t N = this->size();
318
319 gradient.resize(N);
320
321 for (std::vector<double>::iterator i = gradient.begin(); i != gradient.end(); ++i) {
322 *i = 0.0;
323 }
324
325 const double x0 = getChi2(1);
326
327 size_t width = 1;
328
329 for (size_t i = 0; i != N; ++i) {
330 if ((*this)[i].name.size() > width) {
331 width = (*this)[i].name.size();
332 }
333 }
334
335 double V = 0.0;
336
337 for (size_t i = 0; i != N; ++i) {
338
339 if ((*this)[i].value != 0.0) {
340
341 (*this)[i]->apply(+0.5 * (*this)[i].value);
342
343 const double x1 = getChi2(2);
344
345 (*this)[i]->apply(-0.5 * (*this)[i].value);
346 (*this)[i]->apply(-0.5 * (*this)[i].value);
347
348 const double x2 = getChi2(2);
349
350 gradient[i] = x1 - x2;
351
352 (*this)[i]->apply(+0.5 * (*this)[i].value);
353
354 DEBUG(setw(width) << left << (*this)[i].name << right << ' ' << FIXED(12,5) << (*this)[i].value << ' ' << FIXED(12,5) << gradient[i] << endl);
355
356 } else {
357
358 gradient[i] = 0.0;
359 }
360
361 V += gradient[i] * gradient[i];
362 }
363
364 V = sqrt(V);
365
366 DEBUG(setw(width) << left << "|gradient|" << right << ' ' << FIXED(12,5) << V << endl);
367
368 if (normalise) {
369 for (size_t i = 0; i != N; ++i) {
370 gradient[i] /= V;
371 }
372 }
373
374 return x0;
375 }
bool normalise
normalise gradient
Definition JGradient.hh:301

◆ move()

void JFIT::JGradient::move ( const double factor)
inlineprivate

Move.

Parameters
factorfactor

Definition at line 383 of file JGradient.hh.

384 {
385 if (factor > 0.0) {
386 for (size_t i = 0; i != this->size(); ++i) {
387 (*this)[ i ]->apply((*this)[ i ].value * gradient[ i ] * factor);
388 }
389 } else if (factor < 0.0) {
390 for (size_t i = this->size(); i != 0; --i) {
391 (*this)[i-1]->apply((*this)[i-1].value * gradient[i-1] * factor);
392 }
393 }
394 }

◆ scan()

template<class T >
void JFIT::JGradient::scan ( std::ostream & out,
const T & getChi2,
const std::vector< double > & xs,
std::vector< double > & ys ) const
inlineprivate

Scan.

Parameters
outoutput stream
getChi2chi2 function
xsset of steps
ysset of current steps

Definition at line 406 of file JGradient.hh.

407 {
408 using namespace std;
409
410 if (ys.size() == this->size()) {
411
412 for (size_t i = 0; i != this->size(); ++i) {
413 (*this)[ i ]->apply(+ys[ i ]);
414 }
415
416 for (const double y : ys) {
417 out << FIXED(12,5) << y << ' ';
418 }
419
420 out << FIXED(12,5) << getChi2(1) << endl;
421
422 for (size_t i = this->size(); i != 0; --i) {
423 (*this)[i-1]->apply(-ys[i-1]);
424 }
425
426 } else {
427
428 for (const double x : xs) {
429
430 ys.push_back(x * (*this)[ys.size()].value);
431
432 scan(out, getChi2, xs, ys);
433
434 ys.pop_back();
435 }
436 }
437 }

Member Data Documentation

◆ Nmax

size_t JFIT::JGradient::Nmax

maximum number of iterations

Definition at line 295 of file JGradient.hh.

◆ Nextra

size_t JFIT::JGradient::Nextra

maximum number of extra steps

Definition at line 296 of file JGradient.hh.

◆ epsilon

double JFIT::JGradient::epsilon

epsilon

Definition at line 297 of file JGradient.hh.

◆ debug

int JFIT::JGradient::debug

debug

Definition at line 298 of file JGradient.hh.

◆ absolute

bool JFIT::JGradient::absolute = false

absolute chi2

Definition at line 300 of file JGradient.hh.

◆ normalise

bool JFIT::JGradient::normalise = false

normalise gradient

Definition at line 301 of file JGradient.hh.

◆ numberOfIterations

size_t JFIT::JGradient::numberOfIterations

Definition at line 303 of file JGradient.hh.

◆ gradient

std::vector<double> JFIT::JGradient::gradient
private

Definition at line 439 of file JGradient.hh.


The documentation for this struct was generated from the following file: