File indexing completed on 2026-08-06 09:25:33
0001
0002
0003
0004 #ifndef NINJA_NINJA_HH
0005 #define NINJA_NINJA_HH
0006
0007 #define NINJA_NINJA_HH_INSIDE
0008
0009 #include <iostream>
0010 #include <stdexcept>
0011
0012 #include <ninja/types.hh>
0013 #include <ninja/momentum.hh>
0014 #include <ninja/s_mat.hh>
0015 #include <ninja/num_defs.hh>
0016 #include <ninja/ninja_in.hh>
0017
0018
0019 namespace ninja {
0020
0021
0022
0023 struct Test {
0024 enum {
0025 NONE = 0,
0026 ALL = ~(0),
0027 GLOBAL = 1,
0028 LOCAL_4 = 1 << 4,
0029 LOCAL_3 = 1 << 3,
0030 LOCAL_2 = 1 << 2,
0031 LOCAL_1 = 1 << 1,
0032 LOCAL = LOCAL_4 | LOCAL_3 | LOCAL_2 | LOCAL_1
0033 };
0034 };
0035
0036
0037
0038 struct Verbose {
0039 enum {
0040
0041 NONE = 0,
0042 ALL = ~(0),
0043
0044
0045 GLOBAL_TEST = 1,
0046 LOCAL_TEST_4 = 1 << 4,
0047 LOCAL_TEST_3 = 1 << 3,
0048 LOCAL_TEST_2 = 1 << 2,
0049 LOCAL_TEST_1 = 1 << 1,
0050 LOCAL_TESTS = LOCAL_TEST_1 | LOCAL_TEST_2 | LOCAL_TEST_3 | LOCAL_TEST_4,
0051 TESTS = LOCAL_TESTS | GLOBAL_TEST,
0052
0053
0054 C5 = 1 << (4+5),
0055 C4 = 1 << (4+4),
0056 C3 = 1 << (4+3),
0057 C2 = 1 << (4+2),
0058 C1 = 1 << (4+1),
0059 COEFFS = C5 | C4 | C3 | C2 | C1,
0060
0061
0062 RESULT = 1 << (4+5+1),
0063
0064
0065 INTEGRALS = 1 << (4+5+2)
0066 };
0067 };
0068
0069
0070
0071 inline void setTest(unsigned flag)
0072 {
0073 Options::test = flag;
0074 }
0075
0076
0077
0078
0079
0080 inline void setVerbosity(unsigned flag)
0081 {
0082 Options::verb = flag;
0083 }
0084
0085
0086
0087 inline void setDefaultIntegralLibrary(IntegralLibrary & mis)
0088 {
0089 Options::mis = & mis;
0090 }
0091
0092
0093 inline IntegralLibrary * getIntegralLibrary()
0094 {
0095 return Options::mis;
0096 }
0097
0098
0099
0100 void printBanner(std::ostream & banner_out = std::cout,
0101 bool force_print=true);
0102
0103
0104
0105
0106 inline void setChopTolerance(Real chop_tolerance)
0107 {
0108 Options::chop_tol = chop_tolerance;
0109 }
0110
0111
0112
0113
0114
0115 inline void setTestTolerance(Real test_tolerance)
0116 {
0117 Options::test_tol = test_tolerance;
0118 }
0119
0120
0121
0122 inline void setDefaultFloatingPointThreshold(Real threshold)
0123 {
0124 Options::fp_threshold = threshold;
0125 }
0126
0127
0128 inline void setOutputStream(std::ostream & outs)
0129 {
0130 Options::out = & outs;
0131 }
0132
0133
0134
0135
0136 template<typename MassType>
0137 class Amplitude {
0138 public:
0139
0140 enum {SUCCESS = 0, TEST_FAILED=1, UNSTABLE_KINEMATICS=1 << 1};
0141
0142 typedef typename const_pointer<MassType>::type MassConstPtr;
0143
0144 public:
0145
0146
0147 Amplitude()
0148 : result(0.,0.,0.),
0149 s_mat(),
0150 V(0),
0151 mis(Options::mis),
0152 m2(static_cast<MassType*>(0)),
0153 cut_constr(),
0154 scale(1.),
0155 fp_threshold(Options::fp_threshold),
0156 n(0), rank(0),
0157 min_cut(0),
0158 return_val(SUCCESS),
0159 use_mu_exp(true) {}
0160
0161
0162 Amplitude(Amplitude & amp)
0163 : result(amp.result[0],amp.result[1],amp.result[2]),
0164 s_mat(),
0165 V(amp.V),
0166 mis(amp.mis),
0167 m2(amp.m2),
0168 cut_constr(amp.cut_constr),
0169 scale(amp.scale),
0170 fp_threshold(amp.fp_threshold),
0171 n(amp.n), rank(amp.rank),
0172 min_cut(amp.min_cut),
0173 return_val(SUCCESS),
0174 use_mu_exp(amp.use_mu_exp)
0175 {
0176 if (!amp.s_mat.isNull())
0177 s_mat.copy(amp.s_mat);
0178 }
0179
0180
0181
0182
0183
0184 Amplitude(int nn, int rr, const RealMomentum p[], MassConstPtr mass_sq)
0185 : result(0.,0.,0.),
0186 s_mat(0,0),
0187 V(p),
0188 mis(Options::mis),
0189 m2(mass_sq),
0190 cut_constr(),
0191 scale(1.),
0192 fp_threshold(Options::fp_threshold),
0193 n(nn), rank(rr),
0194 min_cut(0),
0195 return_val(SUCCESS),
0196 use_mu_exp(true) {}
0197
0198
0199 Amplitude(int nn, int rr, const RealMomentum p[]);
0200
0201
0202 Amplitude & setN(int nn)
0203 {
0204 n = nn;
0205 return *this;
0206 }
0207
0208
0209 Amplitude & setRank(int rr)
0210 {
0211 rank = rr;
0212 return *this;
0213 }
0214
0215
0216 Amplitude & setKinematics(const RealMomentum p[])
0217 {
0218 V = p;
0219 return *this;
0220 }
0221
0222
0223 Amplitude & setInternalMasses(MassConstPtr mass_sq)
0224 {
0225 m2 = mass_sq;
0226 return *this;
0227 }
0228
0229
0230 Amplitude & setSMatrix(const SMatrix & s_matrix)
0231 {
0232 s_mat = s_matrix;
0233 return *this;
0234 }
0235
0236
0237 Amplitude & setSMatrix(Real * data_ptr)
0238 {
0239 s_mat = SMatrix(data_ptr ? n : 0, data_ptr);
0240 return *this;
0241 }
0242
0243
0244
0245 Amplitude & setRenormalizationScale(Real renorm_scale)
0246 {
0247 scale = renorm_scale;
0248 return *this;
0249 }
0250
0251
0252
0253
0254
0255
0256 Amplitude & setCutStop(int val)
0257 {
0258 min_cut = val;
0259 return *this;
0260 }
0261
0262
0263
0264
0265
0266 Amplitude & useMuExpansion(bool val = true)
0267 {
0268 use_mu_exp = val;
0269 return *this;
0270 }
0271
0272
0273
0274 Amplitude & setIntegralLibrary(IntegralLibrary & library)
0275 {
0276 mis = & library;
0277 return *this;
0278 }
0279
0280
0281 Amplitude & reset()
0282 {
0283 result[0] = result[1] = result[2] = ninja::Complex();
0284 cut_constr = ninja::Complex();
0285 return *this;
0286 }
0287
0288
0289
0290
0291 int evaluate(Numerator & num);
0292
0293
0294 const Complex eps0() const { return result[0];}
0295 const Complex epsm1() const { return result[1];}
0296 const Complex epsm2() const { return result[2];}
0297
0298
0299 const Complex getRationalPart() const
0300 {
0301 return result[0] - cut_constr;
0302 }
0303
0304
0305 const Complex getCutConstructiblePart() const
0306 {
0307 return cut_constr;
0308 }
0309
0310
0311 void onlyCutConstructible()
0312 {
0313 result[0] = cut_constr;
0314 }
0315
0316
0317 const Complex operator[] (unsigned i) const
0318 {
0319 return result[i];
0320 }
0321
0322
0323
0324
0325
0326 void setFloatingPointThreshold(Real threshold)
0327 {
0328 fp_threshold = threshold;
0329 }
0330
0331 private:
0332
0333 void evaluatePentagons(Numerator & num,
0334 CutsVector<cuts::Pentagon> & pentagon);
0335 void evaluatePentagon(Numerator & num,
0336 cuts::Pentagon & pentagon);
0337
0338 void evaluateBoxes(Numerator & num,
0339 const CutsVector<cuts::Pentagon> & pentagon,
0340 CutsVector<cuts::Box> & box);
0341 void evaluateBox(Numerator & num,
0342 const CutsVector<cuts::Pentagon> & pentagon,
0343 cuts::Box & box);
0344
0345 void evaluateFullBoxes(Numerator & num,
0346 const CutsVector<cuts::Pentagon> & pentagon,
0347 CutsVector<cuts::Box> & box);
0348 void evaluateFullBox(Numerator & num,
0349 const CutsVector<cuts::Pentagon> & pentagon,
0350 cuts::Box & box);
0351
0352 void evaluateTriangles(Numerator & num,
0353 CutsVector<cuts::Triangle> & triangle);
0354 void evaluateTriangle(Numerator & num,
0355 cuts::Triangle & triangle);
0356
0357 void evaluateBubbles(Numerator & num,
0358 const CutsVector<cuts::Triangle> & triangle,
0359 CutsVector<cuts::Bubble> & bubble);
0360 void evaluateBubble(Numerator & num,
0361 const CutsVector<cuts::Triangle> & triangle,
0362 cuts::Bubble & bubble);
0363
0364 void evaluateTadpoles(Numerator & num,
0365 const CutsVector<cuts::Triangle> & triangle,
0366 const CutsVector<cuts::Bubble> & bubble,
0367 CutsVector<cuts::Tadpole> & tadpole);
0368 void evaluateTadpole(Numerator & num,
0369 const CutsVector<cuts::Triangle> & triangle,
0370 const CutsVector<cuts::Bubble> & bubble,
0371 cuts::Tadpole & tadpole);
0372
0373 void evaluateFullTadpoles(Numerator & num,
0374 const CutsVector<cuts::Triangle> & triangle,
0375 const CutsVector<cuts::Bubble> & bubble,
0376 CutsVector<cuts::Tadpole> & tadpole);
0377 void evaluateFullTadpole(Numerator & num,
0378 const CutsVector<cuts::Triangle> & triangle,
0379 const CutsVector<cuts::Bubble> & bubble,
0380 cuts::Tadpole & tadpole);
0381
0382
0383 void NeqNtest(Numerator & num,
0384 const CutsVector<cuts::Pentagon> & pentagon,
0385 const CutsVector<cuts::Box> & box,
0386 const CutsVector<cuts::Triangle> & triangle,
0387 const CutsVector<cuts::Bubble> & bubble,
0388 const CutsVector<cuts::Tadpole> & tadpole,
0389 const ComplexMomentum & q, const Complex & muq);
0390
0391 void local4NeqNtests(Numerator & num,
0392 const CutsVector<cuts::Pentagon> & pentagon,
0393 const CutsVector<cuts::Box> & box);
0394 void local3NeqNtests(Numerator & num,
0395 const CutsVector<cuts::Pentagon> & pentagon,
0396 const CutsVector<cuts::Box> & box,
0397 const CutsVector<cuts::Triangle> & triangle);
0398 void local2NeqNtests(Numerator & num,
0399 const CutsVector<cuts::Pentagon> & pentagon,
0400 const CutsVector<cuts::Box> & box,
0401 const CutsVector<cuts::Triangle> & triangle,
0402 const CutsVector<cuts::Bubble> & bubble);
0403 void local1NeqNtests(Numerator & num,
0404 const CutsVector<cuts::Pentagon> & pentagon,
0405 const CutsVector<cuts::Box> & box,
0406 const CutsVector<cuts::Triangle> & triangle,
0407 const CutsVector<cuts::Bubble> & bubble,
0408 const CutsVector<cuts::Tadpole> & tadpole);
0409
0410
0411
0412
0413 int higherRankEvaluate(Numerator & num);
0414
0415 void evaluatePentagons(Numerator & num,
0416 CutsVector<x1cuts::Pentagon> & pentagon);
0417 void evaluatePentagon(Numerator & num,
0418 x1cuts::Pentagon & pentagon);
0419
0420 void evaluateBoxes(Numerator & num,
0421 const CutsVector<x1cuts::Pentagon> & pentagon,
0422 CutsVector<x1cuts::Box> & box);
0423 void evaluateBox(Numerator & num,
0424 const CutsVector<x1cuts::Pentagon> & pentagon,
0425 x1cuts::Box & box);
0426
0427 void evaluateFullBoxes(Numerator & num,
0428 const CutsVector<x1cuts::Pentagon> & pentagon,
0429 CutsVector<x1cuts::Box> & box);
0430 void evaluateFullBox(Numerator & num,
0431 const CutsVector<x1cuts::Pentagon> & pentagon,
0432 x1cuts::Box & box);
0433
0434 void evaluateTriangles(Numerator & num,
0435 CutsVector<x1cuts::Triangle> & triangle);
0436 void evaluateTriangle(Numerator & num,
0437 x1cuts::Triangle & triangle);
0438
0439 void evaluateBubbles(Numerator & num,
0440 const CutsVector<x1cuts::Triangle> & triangle,
0441 CutsVector<x1cuts::Bubble> & bubble);
0442 void evaluateBubble(Numerator & num,
0443 const CutsVector<x1cuts::Triangle> & triangle,
0444 x1cuts::Bubble & bubble);
0445
0446 void evaluateTadpoles(Numerator & num,
0447 const CutsVector<x1cuts::Triangle> & triangle,
0448 const CutsVector<x1cuts::Bubble> & bubble,
0449 CutsVector<x1cuts::Tadpole> & tadpole);
0450 void evaluateTadpole(Numerator & num,
0451 const CutsVector<x1cuts::Triangle> & triangle,
0452 const CutsVector<x1cuts::Bubble> & bubble,
0453 x1cuts::Tadpole & tadpole);
0454
0455 void evaluateFullTadpoles(Numerator & num,
0456 const CutsVector<x1cuts::Triangle> & triangle,
0457 const CutsVector<x1cuts::Bubble> & bubble,
0458 CutsVector<x1cuts::Tadpole> & tadpole);
0459 void evaluateFullTadpole(Numerator & num,
0460 const CutsVector<x1cuts::Triangle> & triangle,
0461 const CutsVector<x1cuts::Bubble> & bubble,
0462 x1cuts::Tadpole & tadpole);
0463
0464
0465
0466 template <typename T>
0467 bool stability_check(const T & z)
0468 {
0469 if (taxicab_norm(z) < fp_threshold) {
0470 return_val = return_val | UNSTABLE_KINEMATICS;
0471 return false;
0472 }
0473 return true;
0474 }
0475
0476
0477 bool unstable_kinematics() const
0478 {
0479 if (return_val & UNSTABLE_KINEMATICS) {
0480 if (Options::verb) {
0481 (*Options::out) << std::endl
0482 << "ninja::Amplitude is returning "
0483 << "UNSTABLE_KINEMATICS" << std::endl;
0484 }
0485 return true;
0486 }
0487 return false;
0488 }
0489
0490
0491 void NeqNtest(Numerator & num,
0492 const CutsVector<x1cuts::Pentagon> & pentagon,
0493 const CutsVector<x1cuts::Box> & box,
0494 const CutsVector<x1cuts::Triangle> & triangle,
0495 const CutsVector<x1cuts::Bubble> & bubble,
0496 const CutsVector<x1cuts::Tadpole> & tadpole,
0497 const ComplexMomentum & q, const Complex & muq);
0498
0499 void local4NeqNtests(Numerator & num,
0500 const CutsVector<x1cuts::Pentagon> & pentagon,
0501 const CutsVector<x1cuts::Box> & box);
0502 void local3NeqNtests(Numerator & num,
0503 const CutsVector<x1cuts::Pentagon> & pentagon,
0504 const CutsVector<x1cuts::Box> & box,
0505 const CutsVector<x1cuts::Triangle> & triangle);
0506 void local2NeqNtests(Numerator & num,
0507 const CutsVector<x1cuts::Pentagon> & pentagon,
0508 const CutsVector<x1cuts::Box> & box,
0509 const CutsVector<x1cuts::Triangle> & triangle,
0510 const CutsVector<x1cuts::Bubble> & bubble);
0511 void local1NeqNtests(Numerator & num,
0512 const CutsVector<x1cuts::Pentagon> & pentagon,
0513 const CutsVector<x1cuts::Box> & box,
0514 const CutsVector<x1cuts::Triangle> & triangle,
0515 const CutsVector<x1cuts::Bubble> & bubble,
0516 const CutsVector<x1cuts::Tadpole> & tadpole);
0517
0518
0519 ninja::details::Array3D<Complex> result;
0520 SMatrix s_mat;
0521 const RealMomentum * V;
0522 IntegralLibrary * mis;
0523 MassConstPtr m2;
0524 Complex cut_constr;
0525 Real scale, fp_threshold;
0526 int n, rank;
0527 int min_cut;
0528 int return_val;
0529 bool use_mu_exp;
0530
0531 };
0532
0533
0534 template <typename MassType>
0535 inline Amplitude<MassType>::Amplitude(int nn, int rr, const RealMomentum p[])
0536 : result(0.,0.,0.),
0537 s_mat(0,0),
0538 V(p),
0539 mis(Options::mis),
0540 m2(static_cast<const MassType*>(0)),
0541 cut_constr(),
0542 scale(1.),
0543 fp_threshold(Options::fp_threshold),
0544 n(nn), rank(rr),
0545 min_cut(0),
0546 return_val(SUCCESS),
0547 use_mu_exp(true)
0548 {
0549
0550 details::MasslessTypeError<MassType>::MassType_must_be_massless();
0551 }
0552
0553 }
0554
0555 #undef NINJA_NINJA_HH_INSIDE
0556
0557 #endif