CMS 3D CMS Logo

Base_Constrainer.cc
Go to the documentation of this file.
1 //
2 //
3 // File: src/Base_Constrainer.cc
4 // Purpose: Abstract base for the chisq fitter classes.
5 // This allows for different algorithms to be used.
6 // Created: Jul, 2000, sss, based on run 1 mass analysis code.
7 //
8 // CMSSW File : src/Base_Constrainer.cc
9 // Original Author : Scott Stuart Snyder <snyder@bnl.gov> for D0
10 // Imported to CMSSW by Haryo Sumowidagdo <Suharyo.Sumowidagdo@cern.ch>
11 //
12 
41 #include <iostream>
42 #include <cmath>
43 #include <cstdlib>
44 
45 using std::abort;
46 using std::abs;
47 using std::cout;
48 using std::ostream;
49 
50 //*************************************************************************
51 // Helper function for doing gradient testing.
52 //
53 
54 namespace {
55 
69  bool test_different(double a, double b, double c, double eps)
70  //
71  // Purpose: Test if A is significantly different than B.
72  // C sets the scale for the comparison; EPS gives
73  // by how much they may differ.
74  //
75  {
76  double scale = eps * (abs(a) + abs(b) + abs(c));
77  if (abs(a) != 0 && abs(b) / abs(a) < 0.1 && abs(a) > scale)
78  scale = abs(a) * .5;
79  if (scale == 0)
80  return false;
81  if (scale < eps)
82  scale = eps;
83  return abs(a - b) > scale;
84  }
85 
86 } // unnamed namespace
87 
88 //*************************************************************************
89 
90 namespace hitfit {
91 
92  //*************************************************************************
93 
95  //
96  // Purpose: Constructor.
97  //
98  // Inputs:
99  // defs - The Defaults instance from which to initialize.
100  //
101  : _test_gradient(defs.get_bool("test_gradient")),
102  _test_step(defs.get_float("test_step")),
103  _test_eps(defs.get_float("test_eps")) {}
104 
106  //
107  // Purpose: Return the test_gradient parameter.
108  // See the header for documentation.
109  //
110  {
111  return _test_gradient;
112  }
113 
115  //
116  // Purpose: Return the test_step parameter.
117  // See the header for documentation.
118  //
119  {
120  return _test_step;
121  }
122 
124  //
125  // Purpose: Return the test_eps parameter.
126  // See the header for documentation.
127  //
128  {
129  return _test_eps;
130  }
131 
132  //*************************************************************************
133 
135  //
136  // Purpose: Constructor.
137  //
138  // Inputs:
139  // nconstraints- The number of constraint functions.
140  //
141  : _nconstraints(nconstraints) {}
142 
144  //
145  // Purpose: Return the number of constraint functions.
146  //
147  // Returns:
148  // The number of constraint functions.
149  //
150  {
151  return _nconstraints;
152  }
153 
154  //*************************************************************************
155 
157  //
158  // Purpose: Constructor.
159  //
160  // Inputs:
161  // args - The parameter settings for this instance.
162  //
163  : _args(args) {}
164 
165  std::ostream& Base_Constrainer::print(std::ostream& s) const
166  //
167  // Purpose: Print our state.
168  //
169  // Inputs:
170  // s - The stream to which to write.
171  //
172  // Returns:
173  // The stream S.
174  //
175  {
176  s << "Base_Constrainer parameters:\n";
177  s << " test_gradient: " << _args.test_gradient() << " test_step: " << _args.test_step()
178  << " test_eps: " << _args.test_eps() << "\n";
179  return s;
180  }
181 
191  std::ostream& operator<<(std::ostream& s, const Base_Constrainer& f)
192  //
193  // Purpose: Print our state.
194  //
195  // Inputs:
196  // s - The stream to which to write.
197  // f - The instance to dump.
198  //
199  // Returns:
200  // The stream S.
201  //
202  {
203  return f.print(s);
204  }
205 
207  const Column_Vector& x,
208  const Column_Vector& y,
209  Row_Vector& F,
210  Matrix& Bx,
211  Matrix& By) const
212  //
213  // Purpose: Call the constraint function for the point x, y.
214  // Return F, Bx, By, and a flag saying if the
215  // point is acceptable.
216  //
217  // If test_gradient is on, we verify the gradients returned
218  // by also computing them numerically.
219  //
220  // Inputs:
221  // constraints - The user-supplied object to evaluate the constraints.
222  // x(Nw) - Vector of well-measured quantities where we evaluate
223  // the constraints.
224  // y(Np) - Vector of poorly-measured quantities where we evaluate
225  // the constraints.
226  //
227  // Outputs:
228  // F(Nc) - The results of the constraint functions.
229  // Bx(Nw,Nc) - Gradients of F with respect to x.
230  // By(Np,Nc) - Gradients of F with respect to y.
231  //
232  // Returns:
233  // True if the point is accepted, false if it was rejected.
234  {
235  // Call the user's function.
236  bool val = constraint_calculator.eval(x, y, F, Bx, By);
237 
238  // If we're not doing gradients numerically, we're done.
239  if (!_args.test_gradient())
240  return val;
241 
242  // Bail if the point was rejected.
243  if (!val)
244  return false;
245 
246  int Nw = x.num_row();
247  int Np = y.num_row();
248  int Nc = F.num_col();
249 
250  // Numerically check Bx.
251  for (int i = 1; i <= Nc; i++) {
252  // Step a little along variable I.
253  Column_Vector step_x(Nw, 0);
254  step_x(i) = _args.test_step();
255  Column_Vector new_x = x + step_x;
256 
257  // Evaluate the constraints at the new point.
258  Matrix new_Bx(Nw, Nc);
259  Matrix new_By(Np, Nc);
260  Row_Vector new_F(Nc);
261  if (!constraint_calculator.eval(new_x, y, new_F, new_Bx, new_By))
262  return false;
263 
264  // Calculate what we expect the constraints to be at this point,
265  // given the user's gradients.
266  Row_Vector test_F = F + step_x.T() * Bx;
267 
268  // Check the results.
269  for (int j = 1; j <= Nc; j++) {
270  if (test_different(test_F(j), new_F(j), F(j), _args.test_eps())) {
271  cout << "bad gradient x " << i << " " << j << "\n";
272  cout << x;
273  cout << y;
274  cout << new_x;
275  cout << F;
276  cout << new_F;
277  cout << Bx;
278  cout << (test_F - new_F);
279  abort();
280  }
281  }
282  }
283 
284  // Numerically check By.
285  for (int i = 1; i <= Np; i++) {
286  // Step a little along variable I.
287  Column_Vector step_y(Np, 0);
288  step_y(i) = _args.test_step();
289  Column_Vector new_y = y + step_y;
290 
291  // Evaluate the constraints at the new point.
292  Matrix new_Bx(Nw, Nc);
293  Matrix new_By(Np, Nc);
294  Row_Vector new_F(Nc);
295  if (!constraint_calculator.eval(x, new_y, new_F, new_Bx, new_By))
296  return false;
297 
298  // Calculate what we expect the constraints to be at this point,
299  // given the user's gradients.
300  Row_Vector test_F = F + step_y.T() * By;
301 
302  // Check the results.
303  for (int j = 1; j <= Nc; j++) {
304  if (test_different(test_F(j), new_F(j), F(j), _args.test_eps())) {
305  cout << "bad gradient y " << i << " " << j << "\n";
306  cout << x;
307  cout << y;
308  cout << new_y;
309  cout << F;
310  cout << new_F;
311  cout << Bx;
312  cout << (test_F - new_F);
313  abort();
314  }
315  }
316  }
317 
318  // Done!
319  return true;
320  }
321 
322 } // namespace hitfit
Define an abstract interface for getting parameter settings.
CLHEP::HepVector Column_Vector
Definition: matutil.h:63
Define matrix types for the HitFit package, and supply a few additional operations.
Abstract base class for evaluating constraints. Users derive from this class and implement the eval()...
CLHEP::HepMatrix Matrix
Definition: matutil.h:62
Constraint_Calculator(int nconstraints)
Base class for constrained fitter.
Base_Constrainer(const Base_Constrainer_Args &args)
friend std::ostream & operator<<(std::ostream &s, const Base_Constrainer &f)
Output stream operator, print the content of this Base_Constrainer to an output stream.
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool call_constraint_fcn(Constraint_Calculator &constraint_calculator, const Column_Vector &x, const Column_Vector &y, Row_Vector &F, Matrix &Bx, Matrix &By) const
Helper function to evaluate constraints. This takes care of checking what the user function returns a...
double f[11][100]
Abstract base classes for the fitter classes.
Base_Constrainer_Args(const Defaults &defs)
Hold on to parameters for the Base_Constrainer class.
double b
Definition: hdecay.h:118
const Base_Constrainer_Args _args
Define an interface for getting parameter settings.
Definition: Defaults.h:57
double a
Definition: hdecay.h:119
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:163
virtual std::ostream & print(std::ostream &s) const
Print out internal state to output stream.
Row-vector class. CLHEP doesn&#39;t have a row-vector class, so HitFit uses its own. This is only a simpl...
Definition: matutil.h:79