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