Analytic Continuation
The continuation module implements the later stages of the analytic continuation pipeline, including holomorphic checking, inversion, and composition operations.
Pipeline Overview
After Laurent map fitting (Stage 3), the pipeline continues with:
Stage 4: Check if the composition is holomorphic on an annulus
Stage 5: Compute the inverse mapping
Stage 6: Compute the composition and continuation grid
Pole Class
Represents a pole with location and residue information for analysis.
Holomorphic Checking (Stage 4)
Configuration
Result
Main Function
- analytic_continuation.check_f_holomorphic_on_annulus(poles, lmap, curve_scale, min_distance_param, cfg=None)[source]
Stage 4: Check that f’s poles are sufficiently far from the annulus image.
- Parameters:
poles (List[Pole]) – The poles of the meromorphic function f
lmap (LaurentMapResult) – The fitted Laurent map
curve_scale (float) – The diameter of the curve (for scaling)
min_distance_param (float) – The minDistance parameter from SplineExport (for pole margin)
cfg (HolomorphicCheckConfig, optional) – Configuration
- Return type:
Example usage:
from analytic_continuation import (
check_f_holomorphic_on_annulus,
HolomorphicCheckConfig,
)
config = HolomorphicCheckConfig(
rho_in=0.5,
rho_out=2.0,
theta_samples=1024,
tolerance=1e-8,
)
result = check_f_holomorphic_on_annulus(laurent_map, config)
if result.ok:
print("Function is holomorphic on the annulus")
else:
print(f"Check failed: {result.failure_reason}")
Inversion (Stage 5)
Configuration
- class analytic_continuation.InvertConfig[source]
Bases:
objectConfiguration for map inversion (Stage 5).
- Parameters:
- __init__(theta_grid=256, seed_radii=<factory>, max_iters=40, tol_abs_factor=1e-10, tol_rel_factor=1e-10, damping=True, max_backtracks=12)
Result
Main Function
- analytic_continuation.invert_z(z_query, lmap, curve_scale, cfg=None)[source]
Stage 5: Invert z(ζ) = z_query using multi-start Newton iteration.
- Parameters:
z_query (complex) – The point to invert
lmap (LaurentMapResult) – The Laurent map
curve_scale (float) – The diameter of the curve (for tolerance scaling)
cfg (InvertConfig, optional) – Configuration
- Return type:
Computes the inverse of the Laurent map at a given target point:
from analytic_continuation import invert_z, InvertConfig
config = InvertConfig(
max_iter=100,
tol=1e-10,
initial_guess=None, # Use automatic guess
)
result = invert_z(laurent_map, target_z=1.5 + 0.5j, config=config)
if result.ok:
print(f"Inverse found: zeta = {result.zeta}")
print(f"Iterations: {result.iterations}")
else:
print(f"Inversion failed: {result.failure_reason}")
Composition (Stage 6)
Result
Main Functions
- analytic_continuation.compute_composition(z_query, f, lmap, curve_scale, invert_cfg=None)[source]
Stage 6: Compute A(f(B(z_query))) using the shared parameterization shortcut.
- Because reflections A and B are defined via the shared parameter ζ:
B(z(ζ)) = z(1/conj(ζ)) A(w(ζ)) = w(1/conj(ζ)) where w(ζ) = f(z(ζ))
- The composition simplifies:
A(f(B(z(ζ)))) = f(z(ζ))
So we just need to: 1. Invert z_query to find ζ 2. Return f(z(ζ)) = f(z_query) if ζ is on the unit circle
- Parameters:
z_query (complex) – The query point
f (Callable[[complex], complex]) – The meromorphic function to evaluate
lmap (LaurentMapResult) – The Laurent map
curve_scale (float) – The diameter of the curve
invert_cfg (InvertConfig, optional) – Configuration for inversion
- Return type:
Compute the composition of functions for analytic continuation:
from analytic_continuation import compute_composition
result = compute_composition(
laurent_map=lmap,
f=lambda z: z**2 + 1, # The function to continue
zeta=np.exp(1j * theta),
)
- analytic_continuation.compute_continuation_grid(f, lmap, curve_scale, x_range, y_range, resolution, invert_cfg=None)[source]
Compute the analytic continuation of f on a grid.
Returns both the computed values and a mask indicating which points converged.
- Parameters:
f (Callable) – The meromorphic function
lmap (LaurentMapResult) – The Laurent map
curve_scale (float) – Curve diameter for tolerance scaling
resolution (int) – Number of grid points per axis
invert_cfg (InvertConfig, optional) – Inversion configuration
- Return type:
- Returns:
values (np.ndarray) – Complex array of shape (resolution, resolution) with computed values
converged (np.ndarray) – Boolean array indicating which points converged
Compute continuation values on a grid:
import numpy as np
from analytic_continuation import compute_continuation_grid
# Define a grid in the zeta plane
re = np.linspace(-2, 2, 100)
im = np.linspace(-2, 2, 100)
zeta_grid = re[:, None] + 1j * im[None, :]
# Compute continuation
continuation = compute_continuation_grid(
laurent_map=lmap,
f=lambda z: np.sin(z),
zeta_grid=zeta_grid,
mask_outside_annulus=True,
)
Workflow Example
Complete workflow for analytic continuation:
from analytic_continuation import (
fit_laurent_map,
check_f_holomorphic_on_annulus,
invert_z,
compute_continuation_grid,
SplineExport,
LaurentFitConfig,
HolomorphicCheckConfig,
)
import numpy as np
# Stage 3: Fit Laurent map
export = SplineExport.from_json(curve_json)
fit_result = fit_laurent_map(export)
if not fit_result.ok:
raise ValueError(f"Fitting failed: {fit_result.failure_reason}")
lmap = fit_result.laurent_map
# Stage 4: Check holomorphic
check_config = HolomorphicCheckConfig(rho_in=0.5, rho_out=2.0)
check_result = check_f_holomorphic_on_annulus(lmap, check_config)
if not check_result.ok:
raise ValueError(f"Holomorphic check failed: {check_result.failure_reason}")
# Stage 6: Compute continuation grid
re = np.linspace(-3, 3, 200)
im = np.linspace(-3, 3, 200)
zeta_grid = re[:, None] + 1j * im[None, :]
continuation = compute_continuation_grid(
laurent_map=lmap,
f=lambda z: 1 / (z**2 + 1),
zeta_grid=zeta_grid,
)
# The result can be visualized using domain coloring