Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00040 #include "TopQuarkAnalysis/TopHitFit/interface/Base_Constrainer.h"
00041 #include "TopQuarkAnalysis/TopHitFit/interface/matutil.h"
00042 #include "TopQuarkAnalysis/TopHitFit/interface/Defaults.h"
00043 #include <iostream>
00044 #include <cmath>
00045 #include <cstdlib>
00046
00047 using std::abort;
00048 using std::abs;
00049 using std::cout;
00050 using std::ostream;
00051
00052
00053
00054
00055
00056
00057
00058 namespace {
00059
00073 bool test_different (double a, double b, double c, double eps)
00074
00075
00076
00077
00078
00079 {
00080 double scale = eps * (abs (a) + abs (b) + abs (c));
00081 if (abs (a) != 0 && abs (b) / abs (a) < 0.1 && abs (a) > scale)
00082 scale = abs (a) * .5;
00083 if (scale == 0) return false;
00084 if (scale < eps) scale = eps;
00085 return abs (a - b) > scale;
00086 }
00087
00088
00089 }
00090
00091
00092
00093
00094
00095 namespace hitfit {
00096
00097
00098
00099
00100
00101 Base_Constrainer_Args::Base_Constrainer_Args (const Defaults& defs)
00102
00103
00104
00105
00106
00107
00108 : _test_gradient (defs.get_bool ("test_gradient")),
00109 _test_step (defs.get_float ("test_step")),
00110 _test_eps (defs.get_float ("test_eps"))
00111 {
00112 }
00113
00114
00115 bool Base_Constrainer_Args::test_gradient () const
00116
00117
00118
00119
00120 {
00121 return _test_gradient;
00122 }
00123
00124
00125 double Base_Constrainer_Args::test_step () const
00126
00127
00128
00129
00130 {
00131 return _test_step;
00132 }
00133
00134
00135 double Base_Constrainer_Args::test_eps () const
00136
00137
00138
00139
00140 {
00141 return _test_eps;
00142 }
00143
00144
00145
00146
00147
00148 Constraint_Calculator::Constraint_Calculator (int nconstraints)
00149
00150
00151
00152
00153
00154
00155 : _nconstraints (nconstraints)
00156 {
00157 }
00158
00159
00160 int Constraint_Calculator::nconstraints () const
00161
00162
00163
00164
00165
00166
00167 {
00168 return _nconstraints;
00169 }
00170
00171
00172
00173
00174
00175 Base_Constrainer::Base_Constrainer (const Base_Constrainer_Args& args)
00176
00177
00178
00179
00180
00181
00182 : _args (args)
00183 {
00184 }
00185
00186
00187 std::ostream& Base_Constrainer::print (std::ostream& s) const
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 {
00198 s << "Base_Constrainer parameters:\n";
00199 s << " test_gradient: " << _args.test_gradient()
00200 << " test_step: " << _args.test_step()
00201 << " test_eps: " << _args.test_eps() << "\n";
00202 return s;
00203 }
00204
00205
00215 std::ostream& operator<< (std::ostream& s, const Base_Constrainer& f)
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 {
00227 return f.print (s);
00228 }
00229
00230
00231 bool Base_Constrainer::call_constraint_fcn (Constraint_Calculator&
00232 constraint_calculator,
00233 const Column_Vector& x,
00234 const Column_Vector& y,
00235 Row_Vector& F,
00236 Matrix& Bx,
00237 Matrix& By) const
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 {
00261
00262 bool val = constraint_calculator.eval (x, y, F, Bx, By);
00263
00264
00265 if (!_args.test_gradient())
00266 return val;
00267
00268
00269 if (!val)
00270 return false;
00271
00272 int Nw = x.num_row();
00273 int Np = y.num_row();
00274 int Nc = F.num_col();
00275
00276
00277 for (int i=1; i<=Nc; i++) {
00278
00279 Column_Vector step_x (Nw, 0);
00280 step_x(i) = _args.test_step();
00281 Column_Vector new_x = x + step_x;
00282
00283
00284 Matrix new_Bx (Nw, Nc);
00285 Matrix new_By (Np, Nc);
00286 Row_Vector new_F (Nc);
00287 if (! constraint_calculator.eval (new_x, y, new_F, new_Bx, new_By))
00288 return false;
00289
00290
00291
00292 Row_Vector test_F = F + step_x.T() * Bx;
00293
00294
00295 for (int j=1; j<=Nc; j++) {
00296 if (test_different (test_F(j), new_F(j), F(j), _args.test_eps())) {
00297 cout << "bad gradient x " << i << " " << j << "\n";
00298 cout << x;
00299 cout << y;
00300 cout << new_x;
00301 cout << F;
00302 cout << new_F;
00303 cout << Bx;
00304 cout << (test_F - new_F);
00305 abort ();
00306 }
00307 }
00308 }
00309
00310
00311 for (int i=1; i<=Np; i++) {
00312
00313 Column_Vector step_y (Np, 0);
00314 step_y(i) = _args.test_step();
00315 Column_Vector new_y = y + step_y;
00316
00317
00318 Matrix new_Bx (Nw, Nc);
00319 Matrix new_By (Np, Nc);
00320 Row_Vector new_F (Nc);
00321 if (! constraint_calculator.eval (x, new_y, new_F, new_Bx, new_By))
00322 return false;
00323
00324
00325
00326 Row_Vector test_F = F + step_y.T() * By;
00327
00328
00329 for (int j=1; j<=Nc; j++) {
00330 if (test_different (test_F(j), new_F(j), F(j), _args.test_eps())) {
00331 cout << "bad gradient y " << i << " " << j << "\n";
00332 cout << x;
00333 cout << y;
00334 cout << new_y;
00335 cout << F;
00336 cout << new_F;
00337 cout << Bx;
00338 cout << (test_F - new_F);
00339 abort ();
00340 }
00341 }
00342 }
00343
00344
00345 return true;
00346 }
00347
00348
00349 }