1 #define ENABLE_INLINING
94 #ifndef LESTER_TESTWHETHERELLIPSESAREDISJOINT_H
95 #define LESTER_TESTWHETHERELLIPSESAREDISJOINT_H
161 #ifdef ENABLE_INLINING
178 if (c_xx<0 || c_yy<0) {
179 throw "precondition violation";
185 #ifdef ENABLE_INLINING
189 det = (2.0*c_x*c_xy*c_y + c*c_xx*c_yy - c_yy*c_x*c_x - c*c_xy*c_xy - c_xx*c_y*c_y) ;
205 const double ans = e1.c_xx*e1.c_yy*e2.c + 2.0*e1.c_xy*e1.c_y*e2.c_x - 2.0*e1.c_x*e1.c_yy*e2.c_x + e1.c*e1.c_yy*e2.c_xx - 2.0*e1.c*e1.c_xy*e2.c_xy + 2.0*e1.c_x*e1.c_y*e2.c_xy + 2.0*e1.c_x*e1.c_xy*e2.c_y - 2.0*e1.c_xx*e1.c_y*e2.c_y + e1.c*e1.c_xx*e2.c_yy - e2.c_yy*(e1.c_x*e1.c_x) - e2.c*(e1.c_xy*e1.c_xy) - e2.c_xx*(e1.c_y*e1.c_y);
208 #ifdef ENABLE_INLINING
213 c_xx == other.c_xx &&
214 c_yy == other.c_yy &&
215 c_xy == other.c_xy &&
235 inline bool __private_ellipsesAreDisjoint(
const double coeffLamPow3,
const double coeffLamPow2,
const double coeffLamPow1,
const double coeffLamPow0);
250 const double coeffLamPow3 = e1.det;
251 const double coeffLamPow2 = e1.lesterFactor(e2);
252 const double coeffLamPow1 = e2.lesterFactor(e1);
253 const double coeffLamPow0 = e2.det;
257 if (fabs(coeffLamPow3) >= fabs(coeffLamPow0)) {
258 return __private_ellipsesAreDisjoint(coeffLamPow3, coeffLamPow2, coeffLamPow1, coeffLamPow0);
260 return __private_ellipsesAreDisjoint(coeffLamPow0, coeffLamPow1, coeffLamPow2, coeffLamPow3);
263 inline bool __private_ellipsesAreDisjoint(
const double coeffLamPow3,
const double coeffLamPow2,
const double coeffLamPow1,
const double coeffLamPow0) {
268 if(coeffLamPow3==0) {
275 const double a = coeffLamPow2 / coeffLamPow3;
276 const double b = coeffLamPow1 / coeffLamPow3;
277 const double c = coeffLamPow0 / coeffLamPow3;
279 #ifdef LESTER_DEEP_FIDDLE
281 const double thing1 = -3.0*b + a*a;
282 const double thing2 = -27.0*c*c + 18.0*c*a*b + a*a*b*b - 4.0*a*a*a*c - 4.0*b*b*b;
284 << (thing1>0) <<
" && " << (thing2>0) <<
" && [[ " << (a>=0) <<
" " << (3.0*a*c + b*a*a - 4.0*b*b<0) <<
" ] or "
285 <<
"[ " << (a< 0) <<
" ] =("<< ((a >= 0 && 3.0*a*c + b*a*a - 4.0*b*b< 0 /*&& thing2 > 0*/) ||
286 (a < 0 )) <<
")] " << (
287 ( (a >= 0 && thing1 > 0 && 3.0*a*c + b*a*a - 4.0*b*b< 0 && thing2 > 0) ||
288 (a < 0 && thing1 > 0 && thing2 > 0))
295 const double thing1 = -3.0*b + a*a;
296 if (thing1<=0)
return false;
297 const double thing2 = -27.0*c*c + 18.0*c*a*b + a*a*b*b - 4.0*a*a*a*c - 4.0*b*b*b;
298 if (thing2<=0)
return false;
301 const bool ans = ( (a >= 0 && 3.0*a*c + b*a*a - 4.0*b*b< 0 ) ||
302 (a < 0 /*&& thing1 > 0*/ ));
318 #ifndef ASYMM_MT2_BISECT_H
319 #define ASYMM_MT2_BISECT_H
330 static const int MT2_ERROR=-1;
332 static double get_mT2(
333 const double mVis1,
const double pxVis1,
const double pyVis1,
334 const double mVis2,
const double pxVis2,
const double pyVis2,
335 const double pxMiss,
const double pyMiss,
336 const double mInvis1,
const double mInvis2,
337 const double desiredPrecisionOnMT2=0,
338 const bool useDeciSectionsInitially=
true
341 const double mT2_Sq = get_mT2_Sq(
342 mVis1, pxVis1, pyVis1,
343 mVis2, pxVis2, pyVis2,
346 desiredPrecisionOnMT2,
347 useDeciSectionsInitially);
348 if (mT2_Sq==MT2_ERROR) {
354 static void disableCopyrightMessage(
const bool printIfFirst=
false) {
355 static bool first =
true;
356 if (first && printIfFirst) {
359 <<
"#=========================================================\n"
360 <<
"# To disable this message, place a call to \n"
362 <<
"# asymm_mt2_lester_bisect::disableCopyrightMessage();\n"
364 <<
"# somewhere before you begin to calculate your MT2 values.\n"
365 <<
"#=========================================================\n"
366 <<
"# You are calculating symmetric or asymmetric MT2 using\n"
367 <<
"# the implementation defined in:\n"
369 <<
"# http://arxiv.org/abs/1411.4312\n"
371 <<
"# Please cite the paper above if you use the MT2 values\n"
372 <<
"# for a scholarly purpose. For the variable MT2 itself,\n"
373 <<
"# please also cite:\n"
375 <<
"# http://arxiv.org/abs/hep-ph/9906349\n"
376 <<
"#=========================================================\n"
377 <<
"\n\n" << std::flush;
382 static double get_mT2_Sq(
383 const double mVis1,
const double pxVis1,
const double pyVis1,
384 const double mVis2,
const double pxVis2,
const double pyVis2,
385 const double pxMiss,
const double pyMiss,
386 const double mInvis1,
const double mInvis2,
387 const double desiredPrecisionOnMT2=0,
388 const bool useDeciSectionsInitially=
true
391 #ifndef DISABLE_COPYRIGHT_PRINTING
392 disableCopyrightMessage(
true);
395 const double m1Min = mVis1+mInvis1;
396 const double m2Min = mVis2+mInvis2;
400 return asymm_mt2_lester_bisect::get_mT2_Sq(
401 mVis2, pxVis2, pyVis2,
402 mVis1, pxVis1, pyVis1,
405 desiredPrecisionOnMT2
410 assert(m1Min<=m2Min);
412 const double mMin = m2Min;
416 const double msSq = mVis1*mVis1;
417 const double sx = pxVis1;
418 const double sy = pyVis1;
419 const double mpSq = mInvis1*mInvis1;
421 const double mtSq = mVis2*mVis2;
422 const double tx = pxVis2;
423 const double ty = pyVis2;
424 const double mqSq = mInvis2*mInvis2;
426 const double sSq = sx*sx + sy*sy;
427 const double tSq = tx*tx + ty*ty;
428 const double pMissSq = pxMiss*pxMiss + pyMiss*pyMiss;
429 const double massSqSum = msSq + mtSq + mpSq + mqSq;
430 const double scaleSq = (massSqSum + sSq + tSq + pMissSq)/8.0;
435 std::cout <<
"\nMOO ";
441 const double scale = sqrt(scaleSq);
444 double mLower = mMin;
445 double mUpper = mMin + scale;
446 unsigned int attempts=0;
447 const unsigned int maxAttempts=10000;
451 const double mUpperSq = mUpper*mUpper;
457 disjoint = Lester::ellipsesAreDisjoint(side1, side2);
466 if (attempts>=maxAttempts) {
467 std::cerr <<
"MT2 algorithm failed to find upper bound to MT2" << std::endl;
480 bool goLow = useDeciSectionsInitially;
481 while(desiredPrecisionOnMT2<=0 || mUpper-mLower>desiredPrecisionOnMT2) {
483 const double trialM = ( goLow ?
484 (mLower*15+mUpper)/16
486 (mUpper + mLower)/2.0
489 if (trialM<=mLower || trialM>=mUpper) {
492 std::cout <<
" MACHINE_PREC " << std::setprecision(10) << mLower <<
" " << trialM <<
" " << mUpper <<
" " << mUpper-mLower <<
" " << desiredPrecisionOnMT2 << std::endl;
494 return trialM*trialM;
496 const double trialMSq = trialM * trialM;
501 const bool disjoint = Lester::ellipsesAreDisjoint(side1, side2);
517 std::cout <<
" THROW " << std::endl;
519 return mLower*mLower;
523 const double mAns = (mLower+mUpper)/2.0;
526 std::cout <<
" USER_PREC " << std::endl;
531 #ifdef ENABLE_INLINING
534 static double lestermax(
const double x,
const double y) {
538 const double mtSq,
const double tx,
const double ty,
540 const double pxmiss,
const double pymiss
542 const double txSq = tx*tx;
543 const double tySq = ty*ty;
544 const double pxmissSq = pxmiss*pxmiss;
545 const double pymissSq = pymiss*pymiss;
548 const double c_xx = +4.0* mtSq + 4.0* tySq;
550 const double c_yy = +4.0* mtSq + 4.0* txSq;
552 const double c_xy = -4.0* tx*ty;
554 const double c_x = -4.0* mtSq*pxmiss - 2.0* mqSq*tx + 2.0* mSq*tx - 2.0* mtSq*tx +
555 4.0* pymiss*tx*ty - 4.0* pxmiss*tySq;
557 const double c_y = -4.0* mtSq*pymiss - 4.0* pymiss*txSq - 2.0* mqSq*ty + 2.0* mSq*ty - 2.0* mtSq*ty +
560 const double c = - mqSq*mqSq + 2*mqSq*mSq - mSq*mSq + 2*mqSq*mtSq + 2*mSq*mtSq - mtSq*mtSq +
561 4.0* mtSq*pxmissSq + 4.0* mtSq*pymissSq + 4.0* mqSq*pxmiss*tx -
562 4.0* mSq*pxmiss*tx + 4.0* mtSq*pxmiss*tx + 4.0* mqSq*txSq +
563 4.0* pymissSq*txSq + 4.0* mqSq*pymiss*ty - 4.0* mSq*pymiss*ty +
564 4.0* mtSq*pymiss*ty - 8.0* pxmiss*pymiss*tx*ty + 4.0* mqSq*tySq +
Definition: lester_mt2_bisect.h:327
Definition: lester_mt2_bisect.h:153