comnum.Ssfm#

class comnum.Ssfm(fiber, *, step_km=1.0, steps_per_span=None, amplification='edfa', raman=None, check_sampling=True)#

The symmetric split-step Fourier method of OptiCommPy (ssfm), one polarisation.

Every span is cut into n = ⌈L_span/h⌉ equal steps of δ = L_span/n (h itself when it divides the span); a step applies half of the linear operator (loss and dispersion) in the frequency domain, the nonlinear phase γ|A|²δ, then the other half. After every span:

  • "edfa": an EDFA of gain α L and the noise figure of the fibre (ASE drawn from rng, noiseless without one);

  • "ideal": a noiseless gain e^{αL/2} on the field;

  • "none": nothing.

Parameters:
  • fiber (FiberParams) – the link.

  • step_km (float) – step size h (km).

  • steps_per_span (int, optional) – this number of logarithmic steps per span instead of step_km (Bosco et al., IEEE PTL 12(5), 2000, eq. (6)): every step carries the same integrated power, short at the start of the span; double precision only.

  • amplification (str) – "edfa", "ideal" or "none".

  • raman (dict, optional) – Raman pumps and ISRS in every span, the keys of fiber.raman in a specification (see raman_profile()); the amplifier after a span then restores every frequency to its launch power.

Raises:

ValueError – for an invalid parameter or input (the message names it).

Examples

>>> import comnum, numpy as np
>>> link = comnum.Ssfm(comnum.FiberParams(n_spans=2), step_km=1.0, amplification="ideal")
>>> x = np.exp(2j * np.pi * np.arange(64) / 64) * 1e-2
>>> np.allclose(link.backpropagate(link.propagate(x, 32e9), 32e9, steps_per_span=80), x)
True
backpropagate(x, fs, *, steps_per_span=1, nonlinear_scale=1.0, step_distribution='uniform', step_factor=0.4, nonlinear_length='effective')#

Digital back-propagation with steps_per_span symmetric steps per span (the split step with -α, -β₂, -γ, spans in reverse order, amplifier gain removed first). With the forward step and no noise it inverts propagate exactly; with coarser steps the nonlinear phase of a step uses its effective length 2 sinh(αδ/2)/α.

Parameters:
  • x (array_like) – the received field (√W).

  • fs (float) – sampling rate (Hz).

  • steps_per_span (int) – steps per span (1 by default, as the dbp block).

  • nonlinear_scale (float) – ξ, multiplies the nonlinear phase (the optimised DBP with few steps per span, Ip & Kahn 2008; 0 gives the linear back-propagation).

  • step_distribution (str) – "uniform" (equal steps), "logarithmic" (Bosco et al. 2000: every step carries the same integrated power of the forward span, applied from its end; better with 2 to 8 steps per span, worse with many) or "modified_logarithmic" (Zhang et al. 2013: the attenuation times step_factor).

  • step_factor (float) – the adjusting factor of the modified logarithmic steps.

  • nonlinear_length (str) – "effective", the effective length of a coarse step (the power integrated over it), or "step", the step itself (the midpoint rule of Häger & Pfister 2021).

Returns:

the back-propagated field (complex128).

Return type:

numpy.ndarray

Raises:

ValueError – for an invalid parameter or input (the message names it).

propagate(x, fs, *, precision='f64', rng=None)#

Propagate a field over the link.

Parameters:
  • x (array_like) – the field (√W).

  • fs (float) – sampling rate (Hz).

  • rng (Rng, optional) – the generator of the ASE (noiseless without one).

  • precision (str) – "f64", or "f32" (about twice as fast, relative error about 1e-6 √steps; the amplifiers stay in double precision).

Returns:

the field at the end of the link (complex128).

Return type:

numpy.ndarray

Raises:

ValueError – for an invalid parameter or input (the message names it).

fiber#

The link (a copy).

Type:

FiberParams

step_km#

The step size (km).

Type:

float