Analytic continuation

Analytic continuation allows one to handle resonances just below threshold (\(m_0 < m_a + m_b\) in Eq. (9)). In practice, this entails using a specific function for \(\rho\) in Eq. (3).

Definitions

Three usual choices for \(\rho\) are the following:

import sympy as sp
from IPython.display import Math

1) Break-up momentum

The sqrt() or ComplexSqrt of breakup_momentum_squared():

from ampform.dynamics import breakup_momentum_squared

s, m_a, m_b = sp.symbols("s, m_a, m_b", real=True)
q_squared = breakup_momentum_squared(s, m_a, m_b)
q_squared_symbol = sp.Symbol("q^{2}(s)")
Math(f"{sp.latex(q_squared_symbol)} = {sp.latex(q_squared)}")
\[\displaystyle q^{2}(s) = \frac{\left(s - \left(m_{a} - m_{b}\right)^{2}\right) \left(s - \left(m_{a} + m_{b}\right)^{2}\right)}{4 s}\]

2) ‘Normal’ phase space factor

The ‘normal’ phase_space_factor() (the denominator makes the difference to (3)!):

from ampform.dynamics import phase_space_factor

rho = phase_space_factor(s, m_a, m_b)
rho_subs = rho.subs(4 * q_squared, 4 * q_squared_symbol)
Math(fR"\rho(s) = {sp.latex(rho_subs)}")
\[\displaystyle \rho(s) = \frac{\sqrt{q^{2}(s)}}{8 \pi \sqrt{s}}\]

3) ‘Complex’ phase space factor

A phase_space_factor_complex() that uses ComplexSqrt:

from ampform.dynamics import phase_space_factor_complex

rho_complex = phase_space_factor_complex(s, m_a, m_b)
rho_complex_subs = rho_complex.subs(4 * q_squared, 4 * q_squared_symbol)
Math(fR"\rho_c(s) = {sp.latex(rho_complex_subs)}")
\[\displaystyle \rho_c(s) = \frac{\sqrt[\mathrm{c}]{q^{2}(s)}}{8 \pi \sqrt{s}}\]

4) ‘Analytic continuation’ of the phase space factor

The following ‘case-by-case’ analytic continuation, phase_space_factor_analytic():

from ampform.dynamics import phase_space_factor_analytic

rho_analytic = phase_space_factor_analytic(s, m_a, m_b)
\[\begin{split}\displaystyle \begin{cases} \frac{i \hat{\rho} \log{\left(\left|{\frac{\hat{\rho} + 1}{\hat{\rho} - 1}}\right| \right)}}{\pi} & \text{for}\: s < 0 \\\frac{i \hat{\rho} \log{\left(\left|{\frac{\hat{\rho} + 1}{\hat{\rho} - 1}}\right| \right)}}{\pi} + \hat{\rho} & \text{for}\: s > \left(m_{a} + m_{b}\right)^{2} \\\frac{2 i \hat{\rho} \operatorname{atan}{\left(\frac{1}{\hat{\rho}} \right)}}{\pi} & \text{otherwise} \end{cases}\end{split}\]

with

\[\displaystyle \hat{\rho} = \frac{\sqrt{\left|{q^{2}(s)}\right|}}{8 \pi \sqrt{s}}\]

(Mind the absolute value.)

Visualization

%matplotlib widget
import matplotlib.pyplot as plt
import mpl_interactions.ipyplot as iplt
import numpy as np

import symplot
from ampform.dynamics import ComplexSqrt

m = sp.Symbol("m", real=True)
rho_c = phase_space_factor_complex(m ** 2, m_a, m_b)
rho_ac = phase_space_factor_analytic(m ** 2, m_a, m_b)
np_rho_c, sliders = symplot.prepare_sliders(plot_symbol=m, expression=rho_c)
np_rho_ac = sp.lambdify((m, m_a, m_b), rho_ac, "numpy")
np_breakup_momentum = sp.lambdify(
    (m, m_a, m_b), ComplexSqrt(q_squared.subs(s, m ** 2)), "numpy"
)
plot_domain = np.linspace(0, 3, 500)
sliders.set_ranges(
    m_a=(0, 2, 200),
    m_b=(0, 2, 200),
)
sliders.set_values(
    m_a=0.6,
    m_b=1.25,
)
fig, axes = plt.subplots(1, 3, figsize=[10, 4], tight_layout=True)
fig.canvas.toolbar_visible = False

ax_q, ax_rho, ax_rho_ac = axes
for ax in axes:
    ax.set_xlabel("$m$")

ylim_q = (-0.04, 1.0)
ylim_rho = (-0.002, 0.05)


def func_imag(func, *args, **kwargs):
    return lambda *args, **kwargs: func(*args, **kwargs).imag


def func_real(func, *args, **kwargs):
    return lambda *args, **kwargs: func(*args, **kwargs).real


q_math = ComplexSqrt(q_squared_symbol)
ax_q.set_title(f"${sp.latex(q_math)}$")
controls = iplt.plot(
    plot_domain,
    func_real(np_breakup_momentum),
    label="real",
    **sliders,
    ylim=ylim_q,
    ax=ax_q,
    alpha=0.7,
)
iplt.plot(
    plot_domain,
    func_imag(np_breakup_momentum),
    label="imaginary",
    controls=controls,
    ylim=ylim_q,
    ax=ax_q,
    alpha=0.7,
)

ax_rho.set_title(f"${sp.latex(rho_complex_subs)}$")
iplt.plot(
    plot_domain,
    func_real(np_rho_c),
    label="real",
    controls=controls,
    ylim=ylim_rho,
    ax=ax_rho,
    alpha=0.7,
)
iplt.plot(
    plot_domain,
    func_imag(np_rho_c),
    label="imaginary",
    controls=controls,
    ylim=ylim_rho,
    ax=ax_rho,
    alpha=0.7,
)

ax_rho_ac.set_title("analytic")
iplt.plot(
    plot_domain,
    func_real(np_rho_ac),
    label="real",
    controls=controls,
    ylim=ylim_rho,
    ax=ax_rho_ac,
    alpha=0.7,
)
iplt.plot(
    plot_domain,
    func_imag(np_rho_ac),
    label="imaginary",
    controls=controls,
    ylim=ylim_rho,
    ax=ax_rho_ac,
    alpha=0.7,
)
plt.legend(loc="upper right")

plt.show()
../../_images/analytic-continuation_32_0.svg