Himalaya
HierarchyCalculator.cpp
Go to the documentation of this file.
1 // ====================================================================
2 // This file is part of Himalaya.
3 //
4 // Himalaya is licenced under the GNU General Public License (GNU GPL)
5 // version 3.
6 // ====================================================================
7 
10 #include "himalaya/version.hpp"
11 
21 #include "himalaya/misc/Logger.hpp"
22 #include "himalaya/misc/Powers.hpp"
23 #include "himalaya/misc/RAII.hpp"
24 
25 #include <algorithm>
26 #include <array>
27 #include <cmath>
28 #include <iostream>
29 #include <numeric>
30 #include <stdexcept>
31 #include <string>
32 
33 #include <Eigen/Eigenvalues>
34 
35 /**
36  * @file HierarchyCalculator.cpp
37  * @brief Implementation of the HierarchyCalculator.
38  */
39 
40 namespace himalaya {
41 
42 static bool isInfoPrinted; ///< if true, no info will be printed
43 
44 namespace {
45 
46 /**
47  * Returns sqrt of smallest eigenvalue of given 2x2 matrix.
48  * @param matrix the matrix whose eigenvalues should be computed
49  * @return sqrt of smallest eigenvalue
50  */
51 double calcSmallestEigenvalue(const Eigen::Matrix2d& matrix)
52 {
53  Eigen::EigenSolver<Eigen::Matrix2d> solver(matrix, false);
54  const auto eigenvalues = solver.eigenvalues().real().cwiseSqrt();
55 
56  return eigenvalues(0) < eigenvalues(1) ? eigenvalues(0) : eigenvalues(1);
57 }
58 
59 /// set flags to omit all corrections, except O(at*as^n)
60 void disable_non_as_terms(himalaya::mh2_eft::Mh2EFTCalculator& mhc)
61 {
82 }
83 
84 /**
85  * Maps a hierarchy to it's mother hierarchy.
86  * @param hierarchy the key to a hierarchy.
87  * @throws runtime_error Throws a runtime_error if the given hierarchy is not included.
88  * @returns The key of the mother hierarchy.
89  */
90 int getMotherHierarchy(int hierarchy)
91 {
92  using namespace himalaya::hierarchies;
93 
94  if (hierarchy < Hierarchies::Hierarchies::FIRST ||
96  if (hierarchy == -1) {
97  throw std::runtime_error("No suitable hierarchy found!");
98  }
99  throw std::runtime_error("Hierarchy " + std::to_string(hierarchy) +
100  " not included!");
101  }
102 
103  // maps all hierarchies to their mother hierarchy
104  static const auto hierarchyMap = [] {
105  std::array<int, Hierarchies::NUMBER_OF_HIERARCHIES> a{};
120  return a;
121  }();
122 
123  return hierarchyMap.at(hierarchy);
124 }
125 
126 /**
127  * Prints out some information about Himalaya.
128  */
129 void printInfo()
130 {
131  std::cerr << "........................................................................\n";
132  std::cerr << "Himalaya " << Himalaya_VERSION_MAJOR << "." << Himalaya_VERSION_MINOR << "." << Himalaya_VERSION_RELEASE << "\tѧѦѧ \n";
133  std::cerr << "Uses code by\n";
134  std::cerr << " P. Slavich et al. (2-loop αt*αs) [hep-ph/0105096]\n";
135  std::cerr << " P. Slavich et al. (2-loop αt^2) [hep-ph/0305127]\n";
136  std::cerr << " P. Slavich et al. (2-loop αb*ατ) [hep-ph/0406166]\n";
137  std::cerr << " P. Slavich et al. (2-loop ατ^2) [hep-ph/0112177]\n";
138  std::cerr << "Uses contributions\n";
139  std::cerr << " 3-loop αt*αs^2 to Mh^2 of Kant et al. [arXiv:1005.5709]\n";
140  std::cerr << " 2-loop αt*αs to λ of Bagnaschi et.al. [arXiv:1407.4081]\n";
141  std::cerr << " 2-loop αt^2 to λ of Bagnaschi et.al. [arXiv:1703.08166]\n";
142  std::cerr << " 2-loop αs^2 to yt of Bednyakov et.al. [hep-ph/0210258, hep-ph/0507139]\n";
143  std::cerr << "........................................................................\n";
144 }
145 
146 } // anonymous namespace
147 
148 /**
149  * Constructor
150  * @param p_ a HimalayaInterface struct
151  * @param verbose_ suppress informative output during the calculation, if set to false
152  */
154  : p(p_), verbose(verbose_)
155 {
156  if (!isInfoPrinted && verbose) {
157  printInfo();
158  isInfoPrinted = true;
159  }
160 
161  p.validate(verbose);
162 
163  expansionDepth.fill(1);
164 }
165 
166 /**
167  * Calculates the 3-loop mass matrix and other information of the hierarchy selection process.
168  * @param isAlphab a bool which determines if the returned object is proportinal to alpha_b.
169  * @return A HierarchyObject which holds all information of the calculation.
170  */
172 {
173  HierarchyObject ho (isAlphab);
174 
175  if (isAlphab)
176  INFO_MSG("3-loop threshold correction Δλ not available for O(αb*αs^2)!");
177 
178  const int mdrFlag = 0;
179 
180  // set mdrFlag
181  ho.setMDRFlag(mdrFlag);
182 
183  // compare hierarchies and get the best fitting hierarchy
184  compareHierarchies(ho);
185 
186  // calculate the 3-loop Higgs mass matrix for the obtained hierachy in the (M)DRbar' scheme
187  ho.setDMh(3, calculateHierarchy(ho, 0, 0, 1) + shiftH3mToDRbarPrime(ho));
188 
189  // set the alpha_x contributions
190  ho.setDMh(1, getMt41L(ho, mdrFlag, mdrFlag));
191 
192  // set the alpha_x*alpha_s contributions
193  ho.setDMh(2, getMt42L(ho, mdrFlag, mdrFlag));
194 
195  // estimate the uncertainty of the expansion at 3-loop level
197  ho.getDMh(0) + ho.getDMh(1)
198  + ho.getDMh(2), 0, 0, 1));
199 
200  // set the uncertainty of the expansion at 1-loop level to 0 by default,
201  // if the user needs this value getExpansionUncertainty should be called
202  ho.setDMhExpUncertainty(1, 0.);
203 
204  // calculate shifts needed to convert DR' to other renormalization schemes,
205  // here one needs it with the minus sign to convert DR -> H3m
207 
208  // to obtain delta_lambda one has to divide the difference of the two calculations by v^2
209  const double v2 = calcV2();
210  const double gt = sqrt2*p.Mt/std::sqrt(v2);
211 
212  // calculate delta_lambda @ 3-loop level
213  calcDeltaLambda3L(ho, false);
214 
215  // create a modified parameters struct and construct
216  // Mh2EFTCalculator and ThresholdCalculator
217  auto p_mass_ES = p;
218  p_mass_ES.mu2(2,2) = pow2(p.MSt(0));
219  p_mass_ES.mq2(2,2) = pow2(p.MSt(1));
220  himalaya::mh2_eft::Mh2EFTCalculator mh2EFTCalculator(p_mass_ES);
222  disable_non_as_terms(mh2EFTCalculator); // omit all but O(at*as^n)
223 
224  // mh_eft^2
225  const double mh2_eft = mh2EFTCalculator.getDeltaMh2EFT0Loop();
226  // 1-Loop prefactor at
227  const double pref_1L = oneLoop * pow2(p.Mt * gt);
228  // 2-Loop prefactor at*as
229  const double pref_2L = twoLoop * pow2(p.Mt * gt * p.g3);
230 
231  ho.setDLambda(0, mh2_eft/v2);
232  ho.setDLambda(1, pref_1L*(tc.getThresholdCorrection(
234  ho.setDLambda(2, pref_2L*(tc.getThresholdCorrection(
236  ho.setDLambda(3, ho.getDLambdaEFT());
239  ho.setDLambdaDRbarPrimeToMSbarShift(2, pref_2L*(-4*ho.getDLambda(1)
242 
244  const auto dmh_fo = mfo.calculate_Mh2();
245  ho.setDMh2FO(0, std::get<0>(dmh_fo));
246  ho.setDMh2FO(1, std::get<1>(dmh_fo));
247  ho.setDMh2FO(2, std::get<2>(dmh_fo));
248  ho.setDMh2FO(3, 0); // filled later, see below
249 
251  const auto dmh_fo_atas = mfo_atas.calculate_Mh2();
252  ho.setDMh2FOAt(0, 0.);
253  ho.setDMh2FOAt(1, std::get<1>(dmh_fo_atas));
254  ho.setDMh2FOAt(2, std::get<2>(dmh_fo_atas));
255  ho.setDMh2FOAt(3, 0.); // filled later, see below
256 
257  // fill in results of EFT calculation
258  himalaya::mh2_eft::Mh2EFTCalculator mh2EFTCalculator_full(p);
259  ho.setDMh2EFT(0, mh2EFTCalculator_full.getDeltaMh2EFT0Loop());
260  ho.setDMh2EFT(1, mh2EFTCalculator_full.getDeltaMh2EFT1Loop(1, 1));
261  ho.setDMh2EFT(2, mh2EFTCalculator_full.getDeltaMh2EFT2Loop(1, 1));
262  ho.setDMh2EFT(3, mh2EFTCalculator_full.getDeltaMh2EFT3Loop(1, 1, 0)
263  + ho.getDLambdaEFT()*v2);
264 
265  {
266  auto ho_mdr = ho;
267  ho_mdr.setMDRFlag(1);
268  // calculate the DR to MDR shift with the obtained hierarchy
269  ho_mdr.setDMhDRbarPrimeToMDRbarPrimeShift(calcDRbarToMDRbarShift(ho_mdr, true, true));
270  ho_mdr.setDMh(3, calculateHierarchy(ho_mdr, 0, 0, 1) + shiftH3mToDRbarPrime(ho_mdr));
271  Eigen::Vector2d mdrMasses;
272  mdrMasses(0) = ho_mdr.getMDRMasses()(0);
273  mdrMasses(1) = ho_mdr.getMDRMasses()(1);
274  ho.setMDRMasses(mdrMasses);
275  ho.setDMhDRbarPrimeToMDRbarPrimeShift(ho_mdr.getDMhDRbarPrimeToMDRbarPrimeShift()
276  + ho_mdr.getDMh(3) - ho.getDMh(3));
277  }
278 
279  // perturbatively diagonalize
280  {
281  const auto DMh2 = fs_diagonalize_hermitian_perturbatively(
282  ho.getDMh(0), ho.getDMh(1), ho.getDMh(2), ho.getDMh(3));
283  ho.setDMh2(0, std::get<0>(DMh2)(0));
284  ho.setDMh2(1, std::get<1>(DMh2)(0));
285  ho.setDMh2(2, std::get<2>(DMh2)(0));
286  ho.setDMh2(3, std::get<3>(DMh2)(0));
287  // set 3L FO corrections to perturbatively diagonalized O(at*as^n) corrections
288  ho.setDMh2FO(3,std::get<3>(DMh2)(0));
289  ho.setDMh2FOAt(3,std::get<3>(DMh2)(0));
290  }
291 
292  return ho;
293 }
294 
295 /**
296  * Compares deviation of all hierarchies with the exact two-loop result and returns the hierarchy which minimizes the error.
297  * @param ho a HierarchyObject with constant isAlphab.
298  * @return An integer which is identified with the suitable hierarchy.
299  */
301 {
302  using namespace himalaya::hierarchies;
303 
304  // temporarily set flags to truncate the expansion
307 
308  double error = -1.;
309  int suitableHierarchy = -1;
310 
311  const double s2b = std::sin(2*calcBeta());
312  const double tb = calcTanBeta();
313 
314  // tree level Higgs mass matrix
315  Eigen::Matrix2d treelvl;
316  treelvl(0, 0) = 0.5 * s2b * (pow2(p.MZ) / tb + pow2(p.MA) * tb);
317  treelvl(1, 0) = 0.5 * s2b * (-pow2(p.MZ) - pow2(p.MA));
318  treelvl(0, 1) = treelvl(1, 0);
319  treelvl(1, 1) = 0.5 * s2b * (pow2(p.MZ) * tb + pow2(p.MA) / tb);
320 
321  ho.setDMh(0, treelvl);
322 
323  // compare the exact higgs mass at 2-loop level with the expanded expressions to find a suitable hierarchy
324  for (int hierarchy = Hierarchies::FIRST; hierarchy < Hierarchies::NUMBER_OF_HIERARCHIES; hierarchy++) {
325  // first, check if the hierarchy is suitable to the mass spectrum
326  ho.setSuitableHierarchy(hierarchy);
327 
328  if (isHierarchySuitable(ho)) {
329  // calculate the exact 1-loop result (only alpha_t/b)
330  const Eigen::Matrix2d Mt41L = getMt41L(ho, ho.getMDRFlag(), 0);
331 
332  // call the routine of Pietro Slavich to get the alpha_s alpha_t/b corrections with the MDRbar masses
333  const Eigen::Matrix2d Mt42L = getMt42L(ho, ho.getMDRFlag(), 0);
334 
335  // calculate the exact Higgs mass at 2-loop (only up to alpha_s alpha_t/b)
336  const double Mh2l = calcSmallestEigenvalue(treelvl + Mt41L + Mt42L);
337 
338  // calculate the expanded 2-loop expression with the specific hierarchy
339  const double Mh2LExpanded = calcSmallestEigenvalue(treelvl + Mt41L + calculateHierarchy(ho, 0, 1, 0));
340 
341  // estimate the error
342  const double twoLoopError = std::abs((Mh2l - Mh2LExpanded));
343 
344  // estimate the uncertainty of the expansion at 2L
345  const double expUncertainty2L = getExpansionUncertainty(ho, treelvl
346  + Mt41L, 0, 1, 0);
347 
348  // estimate the uncertainty of the expansion at 3L
349  const double expUncertainty3L = getExpansionUncertainty(ho, treelvl
350  + Mt41L + Mt42L, 0, 0, 1);
351 
352  // estimate the uncertainty of the difference of delta_lambda @ 3-loop
353  // normalized to the exact logarithms
354  calcDeltaLambda3L(ho, true);
355  /*const double deltaLambdaUncertainty = std::abs((ho.getDLambdaEFT()
356  - ho.getDLambdaH3m())/(ho.getDLambdaEFT() - ho.getDLambdaNonLog()));*/
357 
358  // add these errors to include the error of the expansion in the comparison
359  const double currError = std::sqrt(pow2(twoLoopError/Mh2l)
360  + pow2(expUncertainty2L/Mh2LExpanded));
361 
362  // If the error is negative, it is the first iteration and
363  // there is no hierarchy which fits better. Otherwise,
364  // compare the current error with the last error and choose
365  // the hierarchy which fits best (lowest error).
366  if (error < 0 || currError < error) {
367  error = currError;
368  suitableHierarchy = hierarchy;
369  ho.setAbsDiff2L(twoLoopError);
370  ho.setRelDiff2L(twoLoopError/Mh2l);
371  ho.setDMhExpUncertainty(2, expUncertainty2L);
372  ho.setDMhExpUncertainty(3, expUncertainty3L);
373  }
374  }
375  }
376  ho.setSuitableHierarchy(suitableHierarchy);
377 
378  return suitableHierarchy;
379 }
380 
381 /**
382  * Checks if a hierarchy is suitable to the given mass spectrum.
383  * @param ho a HierarchyObject with constant isAlphab and a hierarchy candidate.
384  * @returns A bool if the hierarchy candidate is suitable to the given mass spectrum.
385  */
387 {
388  using namespace himalaya::hierarchies;
389 
390  const double Mst1 = ho.getIsAlphab() ? p.MSb(0) : p.MSt(0);
391  const double Mst2 = ho.getIsAlphab() ? p.MSb(1) : p.MSt(1);
392 
393  // check if the squark mass is the heaviest mass
394  const double delta = 1.3; // allow for an offset of 30%
395  const double Mgl = p.MG;
396  const double Msq = calcMeanMsq();
397 
398  if (Mst2 > delta*Msq) return false;
399  if (Mgl > delta*Msq) return false;
400 
401  switch (ho.getSuitableHierarchy()) {
402  case Hierarchies::h3:
403  return Mgl > Mst2;
404  case Hierarchies::h32q2g:
405  return (Mst2 >= Msq) && (Mst2 > Mgl);
406  case Hierarchies::h3q22g:
407  return (Msq > Mst2) && (Mst2 > Mgl);
408  case Hierarchies::h4:
409  return (Mst1 < Msq) && (Mst1 >= Mgl);
410  case Hierarchies::h5:
411  return (Mst2 - Mst1 > 0.1*Mst1) && ((Mgl - Mst1) < std::abs(Mgl - Mst2)) && (Mst2 < Msq) && (Mst1 >= Mgl);
412  case Hierarchies::h5g1:
413  return (Mst2 - Mst1 > 0.1*Mst1) && ((Mgl - Mst1) < std::abs(Mgl - Mst2)) && (Mst2 < Msq) && (Mgl > Mst1);
414  case Hierarchies::h6:
415  return (Mst2 - Mst1 > 0.1*Mst1) && ((Mst2 - Mgl) < std::abs(Mgl - Mst1)) && (Mst2*1.3 < Msq) && (Mst2 >= Mgl);
416  case Hierarchies::h6g2:
417  return (Mst2 - Mst1 > 0.1*Mst1) && ((Mst2 - Mgl) < std::abs(Mgl - Mst1)) && (Mst2*1.3 < Msq) && (Mgl > Mst2);
418  case Hierarchies::h6b:
419  return (Mst2 - Mst1 > 0.1*Mst1) && ((Mst2 - Mgl) < std::abs(Mgl - Mst1)) && (Mst2 >= Msq) && (Mst2 >= Mgl);
421  return (Mst2 - Mst1 > 0.1*Mst1) && ((Mst2 - Mgl) < std::abs(Mgl - Mst1)) && (Mst2 >= Msq) && (Mgl > Mst2);
423  return (Mst2 - Mst1 > 0.1*Mst1) && ((Mst2 - Mgl) < std::abs(Mgl - Mst1)) && (Msq > Mst2) && (Mst2 >= Mgl);
425  return (Mst2 - Mst1 > 0.1*Mst1) && ((Mst2 - Mgl) < std::abs(Mgl - Mst1)) && (Msq > Mst2) && (Mgl > Mst2);
426  case Hierarchies::h9:
427  return (Mst2 >= Msq) && ((Mst2 - Mst1) < (Mst1 - Mgl));
428  case Hierarchies::h9q2:
429  return (Msq > Mst2) && ((Mst1 - Mst1) < (Mst1 - Mgl));
430  }
431  return false;
432 }
433 
434 
435 std::array<double, 2>
437 {
438  if (loopOrder == 1) {
439  return { shiftMst1ToMDR(ho, 0, 0), shiftMst2ToMDR(ho, 0, 0) };
440  }
441  if (loopOrder == 2) {
442  return { shiftMst1ToMDR(ho, ho.getMDRFlag(), 0),
443  shiftMst2ToMDR(ho, ho.getMDRFlag(), 0) };
444  }
445  if (loopOrder == 3) {
446  return { shiftMst1ToMDR(ho, ho.getMDRFlag(), ho.getMDRFlag()),
447  shiftMst2ToMDR(ho, ho.getMDRFlag(), ho.getMDRFlag()) };
448  }
449  throw std::runtime_error("There are no tree-level hierarchies included!");
450 }
451 
452 
453 /**
454  * Calculates the hierarchy contributions for a specific hierarchy at
455  * a specific loop order.
456  *
457  * Note: The hierarchy files containing 1-, 2- and 3-loop terms
458  * (αs^0 αt/b, αs αt/b, αs^2 αt/b).
459  *
460  * @todo If one is interested in the expansion at one- and two-loop,
461  * choose a unified choice for the MDR scheme.
462  *
463  * @param ho a HierarchyObject with constant isAlphab.
464  * @param oneLoopFlagIn an integer flag which is 0 or 1 in order to add or omit the expanded one-loop results to the returned value, respectivley.
465  * @param twoLoopFlagIn an integer flag which is 0 or 1 in order to add or omit the expanded two-loop results to the returned value, respectivley.
466  * @param threeLoopFlagIn an integer flag which is 0 or 1 in order to add or omit the expanded three-loop results to the returned value, respectivley.
467  * @throws runtime_error Throws a runtime_error if the tree-level is requested in terms of hierarchies.
468  * @return The loop corrected Higgs mass matrix which contains the expanded corrections at the given order.
469  */
471  HierarchyObject& ho, int oneLoopFlagIn,
472  int twoLoopFlagIn, int threeLoopFlagIn) const
473 {
474  // returnde self-energy contributions
475  double selfEnergy11 = 0., selfEnergy22 = 0., selfEnergy12 = 0.;
476 
477  // get the hierarchy
478  const int hierarchy = ho.getSuitableHierarchy();
479 
480  // common variables
481  const double Mf = ho.getIsAlphab() ? p.Mb : p.Mt;
482  const double s2f = ho.getIsAlphab() ? p.s2b : p.s2t;
483  const double Msq = calcMeanMsq();
484  const double lmMf = std::log(pow2(p.scale / Mf));
485  const bool onlyThreeLoop = oneLoopFlagIn == 0 && twoLoopFlagIn == 0 && threeLoopFlagIn == 1;
486 
487  // calculates contributions to Delta lambda and stores them in ho
488  const auto calcDlambda = [] (HierarchyObject& ho, const auto& hier, double lmMsf1) {
489  const double c = hier.calc_coef_at_as2_no_sm_logs_log0();
490  ho.setDLambdaH3m(c
491  + lmMsf1 * hier.calc_coef_at_as2_no_sm_logs_log1()
492  + pow2(lmMsf1) * hier.calc_coef_at_as2_no_sm_logs_log2()
493  + pow3(lmMsf1) * hier.calc_coef_at_as2_no_sm_logs_log3());
494  ho.setDLambdaNonLog(c);
495  };
496 
497  struct LoopFlags {
498  bool runThisOrder = false;
499  int oneLoop{}, twoLoop{}, threeLoop{};
500  };
501 
502  // sets flags for the loop
503  const auto setLoopFlags = [oneLoopFlagIn, twoLoopFlagIn, threeLoopFlagIn] (int loopOrder) {
504  if (loopOrder == 0) {
505  return LoopFlags{false, 0, 0, 0};
506  } else if (loopOrder == 1) {
507  const bool runThisOrder = oneLoopFlagIn != 0;
508  return LoopFlags{runThisOrder, 1, 0, 0};
509  } else if (loopOrder == 2) {
510  const bool runThisOrder = twoLoopFlagIn != 0;
511  return LoopFlags{runThisOrder, 0, 1, 0};
512  } else if (loopOrder == 3) {
513  const bool runThisOrder = threeLoopFlagIn != 0;
514  return LoopFlags{runThisOrder, 0, 0, 1};
515  }
516 
517  throw std::runtime_error("setLoopFlags: invalid loop order (must be 1, 2 or 3)");
518  };
519 
520  // this loop is needed to calculate the suitable mass shift order by order
521  for (int loopOrder = 1; loopOrder <= 3; loopOrder++) {
522  // set flags to be used in the loop body
523  const auto loopFlags = setLoopFlags(loopOrder);
524 
525  if (loopFlags.runThisOrder) {
526  using namespace himalaya::hierarchies;
527 
528  // set the stop masses according to MDRFlag
529  const auto Msf = calcMsfMDRFlag(ho, loopOrder);
530  const double Msf1 = Msf.at(0);
531  const double Msf2 = Msf.at(1);
532 
533  // calculate self-energy contributions and Delta lambda terms
534  // for suitable hierarchy
535  switch (hierarchy) {
536  case Hierarchies::h3: {
537  const double Dmglst1 = p.MG - Msf1;
538  const double Dmsqst1 = pow2(Msq) - pow2(Msf1);
539  const double Dmsf12 = pow2(Msf1) - pow2(Msf2);
540  const double lmMsf1 = std::log(pow2(p.scale / Msf1));
541  const H3 hier(expansionDepth, calcAsOver4Pi(), calcBeta(),
542  Dmglst1, Dmsf12, Dmsqst1, lmMf, lmMsf1,
543  p.MG, Mf, Msf1, Msf2, Msq, p.mu, s2f,
544  ho.getMDRFlag(), loopFlags.oneLoop, loopFlags.twoLoop, loopFlags.threeLoop);
545  selfEnergy11 += hier.getS1();
546  selfEnergy22 += hier.getS2();
547  selfEnergy12 += hier.getS12();
548  if (onlyThreeLoop) {
549  calcDlambda(ho, hier, lmMsf1);
550  }
551  } // h3
552  break;
553 
554  case Hierarchies::h32q2g: {
555  const double Dmglst1 = p.MG - Msf1;
556  const double Dmsqst1 = pow2(Msq) - pow2(Msf1);
557  const double Dmsf12 = pow2(Msf1) - pow2(Msf2);
558  const double lmMsf1 = std::log(pow2(p.scale / Msf1));
559  const H32q2g hier(expansionDepth, calcAsOver4Pi(), calcBeta(),
560  Dmglst1, Dmsf12, Dmsqst1, lmMf, lmMsf1,
561  Mf, Msf1, Msf2, p.mu, s2f,
562  ho.getMDRFlag(), loopFlags.oneLoop, loopFlags.twoLoop, loopFlags.threeLoop);
563  selfEnergy11 += hier.getS1();
564  selfEnergy22 += hier.getS2();
565  selfEnergy12 += hier.getS12();
566  if (onlyThreeLoop) {
567  calcDlambda(ho, hier, lmMsf1);
568  }
569  } // h32q2g
570  break;
571 
572  case Hierarchies::h3q22g: {
573  const double Dmglst1 = p.MG - Msf1;
574  const double Dmsqst1 = pow2(Msq) - pow2(Msf1);
575  const double Dmsf12 = pow2(Msf1) - pow2(Msf2);
576  const double lmMsf1 = std::log(pow2(p.scale / Msf1));
577  const H3q22g hier(expansionDepth, calcAsOver4Pi(), calcBeta(),
578  Dmglst1, Dmsf12, Dmsqst1, lmMf, lmMsf1,
579  Mf, Msf1, Msf2, Msq, p.mu, s2f,
580  ho.getMDRFlag(), loopFlags.oneLoop, loopFlags.twoLoop, loopFlags.threeLoop);
581  selfEnergy11 += hier.getS1();
582  selfEnergy22 += hier.getS2();
583  selfEnergy12 += hier.getS12();
584  if (onlyThreeLoop) {
585  calcDlambda(ho, hier, lmMsf1);
586  }
587  } // h3q22g
588  break;
589 
590  case Hierarchies::h4: {
591  const double Msusy = (Msf1 + Msf2 + p.MG) / 3.;
592  const double lmMsusy = std::log(pow2(p.scale / Msusy));
593  const double lmMsf1 = std::log(pow2(p.scale / Msf1));
594  const double lmMsq = std::log(pow2(p.scale / calcMeanMsq()));
595  const double At = ho.getIsAlphab() ? p.Ad(2,2) : p.Au(2,2);
596  const H4 hier(expansionDepth, calcAsOver4Pi(), At, calcBeta(),
597  lmMf, lmMsq, lmMsusy, Mf, Msusy, Msq,
598  ho.getMDRFlag(), loopFlags.oneLoop, loopFlags.twoLoop, loopFlags.threeLoop);
599  selfEnergy11 += hier.getS1();
600  selfEnergy22 += hier.getS2();
601  selfEnergy12 += hier.getS12();
602  if (onlyThreeLoop) {
603  calcDlambda(ho, hier, lmMsf1);
604  }
605  } // h4
606  break;
607 
608  case Hierarchies::h5: {
609  const double Dmglst1 = p.MG - Msf1;
610  const double lmMsf1 = std::log(pow2(p.scale / Msf1));
611  const double lmMsf2 = std::log(pow2(p.scale / Msf2));
612  const double lmMsq = std::log(pow2(p.scale / calcMeanMsq()));
613  const H5 hier(expansionDepth, calcAsOver4Pi(), calcBeta(), Dmglst1,
614  lmMf, lmMsf1, lmMsf2, lmMsq, Mf, Msf1,
615  Msf2, Msq, p.mu, s2f,
616  ho.getMDRFlag(), loopFlags.oneLoop, loopFlags.twoLoop, loopFlags.threeLoop);
617  selfEnergy11 += hier.getS1();
618  selfEnergy22 += hier.getS2();
619  selfEnergy12 += hier.getS12();
620  if (onlyThreeLoop) {
621  calcDlambda(ho, hier, lmMsf1);
622  }
623  } // h5
624  break;
625 
626  case Hierarchies::h5g1: {
627  const double Dmglst1 = p.MG - Msf1;
628  const double lmMsf1 = std::log(pow2(p.scale / Msf1));
629  const double lmMsf2 = std::log(pow2(p.scale / Msf2));
630  const double lmMsq = std::log(pow2(p.scale / calcMeanMsq()));
631  const H5g1 hier(expansionDepth, calcAsOver4Pi(), calcBeta(), Dmglst1,
632  lmMf, lmMsf1, lmMsf2, lmMsq, p.MG, Mf, Msf1,
633  Msf2, Msq, p.mu, s2f,
634  ho.getMDRFlag(), loopFlags.oneLoop, loopFlags.twoLoop, loopFlags.threeLoop);
635  selfEnergy11 += hier.getS1();
636  selfEnergy22 += hier.getS2();
637  selfEnergy12 += hier.getS12();
638  if (onlyThreeLoop) {
639  calcDlambda(ho, hier, lmMsf1);
640  }
641  } // h5g1
642  break;
643 
644  case Hierarchies::h6: {
645  const double Dmglst2 = p.MG - Msf2;
646  const double lmMsf1 = std::log(pow2(p.scale / Msf1));
647  const double lmMsf2 = std::log(pow2(p.scale / Msf2));
648  const double lmMsq = std::log(pow2(p.scale / calcMeanMsq()));
649  const H6 hier(expansionDepth, calcAsOver4Pi(), calcBeta(), Dmglst2,
650  lmMf, lmMsf1, lmMsf2, lmMsq,
651  Mf, Msf1, Msf2, Msq, p.mu, s2f,
652  ho.getMDRFlag(), loopFlags.oneLoop, loopFlags.twoLoop, loopFlags.threeLoop);
653  selfEnergy11 += hier.getS1();
654  selfEnergy22 += hier.getS2();
655  selfEnergy12 += hier.getS12();
656  if (onlyThreeLoop) {
657  calcDlambda(ho, hier, lmMsf1);
658  };
659  } // h6
660  break;
661 
662  case Hierarchies::h6g2: {
663  const double Dmglst2 = p.MG - Msf2;
664  const double lmMsf1 = std::log(pow2(p.scale / Msf1));
665  const double lmMsf2 = std::log(pow2(p.scale / Msf2));
666  const double lmMsq = std::log(pow2(p.scale / calcMeanMsq()));
667  const H6g2 hier(expansionDepth, calcAsOver4Pi(), calcBeta(), Dmglst2,
668  lmMf, lmMsf1, lmMsf2, lmMsq,
669  p.MG, Mf, Msf1, Msf2, Msq, p.mu, s2f,
670  ho.getMDRFlag(), loopFlags.oneLoop, loopFlags.twoLoop, loopFlags.threeLoop);
671  selfEnergy11 += hier.getS1();
672  selfEnergy22 += hier.getS2();
673  selfEnergy12 += hier.getS12();
674  if (onlyThreeLoop) {
675  calcDlambda(ho, hier, lmMsf1);
676  }
677  } // h6g2
678  break;
679 
680  case Hierarchies::h6b: {
681  const double Dmglst2 = p.MG - Msf2;
682  const double Dmsqst2 = Msq - Msf2;
683  const double lmMsf1 = std::log(pow2(p.scale / Msf1));
684  const double lmMsf2 = std::log(pow2(p.scale / Msf2));
685  const H6b hier(expansionDepth, calcAsOver4Pi(), calcBeta(), Dmglst2,
686  Dmsqst2, lmMf, lmMsf1, lmMsf2,
687  Mf, Msf1, Msf2, p.mu, s2f,
688  ho.getMDRFlag(), loopFlags.oneLoop, loopFlags.twoLoop, loopFlags.threeLoop);
689  selfEnergy11 += hier.getS1();
690  selfEnergy22 += hier.getS2();
691  selfEnergy12 += hier.getS12();
692  if (onlyThreeLoop) {
693  calcDlambda(ho, hier, lmMsf1);
694  }
695  } // h6b
696  break;
697 
698  case Hierarchies::h6b2qg2: {
699  const double Dmglst2 = p.MG - Msf2;
700  const double Dmsqst2 = Msq - Msf2;
701  const double lmMsf1 = std::log(pow2(p.scale / Msf1));
702  const double lmMsf2 = std::log(pow2(p.scale / Msf2));
703  const H6b2qg2 hier(expansionDepth, calcAsOver4Pi(), calcBeta(), Dmglst2,
704  Dmsqst2, lmMf, lmMsf1, lmMsf2,
705  p.MG, Mf, Msf1, Msf2, p.mu, s2f,
706  ho.getMDRFlag(), loopFlags.oneLoop, loopFlags.twoLoop, loopFlags.threeLoop);
707  selfEnergy11 += hier.getS1();
708  selfEnergy22 += hier.getS2();
709  selfEnergy12 += hier.getS12();
710  if (onlyThreeLoop) {
711  calcDlambda(ho, hier, lmMsf1);
712  }
713  } // h6b2qg2
714  break;
715 
716  case Hierarchies::h6bq22g: {
717  const double Dmglst2 = p.MG - Msf2;
718  const double Dmsqst2 = Msq - Msf2;
719  const double lmMsf1 = std::log(pow2(p.scale / Msf1));
720  const double lmMsf2 = std::log(pow2(p.scale / Msf2));
721  const H6bq22g hier(expansionDepth, calcAsOver4Pi(), calcBeta(), Dmglst2,
722  Dmsqst2, lmMf, lmMsf1, lmMsf2,
723  Mf, Msf1, Msf2, Msq, p.mu, s2f,
724  ho.getMDRFlag(), loopFlags.oneLoop, loopFlags.twoLoop, loopFlags.threeLoop);
725  selfEnergy11 += hier.getS1();
726  selfEnergy22 += hier.getS2();
727  selfEnergy12 += hier.getS12();
728  if (onlyThreeLoop) {
729  calcDlambda(ho, hier, lmMsf1);
730  }
731  } // h6bq22g
732  break;
733 
734  case Hierarchies::h6bq2g2: {
735  const double Dmglst2 = p.MG - Msf2;
736  const double Dmsqst2 = Msq - Msf2;
737  const double lmMsf1 = std::log(pow2(p.scale / Msf1));
738  const double lmMsf2 = std::log(pow2(p.scale / Msf2));
739  const H6bq2g2 hier(expansionDepth, calcAsOver4Pi(), calcBeta(), Dmglst2,
740  Dmsqst2, lmMf, lmMsf1, lmMsf2,
741  p.MG, Mf, Msf1,Msf2, Msq, p.mu, s2f,
742  ho.getMDRFlag(), loopFlags.oneLoop, loopFlags.twoLoop, loopFlags.threeLoop);
743  selfEnergy11 += hier.getS1();
744  selfEnergy22 += hier.getS2();
745  selfEnergy12 += hier.getS12();
746  if (onlyThreeLoop) {
747  calcDlambda(ho, hier, lmMsf1);
748  }
749  } // h6bq2g2
750  break;
751 
752  case Hierarchies::h9: {
753  const double lmMgl = std::log(pow2(p.scale / p.MG));
754  const double lmMsf1 = std::log(pow2(p.scale / Msf1));
755  const double Dmsf12 = pow2(Msf1) - pow2(Msf2);
756  const double Dmsqst1 = pow2(Msq) - pow2(Msf1);
757  const H9 hier(expansionDepth, calcAsOver4Pi(), calcBeta(), Dmsf12, Dmsqst1,
758  lmMf, lmMgl, lmMsf1,
759  p.MG, Mf, Msf1, Msf2, p.mu, s2f,
760  ho.getMDRFlag(), loopFlags.oneLoop, loopFlags.twoLoop, loopFlags.threeLoop);
761  selfEnergy11 += hier.getS1();
762  selfEnergy22 += hier.getS2();
763  selfEnergy12 += hier.getS12();
764  if (onlyThreeLoop) {
765  calcDlambda(ho, hier, lmMsf1);
766  }
767  } // h9
768  break;
769 
770  case Hierarchies::h9q2: {
771  const double lmMgl = std::log(pow2(p.scale / p.MG));
772  const double lmMsf1 = std::log(pow2(p.scale / Msf1));
773  const double Dmsf12 = pow2(Msf1) - pow2(Msf2);
774  const double Dmsqst1 = pow2(Msq) - pow2(Msf1);
775  const H9q2 hier(expansionDepth, calcAsOver4Pi(), calcBeta(), Dmsf12, Dmsqst1,
776  lmMf, lmMgl, lmMsf1,
777  p.MG, Mf, Msf1, Msf2, Msq, p.mu, s2f,
778  ho.getMDRFlag(), loopFlags.oneLoop, loopFlags.twoLoop, loopFlags.threeLoop);
779  selfEnergy11 += hier.getS1();
780  selfEnergy22 += hier.getS2();
781  selfEnergy12 += hier.getS12();
782  if (onlyThreeLoop) {
783  calcDlambda(ho, hier, lmMsf1);
784  }
785  } // h9q2
786  break;
787 
788  default:
789  throw std::runtime_error("calculateHierarchy: non-handled hierarchy");
790  break;
791  } // switch (hierarchy)
792  } // if (runThisOrder)
793  } // for looporder
794 
795  // add the MDR masses to the hierarchy object only if a 3-loop
796  // calculation has to be done, otherwise let the user decide
797  if (onlyThreeLoop) {
798  const auto Msf = calcMsfMDRFlag(ho, 3);
799  Eigen::Vector2d mdrMasses;
800  mdrMasses << Msf.at(0), Msf.at(1);
801  ho.setMDRMasses(mdrMasses);
802  }
803 
804  Eigen::Matrix2d higgsMassMatrix;
805  higgsMassMatrix << selfEnergy11, selfEnergy12, selfEnergy12, selfEnergy22;
806 
807  return calcHiggsMassMatrixPrefactor() * higgsMassMatrix;
808 }
809 
810 /**
811  * Shifts Msx1 according to the hierarchy to the MDR scheme.
812  * @param ho a HierarchyObject with constant isAlphab.
813  * @param oneLoopFlag an integer flag which is 0 or 1 in order to shift the order O(alpha_s).
814  * @param twoLoopFlag an integer flag which is 0 or 1 in order to shift the order O(alpha_s^2).
815  * @return A double which is the MDR sx_1 mass.
816  */
818  unsigned oneLoopFlag,
819  unsigned twoLoopFlag) const
820 {
821  using namespace himalaya::hierarchies;
822 
823  double Mst1mod = 0.;
824 
825  const double Mst1 = ho.getIsAlphab() ? p.MSb(0) : p.MSt(0);
826  const double Mst2 = ho.getIsAlphab() ? p.MSb(1) : p.MSt(1);
827  const double Al4p = calcAsOver4Pi();
828  const double Msq = calcMeanMsq();
829  const double Mgl = p.MG;
830  const double lmMst2 = std::log(pow2(p.scale) / pow2(Mst2));
831  const double lmMgl = std::log(pow2(p.scale / p.MG));
832  const double lmMsq = std::log(pow2(p.scale / calcMeanMsq()));
833  const double Dmglst2 = Mgl - Mst2;
834  const double mdr2mst1ka = (-8. * twoLoopFlag * pow2(Al4p)
835  * (10 * pow2(Msq) * (-1 + 2 * lmMsq + 2 * z2) + pow2(Mst2)
836  * (-1 + 2 * lmMst2 + 2 * z2))) / (3. * pow2(Mst1));
837 
838  switch (getMotherHierarchy(ho.getSuitableHierarchy())) {
839  case Hierarchies::h3:
840  case Hierarchies::h4:
841  case Hierarchies::h5:
842  Mst1mod = (1 + mdr2mst1ka);
843  break;
844  case Hierarchies::h6:
845  Mst1mod = (144 * oneLoopFlag * Al4p * (1 + lmMgl) * pow2(Mgl) * pow4(Msq) + 27 * (1 + mdr2mst1ka) * pow4(Msq) * pow2(Mst1) +
846  twoLoopFlag * pow2(Al4p) * Mgl * (-5 * (67 + 84 * lmMgl - 84 * lmMsq) * pow5(Mgl) - 40 * (43 + 30 * lmMgl - 30 * lmMsq) * pow3(Mgl) * pow2(Msq) +
847  288 * Dmglst2 * pow4(Msq) * (1 - 2 * z2) + 12 * Mgl * pow4(Msq) * (79 + 144 * pow2(lmMgl) - 150 * lmMsq +
848  90 * pow2(lmMsq) - 90 * lmMgl * (-3 + 2 * lmMsq) + 208 * z2))) / (27. * pow4(Msq) * pow2(Mst1));
849  break;
850  case Hierarchies::h6b:
851  Mst1mod = (48 * oneLoopFlag * Al4p * (1 + lmMgl) * pow2(Mgl) + 9 * (1 + mdr2mst1ka) * pow2(Mst1) +
852  8 * twoLoopFlag * pow2(Al4p) * (-135 * pow2(Msq) + 12 * Dmglst2 * Mgl * (1 - 22 * z2) +
853  pow2(Mgl) * (77 + 135 * lmMgl + 72 * pow2(lmMgl) - 75 * lmMsq -
854  90 * lmMgl * lmMsq + 45 * pow2(lmMsq) + 104 * z2))) / (9. * pow2(Mst1));
855  break;
856  case Hierarchies::h9:
857  Mst1mod = (1 + mdr2mst1ka);
858  break;
859  default:
860  break;
861  }
862 
863  return Mst1 * std::sqrt(Mst1mod);
864 }
865 
866 /**
867  * Shifts Msx2 according to the hierarchy to the MDR scheme.
868  * @param ho a HierarchyObject with constant isAlphab.
869  * @param oneLoopFlag an integer flag which is 0 or 1 in order to shift the order O(alpha_s).
870  * @param twoLoopFlag an integer flag which is 0 or 1 in order to shift the order O(alpha_s^2).
871  * @return A double which is the MDR sx_2 mass.
872  */
874  unsigned oneLoopFlag,
875  unsigned twoLoopFlag) const
876 {
877  using namespace himalaya::hierarchies;
878 
879  double Mst2mod = 0.;
880 
881  const double Mst2 = ho.getIsAlphab() ? p.MSb(1) : p.MSt(1);
882  const double Al4p = calcAsOver4Pi();
883  const double Mgl = p.MG;
884  const double Msq = calcMeanMsq();
885  const double lmMgl = std::log(pow2(p.scale / p.MG));
886  const double lmMsq = std::log(pow2(p.scale / calcMeanMsq()));
887  const double Dmglst2 = Mgl - Mst2;
888  const double mdr2mst2ka = (-80. * twoLoopFlag * pow2(Al4p)
889  * pow2(Msq) * (-1 + 2 * lmMsq + 2 * z2)) / (3. * pow2(Mst2));
890 
891  switch (getMotherHierarchy(ho.getSuitableHierarchy())) {
892  case Hierarchies::h3:
893  case Hierarchies::h4:
894  case Hierarchies::h5:
895  Mst2mod = (1 + mdr2mst2ka);
896  break;
897  case Hierarchies::h6:
898  Mst2mod = (144 * oneLoopFlag * Al4p * (1 + lmMgl) * pow2(Mgl) * pow4(Msq) + 27 * (1 + mdr2mst2ka) * pow4(Msq) * pow2(Mst2) +
899  twoLoopFlag * pow2(Al4p) * Mgl * (-5 * (67 + 84 * lmMgl - 84 * lmMsq) * pow5(Mgl) - 40 * (43 + 30 * lmMgl - 30 * lmMsq) * pow3(Mgl) * pow2(Msq) +
900  288 * Dmglst2 * pow4(Msq) * (1 - 2 * z2) + 12 * Mgl * pow4(Msq) * (79 + 144 * pow2(lmMgl) - 150 * lmMsq +
901  90 * pow2(lmMsq) - 90 * lmMgl * (-3 + 2 * lmMsq) + 208 * z2))) / (27. * pow4(Msq) * pow2(Mst2));
902  break;
903  case Hierarchies::h6b:
904  Mst2mod = (48 * oneLoopFlag * Al4p * (1 + lmMgl) * pow2(Mgl) + 9 * (1 + mdr2mst2ka) * pow2(Mst2) +
905  8 * twoLoopFlag * pow2(Al4p) * (-135 * pow2(Msq) + 12 * Dmglst2 * Mgl * (1 - 22 * z2) +
906  pow2(Mgl) * (77 + 135 * lmMgl + 72 * pow2(lmMgl) - 75 * lmMsq -
907  90 * lmMgl * lmMsq + 45 * pow2(lmMsq) + 104 * z2))) / (9. * pow2(Mst2));
908  break;
909  case Hierarchies::h9:
910  Mst2mod = (1 + mdr2mst2ka);
911  break;
912  default:
913  break;
914  }
915 
916  return Mst2 * std::sqrt(Mst2mod);
917 }
918 
919 /**
920  * Shifts the H3m renormalization scheme to DR' scheme. This shift has to be added to the H3m result!
921  * @param ho a HierarchyObject with constant isAlphab.
922  * @return A matrix which shifts the H3m scheme to the DR' scheme at three-loop level
923  *
924  */
926  const himalaya::HierarchyObject& ho) const
927 {
928  const int suitableHierarchy = ho.getSuitableHierarchy();
929 
930  // truncate shift at O(Xt^2) to be consistent with H3m result
931  const int truncateXt =
932  (suitableHierarchy == himalaya::hierarchies::Hierarchies::h3
933  || suitableHierarchy == himalaya::hierarchies::Hierarchies::h32q2g
934  || suitableHierarchy == himalaya::hierarchies::Hierarchies::h3q22g
935  || suitableHierarchy == himalaya::hierarchies::Hierarchies::h9
936  || suitableHierarchy == himalaya::hierarchies::Hierarchies::h9q2)
937  ? 0 : 1;
938 
939  const double tb = calcTanBeta();
940 
941  // stop masses
942  const double Mst1 = shiftMst1ToMDR(ho, ho.getMDRFlag(), ho.getMDRFlag());
943  const double Mst2 = shiftMst2ToMDR(ho, ho.getMDRFlag(), ho.getMDRFlag());
944  // Hierarchy h4 only covers O(Xt^0)
945  const double Xt = suitableHierarchy == himalaya::hierarchies::Hierarchies::h4
946  ? 0 : p.Au(2,2) - p.mu / tb;
947 
948  // threshold for degenerate squark mass case is 1% of the stop mass
949  const double eps = Mst1 * 0.01;
950 
951  // squared masses
952  const double Mst12 = pow2(Mst1);
953  const double Mgl = p.MG;
954  const double Mgl2 = pow2(p.MG);
955  const double Msq2 = pow2(calcMeanMsq());
956  const double scale2 = pow2(p.scale);
957  const double Xt2 = pow2(Xt);
958  const double Mst22 = pow2(Mst2);
959  const double Dmst12 = Mst12 - Mst22;
960 
961  // logarithms
962  const double lmMst1 = std::log(scale2 / Mst12);
963  const double lmMst2 = std::log(scale2 / Mst22);
964  const double lmMsq = std::log(scale2 / Msq2);
965  const double lmMgl = std::log(scale2 / Mgl2);
966 
967  // degenerate mass case flag
968  bool isDegenerate = false;
969 
970  // check for degenerate squark masses
971  if (std::abs(Mst1 - Mst2) < eps) {
972  const double Mst2shift = Mst1 + 0.5*std::sqrt(std::abs(Dmst12));
973  const double lmMst2shift = std::log(scale2 / pow2(Mst2shift));
974  // limit
975  const double lim = (32*Xt2*(-3*(1 + lmMgl)*pow2(Mgl) + 5*(1 + lmMsq)*Msq2 + (1 +
976  lmMst1)*pow2(Mst1))*pow2(p.mu))/(3.*pow6(Mst1));
977  // exact result
978  const double exact = (16*Xt2*(-6*(1 + lmMgl)*pow2(Mgl) + 10*(1 + lmMsq)*Msq2 + (1 +
979  lmMst1)*pow2(Mst1) + (1 + lmMst2)*pow2(Mst2))*pow2(p.mu)*(-4*std::log(Mst1/
980  Mst2)*pow2(Mst1)*pow2(Mst2) + pow4(Mst1) - pow4(Mst2)))/(pow2(Mst1)*
981  pow2(Mst2)*pow3(pow2(Mst1) - pow2(Mst2)));
982  // exact result with shifted stop_2 mass
983  const double exactShifted = (16*Xt2*(-6*(1 + lmMgl)*pow2(Mgl) + 10*(1 + lmMsq)*Msq2 + (1 +
984  lmMst1)*pow2(Mst1) + (1 + lmMst2shift)*pow2(Mst2shift))*pow2(p.mu)*(-4*std::log(Mst1/
985  Mst2shift)*pow2(Mst1)*pow2(Mst2shift) + pow4(Mst1) - pow4(Mst2shift)))/(pow2(Mst1)*
986  pow2(Mst2shift)*pow3(pow2(Mst1) - pow2(Mst2shift)));
987 
988  isDegenerate = std::abs(exactShifted - lim) >= std::abs(exact - lim)
989  || !std::isfinite(exact) || !std::isfinite(exactShifted);
990  }
991 
992  Eigen::Matrix2d shift;
993 
994  // calculate matrix elements
995  if (isDegenerate) {
996  shift(0, 0) = (32*Xt2*(-3*(1 + lmMgl)*pow2(Mgl) + 5*(1 + lmMsq)*Msq2 + (1 +
997  lmMst1)*pow2(Mst1))*pow2(p.mu))/(3.*pow6(Mst1));
998  shift(1, 0) = (-32*p.mu*(-3*(1 + lmMgl)*pow2(Mgl) + 5*(1 + lmMsq)*Msq2 + (1 +
999  lmMst1)*pow2(Mst1))*(p.mu*Xt2 - 3*tb*Xt*pow2(Mst1) + tb*pow3(Xt)))/
1000  (3.*tb*pow6(Mst1));
1001  shift(0, 1) = shift(1, 0);
1002  shift(1, 1) = (32*(-3*(1 + lmMgl)*pow2(Mgl) + 5*(1 + lmMsq)*Msq2 + (1 + lmMst1)*
1003  pow2(Mst1))*(-6*tb*(p.mu*Xt + tb*Xt2)*pow2(Mst1) + Xt2*pow2(p.mu) +
1004  truncateXt*pow2(tb)*pow2(Xt2) + 2*p.mu*tb*pow3(Xt) + 6*pow2(tb)*
1005  pow4(Mst1)))/(3.*pow2(tb)*pow6(Mst1));
1006  } else {
1007  shift(0, 0) = (16*Xt2*(-6*(1 + lmMgl)*pow2(Mgl) + 10*(1 + lmMsq)*Msq2 + (1 +
1008  lmMst1)*pow2(Mst1) + (1 + lmMst2)*pow2(Mst2))*pow2(p.mu)*(-4*std::log(Mst1/
1009  Mst2)*pow2(Mst1)*pow2(Mst2) + pow4(Mst1) - pow4(Mst2)))/(pow2(Mst1)*
1010  pow2(Mst2)*pow3(pow2(Mst1) - pow2(Mst2)));
1011  shift(1, 0) = (16*p.mu*(-6*(1 + lmMgl)*pow2(Mgl) + 10*(1 + lmMsq)*Msq2 + (1 +
1012  lmMst1)*pow2(Mst1) + (1 + lmMst2)*pow2(Mst2))*(4*std::log(Mst1/Mst2)*pow2(
1013  Mst1)*pow2(Mst2)*(p.mu*Xt2 + tb*pow3(Xt)) + p.mu*Xt2*(-pow4(Mst1) +
1014  pow4(Mst2)) + tb*Xt*(pow3(pow2(Mst1) - pow2(Mst2)) + pow2(Xt)*(-
1015  pow4(Mst1) + pow4(Mst2)))))/(tb*pow2(Mst1)*pow2(Mst2)*pow3(pow2(
1016  Mst1) - pow2(Mst2)));
1017  shift(0, 1) = shift(1, 0);
1018  shift(1, 1) = (16*(-6*(1 + lmMgl)*pow2(Mgl) + 10*(1 + lmMsq)*Msq2 + (1 + lmMst1)*
1019  pow2(Mst1) + (1 + lmMst2)*pow2(Mst2))*(-4*std::log(Mst1/Mst2)*pow2(Mst1)*
1020  pow2(Mst2)*(Xt2*pow2(p.mu) + truncateXt*pow2(tb)*pow2(Xt2) + 2*p.mu*
1021  tb*pow3(Xt)) + Xt2*(-2*pow2(tb)*pow3(pow2(Mst1) - pow2(Mst2)) +
1022  pow2(p.mu)*(pow4(Mst1) - pow4(Mst2))) + tb*(-2*p.mu*Xt*pow3(pow2(Mst1) -
1023  pow2(Mst2)) + tb*(pow2(Mst1) + pow2(Mst2))*pow3(pow2(Mst1) - pow2(
1024  Mst2)) + 2*p.mu*pow3(Xt)*(pow4(Mst1) - pow4(Mst2))) + truncateXt*pow2(
1025  tb)*pow2(Xt2)*(pow4(Mst1) - pow4(Mst2))))/(pow2(Mst1)*pow2(Mst2)*
1026  pow2(tb)*pow3(pow2(Mst1) - pow2(Mst2)));
1027  }
1028 
1029  // pre-factor of shift -> checked normalization against H3m normalization and they coincide
1030  const double yt = sqrt2 * p.Mt / p.vu;
1031  const double prefac = threeLoop * pow2(pow2(p.g3) * p.Mt * yt);
1032 
1033  return prefac * shift;
1034 }
1035 
1036 /**
1037  * Shifts the H3m renormalization scheme to DR' scheme. This shift has to be added to the H3m result!
1038  * Note: This shift is WITHOUT the three-loop pre-factor g3^4*k^3*Mt^2*yt^2*Sin[beta]^2 with k = 1 / (16 Pi^2)
1039  * @param ho a HierarchyObject with constant isAlphab.
1040  * @return A double which shifts the H3m scheme to the DR' scheme at three-loop level
1041  *
1042  */
1044  const himalaya::HierarchyObject& ho, int omitLogs) const
1045 {
1046  const int suitableHierarchy = ho.getSuitableHierarchy();
1047 
1048  // truncate shift at O(Xt^2) to be consistent with H3m result
1049  const int truncateXt =
1050  (suitableHierarchy == himalaya::hierarchies::Hierarchies::h3
1051  || suitableHierarchy == himalaya::hierarchies::Hierarchies::h32q2g
1052  || suitableHierarchy == himalaya::hierarchies::Hierarchies::h3q22g
1053  || suitableHierarchy == himalaya::hierarchies::Hierarchies::h9
1054  || suitableHierarchy == himalaya::hierarchies::Hierarchies::h9q2)
1055  ? 0 : 1;
1056 
1057  // stop masses
1058  const double Mst1 = p.MSt(0);
1059  const double Mst2 = p.MSt(1);
1060 
1061  // Hierarchy h4 only covers O(Xt^0)
1062  const double Xt = suitableHierarchy == himalaya::hierarchies::Hierarchies::h4
1063  ? 0 : p.Au(2,2) - p.mu / calcTanBeta();
1064 
1065  // threshold for degenerate squark mass case is 1% of the stop mass
1066  const double eps = Mst1 * 0.01;
1067 
1068  // squared masses
1069  const double Mst12 = pow2(Mst1);
1070  const double Mgl = p.MG;
1071  const double Mgl2 = pow2(p.MG);
1072  const double Msq2 = pow2(calcMeanMsq());
1073  const double scale2 = pow2(p.scale);
1074  const double Xt2 = pow2(Xt);
1075  const double Mst22 = pow2(Mst2);
1076  const double Dmst12 = Mst12 - Mst22;
1077 
1078  // logarithms
1079  const double lmMst1 = omitLogs * std::log(scale2 / Mst12);
1080  const double lmMst2 = omitLogs * std::log(scale2 / Mst12) - std::log(Mst22 / Mst12);
1081  const double lmMsq = omitLogs * std::log(scale2 / Mst12) - std::log(Msq2 / Mst12);
1082  const double lmMgl = omitLogs * std::log(scale2 / Mst12) - std::log(Mgl2 / Mst12);
1083 
1084  // degenerate mass case flag
1085  bool isDegenerate = false;
1086 
1087  // check for degenerate squark masses
1088  if (std::abs(Mst1 - Mst2) < eps) {
1089  const double Mst2shift = Mst1 + 0.5*std::sqrt(std::abs(Dmst12));
1090  const double lmMst2shift = std::log(scale2 / pow2(Mst2shift));
1091  // limit
1092  const double lim = (32*(-3*(1 + lmMgl)*pow2(Mgl) + 5*(1 + lmMsq)*Msq2 + (1 + lmMst1)*
1093  pow2(Mst1))*(-6*Xt2*pow2(Mst1) + truncateXt*pow2(Xt2) + 6*pow4(Mst1)))/
1094  (3.*pow6(Mst1));
1095  // exact result
1096  const double exact = (16*(-6*(1 + lmMgl)*pow2(Mgl) + 10*(1 + lmMsq)*Msq2 + (1 + lmMst1)*
1097  pow2(Mst1) + (1 + lmMst2)*pow2(Mst2))*(4*truncateXt*std::log(Mst2/Mst1)*
1098  pow2(Mst1)*pow2(Mst2)*pow2(Xt2) - 2*Xt2*pow3(pow2(Mst1) - pow2(Mst2)) +
1099  (pow2(Mst1) + pow2(Mst2))*pow3(pow2(Mst1) - pow2(Mst2)) + truncateXt*
1100  pow2(Xt2)*(pow4(Mst1) - pow4(Mst2))))/(pow2(Mst1)*pow2(Mst2)*pow3(pow2(
1101  Mst1) - pow2(Mst2)));
1102  // exact result with shifted stop_2 mass
1103  const double exactShifted = (16*(-6*(1 + lmMgl)*pow2(Mgl) + 10*(1 + lmMsq)*Msq2 + (1 + lmMst1)*
1104  pow2(Mst1) + (1 + lmMst2shift)*pow2(Mst2shift))*(4*truncateXt*std::log(Mst2shift/Mst1)*
1105  pow2(Mst1)*pow2(Mst2shift)*pow2(Xt2) - 2*Xt2*pow3(pow2(Mst1) - pow2(Mst2shift)) +
1106  (pow2(Mst1) + pow2(Mst2shift))*pow3(pow2(Mst1) - pow2(Mst2shift)) + truncateXt*
1107  pow2(Xt2)*(pow4(Mst1) - pow4(Mst2shift))))/(pow2(Mst1)*pow2(Mst2shift)*pow3(pow2(
1108  Mst1) - pow2(Mst2shift)));
1109 
1110  isDegenerate = std::abs(exactShifted - lim) >= std::abs(exact - lim)
1111  || !std::isfinite(exact) || !std::isfinite(exactShifted);
1112  }
1113 
1114  double shift = 0.;
1115 
1116  if (isDegenerate) {
1117  shift = (32*(-3*(1 + lmMgl)*pow2(Mgl) + 5*(1 + lmMsq)*Msq2 + (1 + lmMst1)*
1118  pow2(Mst1))*(-6*Xt2*pow2(Mst1) + truncateXt*pow2(Xt2) + 6*pow4(Mst1)))/
1119  (3.*pow6(Mst1));
1120  } else {
1121  shift = (16*(-6*(1 + lmMgl)*pow2(Mgl) + 10*(1 + lmMsq)*Msq2 + (1 + lmMst1)*
1122  pow2(Mst1) + (1 + lmMst2)*pow2(Mst2))*(4*truncateXt*std::log(Mst2/Mst1)*
1123  pow2(Mst1)*pow2(Mst2)*pow2(Xt2) - 2*Xt2*pow3(pow2(Mst1) - pow2(Mst2)) +
1124  (pow2(Mst1) + pow2(Mst2))*pow3(pow2(Mst1) - pow2(Mst2)) + truncateXt*
1125  pow2(Xt2)*(pow4(Mst1) - pow4(Mst2))))/(pow2(Mst1)*pow2(Mst2)*pow3(pow2(
1126  Mst1) - pow2(Mst2)));
1127  }
1128 
1129  return shift;
1130 }
1131 
1132 
1133 /**
1134  * Calculates the loop corrected Higgs mass matrix at the order O(alpha_x). Here, x can be t or b.
1135  * @param ho a HierarchyObject with constant isAlphab.
1136  * @param shiftOneLoop An integer flag which is 0 or 1 in order to shift the one-loop terms to the MDR scheme.
1137  * @param shiftTwoLoop An integer flag which is 0 or 1 in order to shift the two-loop terms to the MDR scheme.
1138  * @return The loop corrected Higgs mass matrix at the order O(alpha_x).
1139  */
1142  unsigned shiftOneLoop,
1143  unsigned shiftTwoLoop) const
1144 {
1145  using std::log;
1146 
1147  Eigen::Matrix2d Mt41L;
1148  const double beta = calcBeta();
1149  const double Mst1 = shiftMst1ToMDR(ho, shiftOneLoop, shiftTwoLoop);
1150  const double Mst2 = shiftMst2ToMDR(ho, shiftOneLoop, shiftTwoLoop);
1151  const double sbeta = calcSinBeta();
1152  const double cbeta = calcCosBeta();
1153  const double Mt = ho.getIsAlphab() ? p.Mb : p.Mt;
1154  const double s2t = ho.getIsAlphab() ? p.s2b : p.s2t;
1155 
1156  Mt41L(0, 0) = (-pow2(Mt) * pow2(p.mu) *
1157  (-pow2(Mst1) + pow2(Mst2) + pow2(Mst1) * log(Mst1) +
1158  pow2(Mst2) * log(Mst1) - pow2(Mst1) * log(Mst2) -
1159  pow2(Mst2) * log(Mst2)) * pow2(s2t)) /
1160  (4. * (pow2(Mst1) - pow2(Mst2)));
1161 
1162  Mt41L(0, 1) =
1163  (-(pow3(Mt) * p.mu * (log(Mst1) - log(Mst2)) * s2t) / 2. +
1164  (pow2(Mt) * pow2(p.mu) * 1 / tan(beta) *
1165  (-pow2(Mst1) + pow2(Mst2) + pow2(Mst1) * log(Mst1) +
1166  pow2(Mst2) * log(Mst1) - pow2(Mst1) * log(Mst2) -
1167  pow2(Mst2) * log(Mst2)) * pow2(s2t)) /
1168  (4. * (pow2(Mst1) - pow2(Mst2))) +
1169  (Mt * p.mu * (-pow2(Mst1) + pow2(Mst2) + pow2(Mst1) * log(Mst1) +
1170  pow2(Mst2) * log(Mst1) - pow2(Mst1) * log(Mst2) -
1171  pow2(Mst2) * log(Mst2)) * pow3(s2t)) / 8.);
1172 
1173  Mt41L (1,0) = Mt41L(0,1);
1174 
1175  Mt41L(1, 1) =
1176  (pow4(Mt) * (log(Mst1) + log(Mst2) - 2 * log(Mt)) +
1177  pow3(Mt) * p.mu * 1 / tan(beta) * (log(Mst1) - log(Mst2)) * s2t +
1178  (pow2(Mt) * pow2(1 / sbeta) *
1179  (pow2(Mst1) * pow2(p.mu) * pow2(cbeta) -
1180  pow2(Mst2) * pow2(p.mu) * pow2(cbeta) -
1181  pow2(Mst1) * pow2(p.mu) * pow2(cbeta) * log(Mst1) -
1182  pow2(Mst2) * pow2(p.mu) * pow2(cbeta) * log(Mst1) +
1183  pow2(Mst1) * pow2(p.mu) * pow2(cbeta) * log(Mst2) +
1184  pow2(Mst2) * pow2(p.mu) * pow2(cbeta) * log(Mst2) +
1185  2 * pow4(Mst1) * log(Mst1) * pow2(sbeta) -
1186  4 * pow2(Mst1) * pow2(Mst2) * log(Mst1) * pow2(sbeta) +
1187  2 * pow4(Mst2) * log(Mst1) * pow2(sbeta) -
1188  2 * pow4(Mst1) * log(Mst2) * pow2(sbeta) +
1189  4 * pow2(Mst1) * pow2(Mst2) * log(Mst2) * pow2(sbeta) -
1190  2 * pow4(Mst2) * log(Mst2) * pow2(sbeta)) * pow2(s2t)) /
1191  (4. * (pow2(Mst1) - pow2(Mst2))) -
1192  (Mt * p.mu * 1 / tan(beta) * (-pow2(Mst1) + pow2(Mst2) +
1193  pow2(Mst1) * log(Mst1) + pow2(Mst2) * log(Mst1) -
1194  pow2(Mst1) * log(Mst2) - pow2(Mst2) * log(Mst2)) *
1195  pow3(s2t)) / 4. -
1196  ((pow2(Mst1) - pow2(Mst2)) *
1197  (-pow2(Mst1) + pow2(Mst2) + pow2(Mst1) * log(Mst1) +
1198  pow2(Mst2) * log(Mst1) - pow2(Mst1) * log(Mst2) -
1199  pow2(Mst2) * log(Mst2)) * pow4(s2t)) / 16.);
1200 
1201  return calcHiggsMassMatrixPrefactor() * Mt41L;
1202 }
1203 
1204 /**
1205  * Calculates the loop corrected Higgs mass matrix at the order O(alpha_x*alpha_s). Here, x can be t or b.
1206  * @param ho a HierarchyObject with constant isAlphab.
1207  * @param shiftOneLoop An integer flag which is 0 or 1 in order to shift the one-loop terms to the MDR scheme.
1208  * @param shiftTwoLoop An integer flag which is 0 or 1 in order to shift the two-loop terms to the MDR scheme.
1209  * @return The loop corrected Higgs mass matrix at the order O(alpha_x*alpha_s).
1210  */
1211 Eigen::Matrix2d
1213  unsigned shiftOneLoop,
1214  unsigned shiftTwoLoop) const
1215 {
1216  const double Mt2 = ho.getIsAlphab() ? pow2(p.Mb) : pow2(p.Mt);
1217  const double theta = ho.getIsAlphab() ? p.theta_b : p.theta_t;
1218  const double st = std::sin(theta);
1219  const double ct = std::cos(theta);
1220  const double Mst12 = pow2(shiftMst1ToMDR(ho, shiftOneLoop, shiftTwoLoop));
1221  const double Mst22 = pow2(shiftMst2ToMDR(ho, shiftOneLoop, shiftTwoLoop));
1222  const double MG = p.MG;
1223  const double scale2 = pow2(p.scale);
1224  const double mu = - p.mu; // note the sign difference in mu
1225  const double tanb = calcTanBeta();
1226  const double v2 = calcV2();
1227  const double g3 = p.g3;
1228  const int include_heavy_higgs = 0;
1229 
1230  Eigen::Matrix2d Mt42L = mh2l::delta_mh2_2loop_at_as(
1231  Mt2, MG, Mst12, Mst22, st, ct, scale2, mu, tanb, v2, g3,
1232  include_heavy_higgs);
1233 
1234  return Mt42L;
1235 }
1236 
1237 /**
1238  * Calculates the contribution to the order (alpha_x) and (alpha_s alpha_x) as the difference
1239  * of the Higgs mass matrices of the MDR and DR scheme. Here, x can be t or b.
1240  * @param ho a HierarchyObject with constant isAlphab.
1241  * @param shiftOneLoop a bool to shift the terms at one-loop level.
1242  * @param shiftTwoLoop a bool to shift the terms at two-loop level.
1243  * @return The loop corrected Higgs mass matrix difference of the MDR and DR scheme at the given order.
1244  */
1245 Eigen::Matrix2d
1247  bool shiftOneLoop,
1248  bool shiftTwoLoop) const
1249 {
1250  Eigen::Matrix2d shift{Eigen::Matrix2d::Zero()};
1251 
1252  if (shiftOneLoop) {
1253  shift += getMt41L(ho, 1, 1) - getMt41L(ho, 0, 0);
1254  }
1255 
1256  if (shiftTwoLoop) {
1257  shift += getMt42L(ho, 1, 1) - getMt42L(ho, 0, 0);
1258  }
1259 
1260  return shift;
1261 }
1262 
1263 
1265 {
1266  return p.vu / calcV();
1267 }
1268 
1269 
1271 {
1272  return p.vd / calcV();
1273 }
1274 
1275 
1277 {
1278  return p.vu / p.vd;
1279 }
1280 
1281 
1283 {
1284  return std::atan(calcTanBeta());
1285 }
1286 
1287 
1289 {
1290  return std::sqrt(calcV2());
1291 }
1292 
1293 
1295 {
1296  return pow2(p.vu) + pow2(p.vd);
1297 }
1298 
1299 
1300 /**
1301  * Prefactor of self-energy from Section 3 from [1005.5709].
1302  *
1303  * GF = 1/(Sqrt[2] (vu^2 + vd^2)) is defined in the DR'-bar scheme.
1304  * Sin[beta]^2 = vu^2 / (vu^2 + vd^2)
1305  *
1306  * @return 3 Sqrt[2] GF / (2 Pi^2 Sin[beta]^2)
1307  */
1309 {
1310  return 3. / (2 * pow2(Pi * p.vu));
1311 }
1312 
1313 
1315 {
1316  return oneLoop * pow2(p.g3);
1317 }
1318 
1319 
1321 {
1322  return std::sqrt(std::abs(p.calculateMsq2()));
1323 }
1324 
1325 
1326 /**
1327  * Fills in delta_lambda @ 3L to the given HierarchyObject
1328  * @param ho a HierrachyObject
1329  */
1331 {
1332  // set Xt order truncation for EFT contribution to be consistent with H3m
1333  const int suitableHierarchy = ho.getSuitableHierarchy();
1334  const int xtOrder =
1335  (suitableHierarchy == himalaya::hierarchies::Hierarchies::h3
1336  || suitableHierarchy == himalaya::hierarchies::Hierarchies::h32q2g
1337  || suitableHierarchy == himalaya::hierarchies::Hierarchies::h3q22g
1338  || suitableHierarchy == himalaya::hierarchies::Hierarchies::h9
1339  || suitableHierarchy == himalaya::hierarchies::Hierarchies::h9q2) ? 3 : 4;
1340 
1341  // to obtain delta_lambda one has to divide the difference of the two calculations by v^2
1342  const double v2 = calcV2();
1343  const double gt2 = 2 * pow2(p.Mt) / v2;
1344  const double pref = threeLoop * gt2 * pow2(p.Mt * pow2(p.g3));
1345 
1346  // create a modified parameters struct and construct
1347  // Mh2EFTCalculator and ThresholdCalculator
1348  auto p_mass_ES = p;
1349  p_mass_ES.mu2(2,2) = pow2(p.MSt(0));
1350  p_mass_ES.mq2(2,2) = pow2(p.MSt(1));
1351  himalaya::mh2_eft::Mh2EFTCalculator mh2EFTCalculator(p_mass_ES);
1353  disable_non_as_terms(mh2EFTCalculator); // omit all but O(at*as^n)
1354 
1355  // calculate the (non-)logarithmic part of Mh2 without delta_lambda_3L
1356  //
1357  // The first line is equivalent to 64 * dytas - 84 * pow2(dytas) -
1358  // 24 * dytas2 + catas2 including all log(mu^2/Mst1^2) which are
1359  // also included in the H3m result, and the second line omits these
1360  // log(mu^2/Mst1^2) terms since they originate from SM
1361  // contributions. The non-logarithmic part contains only Xt orders
1362  // up to O(Xt^2) which are also included in H3m so no subtraction
1363  // is needed. Checked.
1364  const double subtractionTermH3m = mh2EFTCalculator.getDeltaMh2EFT3Loop(0,1,0);
1365  const double subtractionTermEFT = mh2EFTCalculator.getDeltaMh2EFT3Loop(0,0,0);
1366 
1367  if (omitXtOrders) tc.setXtOrderOfDeltaLambdaAtAs2(xtOrder);
1368 
1369  // calculate the EFT logs. In the first call we calculate the full reconstructed contribution to delta_lambda_3L
1370  // including all logarithmic contributions. In the second line we subtract all non-logarithmic contributions
1371  // to isolate the logarithmic ones. Checked.
1372  const double eftLogs = pref*(
1377 
1378  // calculate the non-logarithmic part of delta_lambda @ 3L
1379  const double deltaLambda3LNonLog = pref*(ho.getDLambdaNonLog()
1380  + shiftH3mToDRbarPrimeMh2(ho,0)) - subtractionTermEFT;
1381 
1382  // calculate delta_lambda_H3m
1383  ho.setDLambdaH3m((pref*(ho.getDLambdaH3m()
1384  + shiftH3mToDRbarPrimeMh2(ho,1)) - subtractionTermH3m)/v2);
1385 
1386  // caluclate delta_lambda_EFT
1387  ho.setDLambdaEFT((deltaLambda3LNonLog + eftLogs)/v2);
1388 
1389  // save the non-logarithmic part of delta_lambda @ 3L
1390  ho.setDLambdaNonLog(deltaLambda3LNonLog/v2);
1391 
1392  // calculate DR' -> MS shift for delta_lambda 3L
1393  // this shift generates Xt^5*Log(mu) terms for the EFT expression
1394  ho.setDLambdaDRbarPrimeToMSbarShift(3, pref*tc.getDRbarPrimeToMSbarShift(xtOrder,1,0)/v2);
1395  // If orders of Xt are omitted, we subtract them from delta_lambda_EFT to be at the same order
1396  // as delta_lambda_H3m. This ensures that in the hierarchy selection process we don't compare
1397  // wrong orders of Xt.
1398  if (omitXtOrders) {
1399  ho.setDLambdaEFT(ho.getDLambdaEFT() + pref*(tc.getDRbarPrimeToMSbarShift(xtOrder,1,0)
1400  - tc.getDRbarPrimeToMSbarShift(xtOrder,1,1))/v2);
1401  }
1402 
1403  // set the uncertainty of delta_lambda due to missing Xt terms
1404  // to summarize: delta_lambda_H3m is always of the x_t order of the suitable
1405  // hierachy (h3, h9 ~ xt^3, h5, h6, h6b ~ xt^4), whereas delta_lambda_EFT
1406  // the non-logarithmic term is of order of the hierarchy but the logarithmic
1407  // part is of order O(xt^4) and using the shift O(xt^5). Note that the shift
1408  // for delta_lambda_H3m is always of order of the hierarchy as well.
1409  // the logarithms are omitted since one would double count the error when
1410  // combining it with delta_exp
1411  const int xt4Flag = xtOrder == 3 ? 1 : 0;
1413  std::abs(xt4Flag*pref/v2*tc.getDRbarPrimeToMSbarXtTerms(tc.getLimit(), 4, 1)));
1414 }
1415 
1416 
1417 /**
1418  * Estimates the uncertainty of the expansion at a given order.
1419  * @param ho a HierarchyObject with constant isAlphab.
1420  * @param massMatrix the CP-even Higgs mass matrix without the corrections whose uncertainty should be estimated.
1421  * @param oneLoopFlag an integer flag which is 0 or 1 in order to estimate the uncertainty of the one-loop expansion terms.
1422  * @param twoLoopFlag an integer flag which is 0 or 1 in order to estimate the uncertainty of the two-loop expansion terms.
1423  * @param threeLoopFlag an integer flag which is 0 or 1 in order to estimte the uncertainty of the three-loop expansion terms.
1424  * @return A double which is the estimated uncertainty.
1425  */
1427  const himalaya::HierarchyObject& ho, const Eigen::Matrix2d& massMatrix,
1428  int oneLoopFlag, int twoLoopFlag, int threeLoopFlag)
1429 {
1430  using namespace himalaya::hierarchies;
1431 
1432  // local copy of ho to work on; can be removed when
1433  // calculateHierarchy() takes a const& HierarchyObject
1434  auto ho_tmp = ho;
1435 
1436  // re-computes the Higgs mass eigenvalues
1437  const auto recomputeMh = [&]() {
1438  return calcSmallestEigenvalue(
1439  massMatrix +
1440  calculateHierarchy(ho_tmp, oneLoopFlag, twoLoopFlag, threeLoopFlag));
1441  };
1442 
1443  // re-computes the Higgs mass eigenvalues with a flag temporarily set to 0
1444  const auto recomputeMhWithLowerExpansion =
1445  [&](ExpansionDepth::ExpansionDepth flag) {
1446  // temporarily lower the expansion
1447  Temporarily_set<int> setFlag(expansionDepth.at(flag), 0);
1448  return recomputeMh();
1449  };
1450 
1451  // temporarily set expansion flags
1454 
1455  const double Mh = recomputeMh();
1456  double uncertainty{};
1457 
1458  // truncate the expansions at all variables with one order lower
1459  // than the maximum expansion depth and add to the expansion
1460  // uncertainty
1461 
1462  switch (getMotherHierarchy(ho.getSuitableHierarchy())) {
1463  case Hierarchies::h3:
1464  uncertainty += pow2(Mh - recomputeMhWithLowerExpansion(ExpansionDepth::Dmglst1));
1465  uncertainty += pow2(Mh - recomputeMhWithLowerExpansion(ExpansionDepth::Dmsqst1));
1466  uncertainty += pow2(Mh - recomputeMhWithLowerExpansion(ExpansionDepth::Dmst12));
1467  break;
1468  case Hierarchies::h4:
1469  uncertainty += pow2(Mh - recomputeMhWithLowerExpansion(ExpansionDepth::At));
1470  uncertainty += pow2(Mh - recomputeMhWithLowerExpansion(ExpansionDepth::lmMsusy));
1471  uncertainty += pow2(Mh - recomputeMhWithLowerExpansion(ExpansionDepth::Msq));
1472  uncertainty += pow2(Mh - recomputeMhWithLowerExpansion(ExpansionDepth::Msusy));
1473  break;
1474  case Hierarchies::h5:
1475  uncertainty += pow2(Mh - recomputeMhWithLowerExpansion(ExpansionDepth::Dmglst1));
1476  uncertainty += pow2(Mh - recomputeMhWithLowerExpansion(ExpansionDepth::Msq));
1477  break;
1478  case Hierarchies::h6:
1479  uncertainty += pow2(Mh - recomputeMhWithLowerExpansion(ExpansionDepth::Dmglst2));
1480  uncertainty += pow2(Mh - recomputeMhWithLowerExpansion(ExpansionDepth::Msq));
1481  break;
1482  case Hierarchies::h6b:
1483  uncertainty += pow2(Mh - recomputeMhWithLowerExpansion(ExpansionDepth::Dmglst2));
1484  uncertainty += pow2(Mh - recomputeMhWithLowerExpansion(ExpansionDepth::Dmsqst2));
1485  break;
1486  case Hierarchies::h9:
1487  uncertainty += pow2(Mh - recomputeMhWithLowerExpansion(ExpansionDepth::Dmsqst1));
1488  uncertainty += pow2(Mh - recomputeMhWithLowerExpansion(ExpansionDepth::Dmst12));
1489  uncertainty += pow2(Mh - recomputeMhWithLowerExpansion(ExpansionDepth::Mgl));
1490  break;
1491  }
1492 
1493  return std::sqrt(uncertainty);
1494 }
1495 
1496 } // namespace himalaya
Contains the definition of the MSSM_mass_eigenstates class.
double shiftH3mToDRbarPrimeMh2(const himalaya::HierarchyObject &ho, int omitLogs) const
truncate the expansion depth in At/Ab by one order
void setSuitableHierarchy(int hierarchy)
int compareHierarchies(HierarchyObject &ho)
double calcBeta() const
calculate beta from tan(beta)
truncate the expansion depth in the difference of the stop/sbottom 1 mass and the average squark mass...
double vu
VEV of up Higgs, with v = Sqrt[vu^2 + vd^2] ~ 246 GeV.
void setDLambdaEFT(double deltaLambda)
void setCorrectionFlag(CouplingOrders::CouplingOrders order, int flag)
Definition of threshold corrections class to express the Higgs mass calculation in terms of SM MS-bar...
double getDeltaMh2EFT3Loop(int omitSMLogs, int omitMSSMLogs, int omitDeltaLambda3L=1) const
#define Himalaya_VERSION_MINOR
Definition: version.hpp:11
Eigen::Matrix2d calcDRbarToMDRbarShift(const HierarchyObject &ho, bool shiftOneLoop, bool shiftTwoLoop) const
double getThresholdCorrection(ThresholdCouplingOrders couplingOrder, RenSchemes scheme, int omitLogs) const
Definition: H3.cpp:14
double calcAsOver4Pi() const
calculate prefactor as/(4 Pi)
RM33 Ad
trilinear down type squark-Higgs coupling matrix
std::array< double, 2 > calcMsfMDRFlag(const HierarchyObject &ho, int loopOrder) const
calculate sfermion masses shifted to MDR
void validate(bool verbose)
validates the parameter set
Eigen::Matrix2d shiftH3mToDRbarPrime(const HierarchyObject &ho) const
double vd
VEV of down Higgs, with v = Sqrt[vu^2 + vd^2] ~ 246 GeV.
void setDMh(int loops, const Eigen::Matrix2d &dMh)
truncate the expansion depth in the difference of the stop/sbottom masses by one order ...
bool isHierarchySuitable(const HierarchyObject &ho) const
void setMDRMasses(const Eigen::Vector2d &mdrMasses)
truncate the expansion depth in the stop/sbottom masses by one order
truncate the expansion depth in log(Msusy) by one order
void setMDRFlag(int mdrFlag)
double calcSinBeta() const
calculate sin(beta)
truncate the expansion depth in the average SUSY mass by one order
truncate the expansion depth in the gluino mass by one order
truncate the expansion depth in the average squark mass by one order
#define Himalaya_VERSION_MAJOR
Definition: version.hpp:10
double theta_t
stop mixing angle
Eigen::Matrix2d getMt42L(const HierarchyObject &ho, unsigned shiftOneLoop, unsigned shiftTwoLoop) const
Eigen::Matrix< double, 2, 2 > delta_mh2_2loop_at_as(double mt2, double mg, double mst12, double mst22, double sxt, double cxt, double scale2, double mu, double tanb, double vev2, double g3, int include_heavy_higgs)
2-loop CP-even Higgs contribution O(at*as)
Definition: DSZHiggs.cpp:269
Implementation of logging macros.
double s2b
sine of 2 times the sbottom mixing angle
enum definitions
#define Himalaya_VERSION_RELEASE
Definition: version.hpp:12
double getExpansionUncertainty(const himalaya::HierarchyObject &ho, const Eigen::Matrix2d &massMatrix, int oneLoopFlag, int twoLoopFlag, int threeLoopFlag)
void setDLambda(int loops, double deltaLambda)
double s2t
sine of 2 times the stop mixing angle
HierarchyObject calculateDMh3L(bool isAlphab)
double mu
mu parameter, convention of [Phys.Rept. 117 (1985) 75-263]
double calcCosBeta() const
calculate cos(beta)
double calculateMsq2() const
calculates average light squark mass squared
RM33 mu2
soft-breaking squared right-handed up-squark mass parameters
void setDLambdaH3m(double deltaLambda)
double getDRbarPrimeToMSbarShift(int xtOrder, int omitLogs, int omitXtLogs=1) const
Contains routines to diagonalize mass matrices.
void calcDeltaLambda3L(HierarchyObject &ho, bool omitXtOrders) const
void setDMhDRbarPrimeToH3mShift(const Eigen::Matrix2d &shift)
double theta_b
sbottom mixing angle
double scale
renormalization scale
truncate the expansion depth in the difference of the average squark mass and the stop/sbottom 2 mass...
void setDMh2EFT(int loops, double deltaMh2)
This class performs a fixed-order calculation of the light CP-even Higgs mass up to 2-loop order...
void setDMh2(int loops, double dMh2)
void setDMhExpUncertainty(int loops, double uncertainty)
Definition of the HierarchyObject, which contains all the calculational results.
double MA
CP-odd Higgs.
truncate the two loop expansion at the three loop expansion depth
double getDeltaMh2EFT2Loop(int omitSMLogs, int omitMSSMLogs) const
truncate the expansion depth in the difference of stop/sbottom 1 mass and the gluino mass by one orde...
double calcHiggsMassMatrixPrefactor() const
calculate prefactor of the Higgs mass matrix
double calcTanBeta() const
calculate tan(beta)
double g3
gauge coupling g3 SU(3)
double calcV() const
calculate v = sqrt(vu^2 + vd^2)
void setDLambdaDRbarPrimeToMSbarShift(int loops, double shift)
function declarations for 2-loop MSSM Higgs contributions
Definition of EFT Higgs mass calculation class.
double calcV2() const
calculate v^2 = vu^2 + vd^2
static bool isInfoPrinted
if true, no info will be printed
Complex< T > log(const Complex< T > &z_) noexcept
Definition: complex.hpp:45
void setDLambdaXtUncertainty(double uncertainty)
Eigen::Matrix2d getDMh(int loops) const
std::tuple< V2, V2, V2, V2 > fs_diagonalize_hermitian_perturbatively(const RM22 &m0, const RM22 &m1, const RM22 &m2, const RM22 &m3)
Definition: Linalg.cpp:46
HierarchyCalculator(const Parameters &p_, bool verbose_=true)
double shiftMst1ToMDR(const HierarchyObject &ho, unsigned oneLoopFlag, unsigned twoLoopFlag) const
void setRelDiff2L(double relDiff2L)
void setDMh2FO(int loops, double deltaMh2)
void setAbsDiff2L(double absDiff2L)
void setDMh2FOAt(int loops, double deltaMh2)
double shiftMst2ToMDR(const HierarchyObject &ho, unsigned oneLoopFlag, unsigned twoLoopFlag) const
void setDLambdaNonLog(double deltaLambda)
void setDMhDRbarPrimeToMDRbarPrimeShift(const Eigen::Matrix2d &mdrShift)
std::array< int, 12 > expansionDepth
hierarchy expansion depth
double getDLambda(int loops) const
#define INFO_MSG(message)
Definition: Logger.hpp:65
Definition of the HierarchyCalculator.
double getDRbarPrimeToMSbarXtTerms(Limits limit, int xtOrder, int omitLogs) const
double getDeltaMh2EFT1Loop(int omitSMLogs, int omitMSSMLogs) const
Parameters p
Himalaya input parameters.
Eigen::Matrix2d calculateHierarchy(himalaya::HierarchyObject &ho, int oneLoopFlagIn, int twoLoopFlagIn, int threeLoopFlagIn) const
truncate the expansion depth in the difference of the stop/sbottom 2 mass and the gluino mass by one ...
std::tuple< double, double, double > calculate_Mh2() const
calculates squared Higgs masses
RM33 Au
trilinear up type squark-Higgs coupling matrix
bool verbose
enable/disable verbose output
double calcMeanMsq() const
mean (non-squared) light squark mass
Eigen::Matrix2d getMt41L(const HierarchyObject &ho, unsigned shiftOneLoop, unsigned shiftTwoLoop) const