Wolski

Compute coupled Wolski twiss matrices and normalization matrix in standard gauge Input matrix is assumed stable and can have arbitrary even dimension Main function can be mapped over a batch of input matrices and is differentiable

twiss.wolski.advance(n: torch.Tensor, m: torch.Tensor) tuple[torch.Tensor, torch.Tensor][source]

Compute advance and final normalization matrix given input transport and normalization matrices

Parameters:
  • n (Tensor, even-dimension, symplectic) – normalization matrix

  • m (Tensor, even-dimension, symplectic) – transport matrix

Returns:

phase advance final normalization matrix

Return type:

tuple[Tensor, Tensor]

Note

Output phase advance is mod 2 pi

Examples

>>> from math import pi
>>> import torch
>>> from twiss.matrix import  rotation
>>> m = rotation(2*pi*torch.tensor(0.88, dtype=torch.float64))
>>> _, n1, _ = twiss(m)
>>> t = torch.tensor([[1.0, 0.1], [0.0, 1.0]], dtype=torch.float64)
>>> mu, n2 = advance(n1, t)
>>> torch.allclose(t, n2 @ rotation(*mu) @ n1.inverse())
True
twiss.wolski.is_stable(m: torch.Tensor, *, epsilon: float = 1e-12) bool[source]

Check one-turn matrix stability

Parameters:
  • m (Tensor, even-dimension) – input one-turn matrix

  • epsilon (float, default=1.0E-12) – tolerance epsilon

Return type:

bool

Note

Input matrix is stable if eigenvalues are on the unit circle

Examples

>>> from math import pi
>>> import torch
>>> from twiss.matrix import rotation
>>> m = rotation(2*pi*torch.tensor(0.1234, dtype=torch.float64))
>>> is_stable(m)
True
>>> is_stable(m + 1.0E-3)
False
twiss.wolski.propagate(w: torch.Tensor, m: torch.Tensor) torch.Tensor[source]

Propagate Wolski twiss matrices throught a given transport matrix

Parameters:
  • w (Tensor, even-dimension) – Wolski twiss matrices

  • m (Tensor, even-dimension, symplectic) – transport matrix

Return type:

Tensor

Note

W_I = M W_I M.T

Examples

>>> from math import pi
>>> import torch
>>> from twiss.matrix import  rotation
>>> m = rotation(2*pi*torch.tensor(0.88, dtype=torch.float64))
>>> *_, w = twiss(m)
>>> propagate(w, torch.tensor([[1.0, 0.1], [0.0, 1.0]], dtype=torch.float64))
tensor([[[1.0100, 0.1000],
         [0.1000, 1.0000]]], dtype=torch.float64)
twiss.wolski.twiss(m: torch.Tensor, *, epsilon: float = 1e-12) tuple[torch.Tensor, torch.Tensor, torch.Tensor][source]

Compute coupled Wolski twiss parameters for a given one-turn input matrix

Returns fractional tunes, normalization matrix (standard gauge) and Wolski twiss matrices

Input matrix can have arbitrary even dimension Input matrix stability is not checked

Symplectic block is [[0, 1], [-1, 0]] Rotation block is [[cos(alpha), sin(alpha)], [-sin(alpha), cos(alpha)]] Complex block is 1/sqrt(2)*[[1, 1j], [1, -1j]]

Parameters:
  • m (Tensor, even-dimension, symplectic) – input one-turn matrix

  • epsilon (float, default=1.0E-12) – tolerance epsilon (ordering of planes)

Returns:

fractional tunes […, T_I, …] normalization matrix (standard gauge) N twiss matrices W = […, W_I, …]

Return type:

tuple[Tensor, Tensor, Tensor]

Note

M = N R N^-1 = … + W_I S sin(2*pi*T_I) - (W_I S)**2 cos(2*pi*T_I) + …

Examples

>>> from math import pi
>>> import torch
>>> from twiss.matrix import  rotation
>>> m = rotation(2*pi*torch.tensor(0.88, dtype=torch.float64))
>>> t, n, w = twiss(m)
>>> t
tensor([0.8800], dtype=torch.float64)
>>> n
tensor([[1.0000, 0.0000],
        [0.0000, 1.0000]], dtype=torch.float64)
>>> w
tensor([[[1.0000, 0.0000],
         [0.0000, 1.0000]]], dtype=torch.float64)
>>> from math import pi
>>> import torch
>>> from twiss.matrix import rotation
>>> m = rotation(*(2*pi*torch.linspace(0.1, 0.9, 9, dtype=torch.float64)))
>>> t, n, w = twiss(m)
>>> t
tensor([0.1000, 0.2000, 0.3000, 0.4000, 0.5000, 0.6000, 0.7000, 0.8000, 0.9000],
       dtype=torch.float64)
>>> from math import pi
>>> import torch
>>> from twiss.matrix import rotation
>>> m = torch.func.vmap(rotation)(2*pi*torch.linspace(0.1, 0.9, 9, dtype=torch.float64))
>>> t, n, w = torch.func.vmap(twiss)(m)
>>> t
tensor([[0.1000],
        [0.2000],
        [0.3000],
        [0.4000],
        [0.5000],
        [0.6000],
        [0.7000],
        [0.8000],
        [0.9000]], dtype=torch.float64)
>>> from math import pi
>>> import torch
>>> from twiss.matrix import  rotation
>>> def fn(k):
...    m = rotation(2*pi*torch.tensor(0.88, dtype=torch.float64))
...    i = torch.ones_like(k)
...    o = torch.zeros_like(k)
...    m = m @ torch.stack([i, k, o, i]).reshape(m.shape)
...    t, *_ = twiss(m)
...    return t
>>> k = torch.tensor(0.0, dtype=torch.float64)
>>> fn(k)
tensor([0.8800], dtype=torch.float64)
>>> torch.func.jacfwd(fn)(k)
tensor([0.0796], dtype=torch.float64)