CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 
42 #include <iostream>
43 #include <cmath>
44 #include <cstdlib>
45 
46 using std::abort;
47 using std::abs;
48 using std::cout;
49 using std::ostream;
50 
51 
52 //*************************************************************************
53 // Helper function for doing gradient testing.
54 //
55 
56 
57 namespace {
58 
72 bool test_different (double a, double b, double c, double eps)
73 //
74 // Purpose: Test if A is significantly different than B.
75 // C sets the scale for the comparison; EPS gives
76 // by how much they may differ.
77 //
78 {
79  double scale = eps * (abs (a) + abs (b) + abs (c));
80  if (abs (a) != 0 && abs (b) / abs (a) < 0.1 && abs (a) > scale)
81  scale = abs (a) * .5;
82  if (scale == 0) return false;
83  if (scale < eps) scale = eps;
84  return abs (a - b) > scale;
85 }
86 
87 
88 } // unnamed namespace
89 
90 
91 //*************************************************************************
92 
93 
94 namespace hitfit {
95 
96 
97 //*************************************************************************
98 
99 
101 //
102 // Purpose: Constructor.
103 //
104 // Inputs:
105 // defs - The Defaults instance from which to initialize.
106 //
107  : _test_gradient (defs.get_bool ("test_gradient")),
108  _test_step (defs.get_float ("test_step")),
109  _test_eps (defs.get_float ("test_eps"))
110 {
111 }
112 
113 
115 //
116 // Purpose: Return the test_gradient parameter.
117 // See the header for documentation.
118 //
119 {
120  return _test_gradient;
121 }
122 
123 
125 //
126 // Purpose: Return the test_step parameter.
127 // See the header for documentation.
128 //
129 {
130  return _test_step;
131 }
132 
133 
135 //
136 // Purpose: Return the test_eps parameter.
137 // See the header for documentation.
138 //
139 {
140  return _test_eps;
141 }
142 
143 
144 //*************************************************************************
145 
146 
148 //
149 // Purpose: Constructor.
150 //
151 // Inputs:
152 // nconstraints- The number of constraint functions.
153 //
154  : _nconstraints (nconstraints)
155 {
156 }
157 
158 
160 //
161 // Purpose: Return the number of constraint functions.
162 //
163 // Returns:
164 // The number of constraint functions.
165 //
166 {
167  return _nconstraints;
168 }
169 
170 
171 //*************************************************************************
172 
173 
175 //
176 // Purpose: Constructor.
177 //
178 // Inputs:
179 // args - The parameter settings for this instance.
180 //
181  : _args (args)
182 {
183 }
184 
185 
186 std::ostream& Base_Constrainer::print (std::ostream& s) const
187 //
188 // Purpose: Print our state.
189 //
190 // Inputs:
191 // s - The stream to which to write.
192 //
193 // Returns:
194 // The stream S.
195 //
196 {
197  s << "Base_Constrainer parameters:\n";
198  s << " test_gradient: " << _args.test_gradient()
199  << " test_step: " << _args.test_step()
200  << " test_eps: " << _args.test_eps() << "\n";
201  return s;
202 }
203 
204 
214 std::ostream& operator<< (std::ostream& s, const Base_Constrainer& f)
215 //
216 // Purpose: Print our state.
217 //
218 // Inputs:
219 // s - The stream to which to write.
220 // f - The instance to dump.
221 //
222 // Returns:
223 // The stream S.
224 //
225 {
226  return f.print (s);
227 }
228 
229 
231  constraint_calculator,
232  const Column_Vector& x,
233  const Column_Vector& y,
234  Row_Vector& F,
235  Matrix& Bx,
236  Matrix& By) const
237 //
238 // Purpose: Call the constraint function for the point x, y.
239 // Return F, Bx, By, and a flag saying if the
240 // point is acceptable.
241 //
242 // If test_gradient is on, we verify the gradients returned
243 // by also computing them numerically.
244 //
245 // Inputs:
246 // constraints - The user-supplied object to evaluate the constraints.
247 // x(Nw) - Vector of well-measured quantities where we evaluate
248 // the constraints.
249 // y(Np) - Vector of poorly-measured quantities where we evaluate
250 // the constraints.
251 //
252 // Outputs:
253 // F(Nc) - The results of the constraint functions.
254 // Bx(Nw,Nc) - Gradients of F with respect to x.
255 // By(Np,Nc) - Gradients of F with respect to y.
256 //
257 // Returns:
258 // True if the point is accepted, false if it was rejected.
259 {
260  // Call the user's function.
261  bool val = constraint_calculator.eval (x, y, F, Bx, By);
262 
263  // If we're not doing gradients numerically, we're done.
264  if (!_args.test_gradient())
265  return val;
266 
267  // Bail if the point was rejected.
268  if (!val)
269  return false;
270 
271  int Nw = x.num_row();
272  int Np = y.num_row();
273  int Nc = F.num_col();
274 
275  // Numerically check Bx.
276  for (int i=1; i<=Nc; i++) {
277  // Step a little along variable I.
278  Column_Vector step_x (Nw, 0);
279  step_x(i) = _args.test_step();
280  Column_Vector new_x = x + step_x;
281 
282  // Evaluate the constraints at the new point.
283  Matrix new_Bx (Nw, Nc);
284  Matrix new_By (Np, Nc);
285  Row_Vector new_F (Nc);
286  if (! constraint_calculator.eval (new_x, y, new_F, new_Bx, new_By))
287  return false;
288 
289  // Calculate what we expect the constraints to be at this point,
290  // given the user's gradients.
291  Row_Vector test_F = F + step_x.T() * Bx;
292 
293  // Check the results.
294  for (int j=1; j<=Nc; j++) {
295  if (test_different (test_F(j), new_F(j), F(j), _args.test_eps())) {
296  cout << "bad gradient x " << i << " " << j << "\n";
297  cout << x;
298  cout << y;
299  cout << new_x;
300  cout << F;
301  cout << new_F;
302  cout << Bx;
303  cout << (test_F - new_F);
304  abort ();
305  }
306  }
307  }
308 
309  // Numerically check By.
310  for (int i=1; i<=Np; i++) {
311  // Step a little along variable I.
312  Column_Vector step_y (Np, 0);
313  step_y(i) = _args.test_step();
314  Column_Vector new_y = y + step_y;
315 
316  // Evaluate the constraints at the new point.
317  Matrix new_Bx (Nw, Nc);
318  Matrix new_By (Np, Nc);
319  Row_Vector new_F (Nc);
320  if (! constraint_calculator.eval (x, new_y, new_F, new_Bx, new_By))
321  return false;
322 
323  // Calculate what we expect the constraints to be at this point,
324  // given the user's gradients.
325  Row_Vector test_F = F + step_y.T() * By;
326 
327  // Check the results.
328  for (int j=1; j<=Nc; j++) {
329  if (test_different (test_F(j), new_F(j), F(j), _args.test_eps())) {
330  cout << "bad gradient y " << i << " " << j << "\n";
331  cout << x;
332  cout << y;
333  cout << new_y;
334  cout << F;
335  cout << new_F;
336  cout << Bx;
337  cout << (test_F - new_F);
338  abort ();
339  }
340  }
341  }
342 
343  // Done!
344  return true;
345 }
346 
347 
348 } // namespace hitfit
int i
Definition: DBlmapReader.cc:9
Define an abstract interface for getting parameter settings.
CLHEP::HepVector Column_Vector
Definition: matutil.h:66
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:65
Constraint_Calculator(int nconstraints)
T x() const
Cartesian x coordinate.
Base class for constrained fitter.
Base_Constrainer(const Base_Constrainer_Args &args)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int j
Definition: DBlmapReader.cc:9
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:120
string const
Definition: compareJSON.py:14
Define an interface for getting parameter settings.
Definition: Defaults.h:61
double a
Definition: hdecay.h:121
std::ostream & operator<<(std::ostream &s, const Constraint_Intermed &ci)
Output stream operator, print the content of this Constraint_Intermed to an output stream...
tuple cout
Definition: gather_cfg.py:121
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:281
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:83