flavio.physics.running.running module
Functions to solve the renormalization group equations (RGEs) numerically.
"""Functions to solve the renormalization group equations (RGEs) numerically.""" from flavio.physics.running import betafunctions from flavio.physics.running import masses from scipy.integrate import odeint import numpy as np from functools import lru_cache from flavio.config import config import copy from math import log, pi from wilson.util import qcd import rundec # quark mass thresholds def _thresholds(): thresholds = { 3: 0.1, 4: config['RGE thresholds']['mc'], 5: config['RGE thresholds']['mb'], 6: config['RGE thresholds']['mt'], 7: np.inf, } return thresholds def rg_evolve(initial_condition, derivative, scale_in, scale_out): sol = odeint(derivative, initial_condition, [scale_in, scale_out]) return sol[1] def rg_evolve_sm(initial_condition, derivative_nf, scale_in, scale_out, nf_out=None): if scale_in == scale_out: # no need to run! # However, return a copy to prevent accidentally changing the initial condition return copy.deepcopy(initial_condition) if scale_out < 0.1: raise ValueError('RG evolution below the strange threshold not implemented.') return _rg_evolve_sm(tuple(initial_condition), derivative_nf, scale_in, scale_out, nf_out) @lru_cache(maxsize=config['settings']['cache size']) def _rg_evolve_sm(initial_condition, derivative_nf, scale_in, scale_out, nf_out): thresholds = _thresholds() if scale_in > scale_out: # running DOWN # set initial values and scales initial_nf = initial_condition scale_in_nf = scale_in for nf in (6,5,4,3): if scale_in <= thresholds[nf]: continue if nf_out is not None and nf == nf_out: scale_stop = scale_out else: # run either to next threshold or to final scale, whichever is closer scale_stop = max(thresholds[nf], scale_out) sol = rg_evolve(initial_nf, derivative_nf(nf), scale_in_nf, scale_stop) if scale_stop == scale_out: return sol initial_nf = sol scale_in_nf = thresholds[nf] elif scale_in < scale_out: # running UP # set initial values and scales initial_nf = initial_condition scale_in_nf = scale_in for nf in (3,4,5,6): if nf < 6 and scale_in >= thresholds[nf+1]: continue # run either to next threshold or to final scale, whichever is closer scale_stop = min(thresholds[nf+1], scale_out) sol = rg_evolve(initial_nf, derivative_nf(nf), scale_in_nf, scale_stop) if scale_stop == scale_out: return sol initial_nf = sol scale_in_nf = thresholds[nf+1] return sol @lru_cache(maxsize=config['settings']['cache size']) def run_alpha_e(alpha_e_in, scale_in, scale_out, n_u, n_d, n_e): """Get the electromagnetic fine structure constant at the scale `scale_out`, given its value at the scale `scale_in` and running with `n_u` dynamical up quark flavours, `n_d` dynamical down quark flavours, and `n_e` dynamical charged lepton flavours.""" if scale_out == scale_in: # nothing to do return alpha_e_in beta0 = -4/3 * (4 * n_u / 3 + n_d / 3 + n_e) # -4/3 * sum Q_f^2 N_f return alpha_e_in / (1 + alpha_e_in * beta0 * log(scale_out/scale_in) / (2 * pi)) def get_nf(scale): """Guess the number of quark flavours based on the scale, if not specified manually.""" mt = config['RGE thresholds']['mt'] mb = config['RGE thresholds']['mb'] mc = config['RGE thresholds']['mc'] if scale >= mt: return 6 elif mb <= scale < mt: return 5 elif mc <= scale < mb: return 4 elif scale < mc: return 3 else: raise ValueError("Unexpected value: scale={}".format(scale)) def get_alpha_e(par, scale, nf_out=None): r"""Get the running $\overline{\mathrm{MS}}$ fine-structure constant $\alpha_e$ at the specified scale.""" nf = nf_out or get_nf(scale) aeMZ = par['alpha_e'] MZ = 91.1876 # m_Z treated as a constant here mt = config['RGE thresholds']['mt'] mb = config['RGE thresholds']['mb'] mc = config['RGE thresholds']['mc'] if nf == 5: return run_alpha_e(aeMZ, MZ, scale, n_u=2, n_d=3, n_e=3) elif nf == 6: aemt = run_alpha_e(aeMZ, MZ, mt, n_u=2, n_d=3, n_e=3) return run_alpha_e(aemt, mt, scale, n_u=3, n_d=3, n_e=3) elif nf == 4: aemb = run_alpha_e(aeMZ, MZ, mb, n_u=2, n_d=3, n_e=3) return run_alpha_e(aemb, mb, scale, n_u=2, n_d=2, n_e=3) elif nf == 3: aemb = run_alpha_e(aeMZ, MZ, mb, n_u=2, n_d=3, n_e=3) aemc = run_alpha_e(aemb, mb, mc, n_u=2, n_d=2, n_e=3) return run_alpha_e(aemc, mc, scale, n_u=1, n_d=2, n_e=2) else: raise ValueError("Invalid value: nf_out={}".format(nf_out)) def get_alpha_s(par, scale, nf_out=None): r"""Get the running $\overline{\mathrm{MS}}$ QCD coupling constant $\alpha_s$ at the specified scale.""" nf = nf_out or get_nf(scale) return qcd.alpha_s(scale=scale, f=nf, alphasMZ=par['alpha_s']) def get_alpha(par, scale, nf_out=None): r"""Get the running $\overline{\mathrm{MS}}$ $\alpha_s$ and $\alpha_e$ at the specified scale. """ return {'alpha_e' : get_alpha_e(par, scale, nf_out=nf_out), 'alpha_s' : get_alpha_s(par, scale, nf_out=nf_out)} def get_mb(par, scale, nf_out=None): r"""Get the running $b$ quark mass at the specified scale.""" nf = nf_out or get_nf(scale) return qcd.m_b(mbmb=par['m_b'], scale=scale, f=nf, alphasMZ=par['alpha_s']) def get_mc(par, scale, nf_out=None): r"""Get the running $c$ quark mass at the specified scale.""" nf = nf_out or get_nf(scale) return qcd.m_c(mcmc=par['m_c'], scale=scale, f=nf, alphasMZ=par['alpha_s']) def get_mu(par, scale, nf_out=None): r"""Get the running $u$ quark mass at the specified scale.""" nf = nf_out or get_nf(scale) return qcd.m_s(ms2=par['m_u'], scale=scale, f=nf, alphasMZ=par['alpha_s']) def get_md(par, scale, nf_out=None): r"""Get the running $d$ quark mass at the specified scale.""" nf = nf_out or get_nf(scale) return qcd.m_s(ms2=par['m_d'], scale=scale, f=nf, alphasMZ=par['alpha_s']) def get_ms(par, scale, nf_out=None): r"""Get the running $s$ quark mass at the specified scale.""" nf = nf_out or get_nf(scale) return qcd.m_s(ms2=par['m_s'], scale=scale, f=nf, alphasMZ=par['alpha_s']) def get_mq(q, par, scale, nf_out=None): fdict = {'u': get_mu, 'c': get_mc, 'd': get_md, 's': get_ms, 'b': get_mb} return fdict[q](par, scale, nf_out=nf_out) def get_mc_pole(par, nl=2): # for mc, default to 2-loop conversion only due to renormalon ambiguity! r"""Get the $c$ quark pole mass, using the 2-loop conversion formula from the $\overline{\mathrm{MS}}$ mass.""" mcmc = par['m_c'] alpha_s = get_alpha(par, mcmc)['alpha_s'] return _get_mc_pole(mcmc=mcmc, alpha_s=alpha_s, nl=nl) # cached version @lru_cache(maxsize=config['settings']['cache size']) def _get_mc_pole(mcmc, alpha_s, nl): crd = rundec.CRunDec() return crd.mMS2mOS(mcmc, None, alpha_s, mcmc, 4, nl) def get_mc_KS(par, scale): r"""Get the $c$ quark mass in the kinetic scheme.""" mcmc = par['m_c'] alpha_s = get_alpha(par, mcmc)['alpha_s'] return _get_mc_KS(mcmc=mcmc, alpha_s=alpha_s, scale=scale, nl=3) # cached version @lru_cache(maxsize=config['settings']['cache size']) def _get_mc_KS(mcmc, alpha_s, scale, nl): return masses.mMS2mKS(MS=mcmc, Nf=3, asM=alpha_s, Mu=scale, nl=nl) def get_mb_pole(par, nl=2): # for mb, default to 2-loop conversion only due to renormalon ambiguity! r"""Get the $b$ quark pole mass, using the 2-loop conversion formula from the $\overline{\mathrm{MS}}$ mass.""" mbmb = par['m_b'] alpha_s = get_alpha(par, mbmb)['alpha_s'] return _get_mb_pole(mbmb=mbmb, alpha_s=alpha_s, nl=nl) # cached version @lru_cache(maxsize=config['settings']['cache size']) def _get_mb_pole(mbmb, alpha_s, nl): crd = rundec.CRunDec() return crd.mMS2mOS(mbmb, None, alpha_s, mbmb, 5, nl) def get_mb_KS(par, scale): r"""Get the $b$ quark mass in the kinetic scheme.""" mbmb = par['m_b'] alpha_s = get_alpha(par, mbmb)['alpha_s'] return _get_mb_KS(mbmb=mbmb, alpha_s=alpha_s, scale=scale, nl=3) # cached version @lru_cache(maxsize=config['settings']['cache size']) def _get_mb_KS(mbmb, alpha_s, scale, nl): # see 1107.3100 for why Nf=4 return masses.mMS2mKS(MS=mbmb, Nf=4, asM=alpha_s, Mu=scale, nl=nl) def get_mb_1S(par, nl=3): r"""Get the $b$ quark mass in the 1S scheme.""" mbmb = par['m_b'] alpha_s = get_alpha(par, mbmb)['alpha_s'] return _get_mb_1S(mbmb=mbmb, alpha_s=alpha_s, scale=mbmb, nl=nl) # cached version @lru_cache(maxsize=config['settings']['cache size']) def _get_mb_1S(mbmb, alpha_s, scale, nl): crd = rundec.CRunDec() return crd.mMS2m1S(mbmb, None, alpha_s, scale, 5, nl) def get_mt(par, scale): r"""Get the running top quark mass at the specified scale.""" return _get_mt(mt_pole=par['m_t'], alpha_s=get_alpha_s(par, scale), scale=scale) # cached version @lru_cache(maxsize=config['settings']['cache size']) def _get_mt(mt_pole, alpha_s, scale): r"""Get the running top quark mass at the specified scale.""" crd = rundec.CRunDec() return crd.mOS2mMS(mt_pole, None, alpha_s, scale, 6, 3) def get_mt_mt(par): r"""Get the scale invariant top quark mass mt(mt).""" mt_pole = par['m_t'] return _get_mt_mt(mt_pole=mt_pole, alpha_s=get_alpha_s(par, mt_pole)) # cached version @lru_cache(maxsize=config['settings']['cache size']) def _get_mt_mt(mt_pole, alpha_s): r"""Get the scale invariant top quark mass mt(mt).""" crd = rundec.CRunDec() return crd.mOS2mSI(mt_pole, None, alpha_s, 6, 3) def make_wilson_rge_derivative(adm): if adm is None: return None def derivative(x, mu, nf): alpha_s = x[-2] alpha_e = x[-1] c_real = x[:-2] c = c_real.view(np.complex) d_alpha = betafunctions.beta_qcd_qed([alpha_s, alpha_e], mu, nf) d_c = np.dot(adm(nf, alpha_s, alpha_e).T, c)/mu d_c_real = d_c.view(float) return np.append(d_c_real, d_alpha) def derivative_nf(nf): return lambda x, mu: derivative(x, mu, nf) return derivative_nf def get_wilson(par, c_in, derivative_nf, scale_in, scale_out, nf_out=None): r"""RG evolution of a vector of Wilson coefficients. In terms of the anomalous dimension matrix $\gamma$, the RGE reads $$\mu\frac{d}{d\mu} \vec C = \gamma^T(n_f, \alpha_s, \alpha_e) \vec C$$ """ alpha_in = get_alpha(par, scale_in, nf_out=nf_out) # x is (c_1, ..., c_N, alpha_s, alpha_e) c_in_real = np.asarray(c_in, dtype=complex).view(float) x_in = np.append(c_in_real, [alpha_in['alpha_s'], alpha_in['alpha_e']]) sol = rg_evolve_sm(x_in, derivative_nf, scale_in, scale_out, nf_out=nf_out) c_out = sol[:-2] return c_out.view(np.complex) def get_f_perp(par, meson, scale, nf_out=None): r"""Get the transverse meson decay constant at a given scale. The argument `meson` should be one of `rho0`, `rho+`, `K*0`, `K*+`, `omega`, `phi`. The input value for the transverse decay constant is taken from `par` and is assumed to be at a scale of 2 GeV in the 3-flavour scheme. """ thresholds = _thresholds() f_perp = par['f_perp_' + meson] scale_start = 2 nf = 3 if scale == scale_start: return f_perp for nf in (3, 4, 5, 6): # run to final scale directly if nf equals nf_out if nf_out is not None and nf_out == nf: scale_stop = scale # run either to next threshold or to final scale, whichever is closer else: scale_stop = min(thresholds[nf + 1], scale) f_perp = _rg_factor_f_perp(par, scale_start, scale_stop, nf) * f_perp if scale_stop == scale: return f_perp scale_start = thresholds[nf + 1] def _rg_factor_f_perp(par, scale_start, scale_stop, nf): r"""This function returns the leading order renormalization group (RG) factor that relates the value of the transverse meson decay constant at the scale `scale_stop` to its value at the scale `scale_start`. The number of fermion flavours to be taken into account is specified by `nf`. The exponent used in the RG factor can be written es `4/(3*beta_0)`, where `beta_0` is given by `11-2*nf/3` (cf. e.g. https://arxiv.org/abs/hep-lat/0301020 eq. (14)). """ alpha_start = get_alpha_s(par, scale_start, nf_out=nf) alpha_stop = get_alpha_s(par, scale_stop, nf_out=nf) return (alpha_stop / alpha_start)**(4 / (33 - 2 * nf))
Module variables
var config
var pi
var run_alpha_e
Functions
def get_alpha(
par, scale, nf_out=None)
Get the running $\overline{\mathrm{MS}}$ $\alpha_s$ and $\alpha_e$ at the specified scale.
def get_alpha(par, scale, nf_out=None): r"""Get the running $\overline{\mathrm{MS}}$ $\alpha_s$ and $\alpha_e$ at the specified scale. """ return {'alpha_e' : get_alpha_e(par, scale, nf_out=nf_out), 'alpha_s' : get_alpha_s(par, scale, nf_out=nf_out)}
def get_alpha_e(
par, scale, nf_out=None)
Get the running $\overline{\mathrm{MS}}$ fine-structure constant $\alpha_e$ at the specified scale.
def get_alpha_e(par, scale, nf_out=None): r"""Get the running $\overline{\mathrm{MS}}$ fine-structure constant $\alpha_e$ at the specified scale.""" nf = nf_out or get_nf(scale) aeMZ = par['alpha_e'] MZ = 91.1876 # m_Z treated as a constant here mt = config['RGE thresholds']['mt'] mb = config['RGE thresholds']['mb'] mc = config['RGE thresholds']['mc'] if nf == 5: return run_alpha_e(aeMZ, MZ, scale, n_u=2, n_d=3, n_e=3) elif nf == 6: aemt = run_alpha_e(aeMZ, MZ, mt, n_u=2, n_d=3, n_e=3) return run_alpha_e(aemt, mt, scale, n_u=3, n_d=3, n_e=3) elif nf == 4: aemb = run_alpha_e(aeMZ, MZ, mb, n_u=2, n_d=3, n_e=3) return run_alpha_e(aemb, mb, scale, n_u=2, n_d=2, n_e=3) elif nf == 3: aemb = run_alpha_e(aeMZ, MZ, mb, n_u=2, n_d=3, n_e=3) aemc = run_alpha_e(aemb, mb, mc, n_u=2, n_d=2, n_e=3) return run_alpha_e(aemc, mc, scale, n_u=1, n_d=2, n_e=2) else: raise ValueError("Invalid value: nf_out={}".format(nf_out))
def get_alpha_s(
par, scale, nf_out=None)
Get the running $\overline{\mathrm{MS}}$ QCD coupling constant $\alpha_s$ at the specified scale.
def get_alpha_s(par, scale, nf_out=None): r"""Get the running $\overline{\mathrm{MS}}$ QCD coupling constant $\alpha_s$ at the specified scale.""" nf = nf_out or get_nf(scale) return qcd.alpha_s(scale=scale, f=nf, alphasMZ=par['alpha_s'])
def get_f_perp(
par, meson, scale, nf_out=None)
Get the transverse meson decay constant at a given scale.
The argument meson
should be one of rho0
, rho+
, K*0
, K*+
,
omega
, phi
. The input value for the transverse decay constant is taken
from par
and is assumed to be at a scale of 2 GeV in the 3-flavour
scheme.
def get_f_perp(par, meson, scale, nf_out=None): r"""Get the transverse meson decay constant at a given scale. The argument `meson` should be one of `rho0`, `rho+`, `K*0`, `K*+`, `omega`, `phi`. The input value for the transverse decay constant is taken from `par` and is assumed to be at a scale of 2 GeV in the 3-flavour scheme. """ thresholds = _thresholds() f_perp = par['f_perp_' + meson] scale_start = 2 nf = 3 if scale == scale_start: return f_perp for nf in (3, 4, 5, 6): # run to final scale directly if nf equals nf_out if nf_out is not None and nf_out == nf: scale_stop = scale # run either to next threshold or to final scale, whichever is closer else: scale_stop = min(thresholds[nf + 1], scale) f_perp = _rg_factor_f_perp(par, scale_start, scale_stop, nf) * f_perp if scale_stop == scale: return f_perp scale_start = thresholds[nf + 1]
def get_mb(
par, scale, nf_out=None)
Get the running $b$ quark mass at the specified scale.
def get_mb(par, scale, nf_out=None): r"""Get the running $b$ quark mass at the specified scale.""" nf = nf_out or get_nf(scale) return qcd.m_b(mbmb=par['m_b'], scale=scale, f=nf, alphasMZ=par['alpha_s'])
def get_mb_1S(
par, nl=3)
Get the $b$ quark mass in the 1S scheme.
def get_mb_1S(par, nl=3): r"""Get the $b$ quark mass in the 1S scheme.""" mbmb = par['m_b'] alpha_s = get_alpha(par, mbmb)['alpha_s'] return _get_mb_1S(mbmb=mbmb, alpha_s=alpha_s, scale=mbmb, nl=nl)
def get_mb_KS(
par, scale)
Get the $b$ quark mass in the kinetic scheme.
def get_mb_KS(par, scale): r"""Get the $b$ quark mass in the kinetic scheme.""" mbmb = par['m_b'] alpha_s = get_alpha(par, mbmb)['alpha_s'] return _get_mb_KS(mbmb=mbmb, alpha_s=alpha_s, scale=scale, nl=3)
def get_mb_pole(
par, nl=2)
Get the $b$ quark pole mass, using the 2-loop conversion formula from the $\overline{\mathrm{MS}}$ mass.
def get_mb_pole(par, nl=2): # for mb, default to 2-loop conversion only due to renormalon ambiguity! r"""Get the $b$ quark pole mass, using the 2-loop conversion formula from the $\overline{\mathrm{MS}}$ mass.""" mbmb = par['m_b'] alpha_s = get_alpha(par, mbmb)['alpha_s'] return _get_mb_pole(mbmb=mbmb, alpha_s=alpha_s, nl=nl)
def get_mc(
par, scale, nf_out=None)
Get the running $c$ quark mass at the specified scale.
def get_mc(par, scale, nf_out=None): r"""Get the running $c$ quark mass at the specified scale.""" nf = nf_out or get_nf(scale) return qcd.m_c(mcmc=par['m_c'], scale=scale, f=nf, alphasMZ=par['alpha_s'])
def get_mc_KS(
par, scale)
Get the $c$ quark mass in the kinetic scheme.
def get_mc_KS(par, scale): r"""Get the $c$ quark mass in the kinetic scheme.""" mcmc = par['m_c'] alpha_s = get_alpha(par, mcmc)['alpha_s'] return _get_mc_KS(mcmc=mcmc, alpha_s=alpha_s, scale=scale, nl=3)
def get_mc_pole(
par, nl=2)
Get the $c$ quark pole mass, using the 2-loop conversion formula from the $\overline{\mathrm{MS}}$ mass.
def get_mc_pole(par, nl=2): # for mc, default to 2-loop conversion only due to renormalon ambiguity! r"""Get the $c$ quark pole mass, using the 2-loop conversion formula from the $\overline{\mathrm{MS}}$ mass.""" mcmc = par['m_c'] alpha_s = get_alpha(par, mcmc)['alpha_s'] return _get_mc_pole(mcmc=mcmc, alpha_s=alpha_s, nl=nl)
def get_md(
par, scale, nf_out=None)
Get the running $d$ quark mass at the specified scale.
def get_md(par, scale, nf_out=None): r"""Get the running $d$ quark mass at the specified scale.""" nf = nf_out or get_nf(scale) return qcd.m_s(ms2=par['m_d'], scale=scale, f=nf, alphasMZ=par['alpha_s'])
def get_mq(
q, par, scale, nf_out=None)
def get_mq(q, par, scale, nf_out=None): fdict = {'u': get_mu, 'c': get_mc, 'd': get_md, 's': get_ms, 'b': get_mb} return fdict[q](par, scale, nf_out=nf_out)
def get_ms(
par, scale, nf_out=None)
Get the running $s$ quark mass at the specified scale.
def get_ms(par, scale, nf_out=None): r"""Get the running $s$ quark mass at the specified scale.""" nf = nf_out or get_nf(scale) return qcd.m_s(ms2=par['m_s'], scale=scale, f=nf, alphasMZ=par['alpha_s'])
def get_mt(
par, scale)
Get the running top quark mass at the specified scale.
def get_mt(par, scale): r"""Get the running top quark mass at the specified scale.""" return _get_mt(mt_pole=par['m_t'], alpha_s=get_alpha_s(par, scale), scale=scale)
def get_mt_mt(
par)
Get the scale invariant top quark mass mt(mt).
def get_mt_mt(par): r"""Get the scale invariant top quark mass mt(mt).""" mt_pole = par['m_t'] return _get_mt_mt(mt_pole=mt_pole, alpha_s=get_alpha_s(par, mt_pole))
def get_mu(
par, scale, nf_out=None)
Get the running $u$ quark mass at the specified scale.
def get_mu(par, scale, nf_out=None): r"""Get the running $u$ quark mass at the specified scale.""" nf = nf_out or get_nf(scale) return qcd.m_s(ms2=par['m_u'], scale=scale, f=nf, alphasMZ=par['alpha_s'])
def get_nf(
scale)
Guess the number of quark flavours based on the scale, if not specified manually.
def get_nf(scale): """Guess the number of quark flavours based on the scale, if not specified manually.""" mt = config['RGE thresholds']['mt'] mb = config['RGE thresholds']['mb'] mc = config['RGE thresholds']['mc'] if scale >= mt: return 6 elif mb <= scale < mt: return 5 elif mc <= scale < mb: return 4 elif scale < mc: return 3 else: raise ValueError("Unexpected value: scale={}".format(scale))
def get_wilson(
par, c_in, derivative_nf, scale_in, scale_out, nf_out=None)
RG evolution of a vector of Wilson coefficients.
In terms of the anomalous dimension matrix $\gamma$, the RGE reads $$\mu\frac{d}{d\mu} \vec C = \gamma^T(n_f, \alpha_s, \alpha_e) \vec C$$
def get_wilson(par, c_in, derivative_nf, scale_in, scale_out, nf_out=None): r"""RG evolution of a vector of Wilson coefficients. In terms of the anomalous dimension matrix $\gamma$, the RGE reads $$\mu\frac{d}{d\mu} \vec C = \gamma^T(n_f, \alpha_s, \alpha_e) \vec C$$ """ alpha_in = get_alpha(par, scale_in, nf_out=nf_out) # x is (c_1, ..., c_N, alpha_s, alpha_e) c_in_real = np.asarray(c_in, dtype=complex).view(float) x_in = np.append(c_in_real, [alpha_in['alpha_s'], alpha_in['alpha_e']]) sol = rg_evolve_sm(x_in, derivative_nf, scale_in, scale_out, nf_out=nf_out) c_out = sol[:-2] return c_out.view(np.complex)
def make_wilson_rge_derivative(
adm)
def make_wilson_rge_derivative(adm): if adm is None: return None def derivative(x, mu, nf): alpha_s = x[-2] alpha_e = x[-1] c_real = x[:-2] c = c_real.view(np.complex) d_alpha = betafunctions.beta_qcd_qed([alpha_s, alpha_e], mu, nf) d_c = np.dot(adm(nf, alpha_s, alpha_e).T, c)/mu d_c_real = d_c.view(float) return np.append(d_c_real, d_alpha) def derivative_nf(nf): return lambda x, mu: derivative(x, mu, nf) return derivative_nf
def rg_evolve(
initial_condition, derivative, scale_in, scale_out)
def rg_evolve(initial_condition, derivative, scale_in, scale_out): sol = odeint(derivative, initial_condition, [scale_in, scale_out]) return sol[1]
def rg_evolve_sm(
initial_condition, derivative_nf, scale_in, scale_out, nf_out=None)
def rg_evolve_sm(initial_condition, derivative_nf, scale_in, scale_out, nf_out=None): if scale_in == scale_out: # no need to run! # However, return a copy to prevent accidentally changing the initial condition return copy.deepcopy(initial_condition) if scale_out < 0.1: raise ValueError('RG evolution below the strange threshold not implemented.') return _rg_evolve_sm(tuple(initial_condition), derivative_nf, scale_in, scale_out, nf_out)