Example-18: Inverse tracking

[1]:
import torch

from model.library.drift import Drift
from model.library.quadrupole import Quadrupole
from model.library.sextupole import Sextupole
from model.library.octupole import Octupole
from model.library.multipole import Multipole
from model.library.dipole import Dipole
from model.library.corrector import Corrector
from model.library.gradient import Gradient
from model.library.linear import Linear
from model.library.bpm import BPM
from model.library.marker import Marker
from model.library.line import Line
[2]:
# Drift

MF = Drift('MAG', length=1.0, dp=0.001, dx=0.0, dy=0.0, dz=0.0, wx=0.0, wy=0.0, wz=0.0, ns=10, exact=False)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Drift('MAG', length=1.0, dp=0.001, dx=0.0, dy=0.0, dz=0.0, wx=0.0, wy=0.0, wz=0.0, ns=10, exact=True)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Drift('MAG', length=1.0, dp=0.001, dx=0.01, dy=0.01, dz=-0.01, wx=0.001, wy=-0.001, wz=0.001, ns=10, exact=True)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Drift('MAG', length=1.0, dp=0.001, dx=0.01, dy=0.01, dz=-0.01, wx=0.001, wy=-0.001, wz=0.001, ns=10, exact=True, insertion=True)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0005, -0.0005,  0.0060,  0.0010], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([0., 0., 0., 0.], dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0005, -0.0005,  0.0060,  0.0010], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([0., 0., 0., 0.], dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0005, -0.0005,  0.0060,  0.0010], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([-8.6736e-19,  2.1684e-19,  0.0000e+00, -4.3368e-19],
       dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([-2.7015e-10, -5.0000e-04,  6.0000e-03,  1.0000e-03],
       dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([-2.6021e-18,  2.1684e-19,  8.6736e-19, -4.3368e-19],
       dtype=torch.float64)

[3]:
# Quadrupole

MF = Quadrupole('MAG', length=0.5, kn=3.0, ks=-1.0, dp=0.001, dx=0.0, dy=0.0, dz=0.0, wx=0.0, wy=0.0, wz=0.0, ns=10, exact=False)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Quadrupole('MAG', length=0.5, kn=3.0, ks=-1.0, dp=0.001, dx=0.0, dy=0.0, dz=0.0, wx=0.0, wy=0.0, wz=0.0, ns=10, exact=True)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Quadrupole('MAG', length=0.5, kn=3.0, ks=-1.0, dp=0.001, dx=0.01, dy=0.01, dz=-0.01, wx=0.001, wy=-0.001, wz=0.001, ns=10, exact=True)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Quadrupole('MAG', length=0.5, kn=3.0, ks=-1.0, dp=0.001, dx=0.01, dy=0.01, dz=-0.01, wx=0.001, wy=-0.001, wz=0.001, ns=10, exact=True, insertion=True)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([-0.0002, -0.0043,  0.0075,  0.0095], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 6.5052e-19,  0.0000e+00,  3.4694e-18, -8.6736e-19],
       dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([-0.0002, -0.0043,  0.0075,  0.0095], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([-8.6736e-19, -7.0473e-18,  6.0715e-18, -2.1684e-18],
       dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0046,  0.0135,  0.0046, -0.0031], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([-9.5410e-18,  1.1926e-18,  8.6736e-19, -7.8063e-18],
       dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0005, -0.0005,  0.0055,  0.0010], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([-7.8063e-18, -3.9031e-18, -2.6021e-18, -8.6736e-19],
       dtype=torch.float64)

[4]:
# Sextupole

MF = Sextupole('MAG', length=0.25, ms=10.0, dp=0.001, dx=0.0, dy=0.0, dz=0.0, wx=0.0, wy=0.0, wz=0.0, ns=10, exact=False)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Sextupole('MAG', length=0.25, ms=10.0, dp=0.001, dx=0.0, dy=0.0, dz=0.0, wx=0.0, wy=0.0, wz=0.0, ns=10, exact=True)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Sextupole('MAG', length=0.25, ms=10.0, dp=0.001, dx=0.01, dy=0.01, dz=-0.01, wx=0.001, wy=-0.001, wz=0.001, ns=10, exact=True)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Sextupole('MAG', length=0.25, ms=10.0, dp=0.001, dx=0.01, dy=0.01, dz=-0.01, wx=0.001, wy=-0.001, wz=0.001, ns=10, exact=True, insertion=True)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0009, -0.0005,  0.0053,  0.0010], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([0., 0., 0., 0.], dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0009, -0.0005,  0.0053,  0.0010], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([0., 0., 0., 0.], dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0009, -0.0006,  0.0053,  0.0011], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([-8.6736e-19,  1.0842e-19, -8.6736e-19, -4.3368e-19],
       dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0007, -0.0006,  0.0053,  0.0011], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([-8.6736e-19,  1.0842e-19, -8.6736e-19,  0.0000e+00],
       dtype=torch.float64)

[5]:
# Octupole

MF = Octupole('MAG', length=0.25, mo=25.0, dp=0.001, dx=0.0, dy=0.0, dz=0.0, wx=0.0, wy=0.0, wz=0.0, ns=10, exact=False)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Octupole('MAG', length=0.25, mo=25.0, dp=0.001, dx=0.0, dy=0.0, dz=0.0, wx=0.0, wy=0.0, wz=0.0, ns=10, exact=True)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Octupole('MAG', length=0.25, mo=25.0, dp=0.001, dx=0.01, dy=0.01, dz=-0.01, wx=0.001, wy=-0.001, wz=0.001, ns=10, exact=True)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Octupole('MAG', length=0.25, mo=25.0, dp=0.001, dx=0.01, dy=0.01, dz=-0.01, wx=0.001, wy=-0.001, wz=0.001, ns=10, exact=True, insertion=True)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0009, -0.0005,  0.0052,  0.0010], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([0., 0., 0., 0.], dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0009, -0.0005,  0.0052,  0.0010], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([0., 0., 0., 0.], dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0009, -0.0005,  0.0052,  0.0010], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([-8.6736e-19,  1.0842e-19,  0.0000e+00,  0.0000e+00],
       dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0008, -0.0005,  0.0052,  0.0010], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([-8.6736e-19,  0.0000e+00,  8.6736e-19,  0.0000e+00],
       dtype=torch.float64)

[6]:
# Multipole

MF = Multipole('MAG', length=0.25, kn=3.0, ks=-1.0, ms=10.0, mo=25.0, dp=0.001, dx=0.0, dy=0.0, dz=0.0, wx=0.0, wy=0.0, wz=0.0, ns=10, exact=False)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Multipole('MAG', length=0.25, kn=3.0, ks=-1.0, ms=10.0, mo=25.0, dp=0.001, dx=0.0, dy=0.0, dz=0.0, wx=0.0, wy=0.0, wz=0.0, ns=10, exact=True)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Multipole('MAG', length=0.25, kn=3.0, ks=-1.0, ms=10.0, mo=25.0, dp=0.001, dx=0.01, dy=0.01, dz=-0.01, wx=0.001, wy=-0.001, wz=0.001, ns=10, exact=True)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Multipole('MAG', length=0.25, kn=3.0, ks=-1.0, ms=10.0, mo=25.0, dp=0.001, dx=0.01, dy=0.01, dz=-0.01, wx=0.001, wy=-0.001, wz=0.001, ns=10, exact=True, insertion=True)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0006, -0.0024,  0.0057,  0.0048], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 7.5894e-18, -4.3368e-19, -2.0817e-17, -2.8189e-18],
       dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0006, -0.0024,  0.0057,  0.0048], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 7.3726e-18, -3.7947e-18, -2.0817e-17, -1.9516e-18],
       dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0019,  0.0072,  0.0051, -0.0005], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([-4.4235e-17,  3.0358e-18,  1.6480e-17, -4.1200e-18],
       dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0007, -0.0006,  0.0053,  0.0011], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([-3.7297e-17,  8.6736e-19,  9.5410e-18,  0.0000e+00],
       dtype=torch.float64)

[7]:
# Dipole

MF = Dipole('MAG', length=2.0, angle=0.1, e1=0.01, e2=0.05, kn=3.0, ks=-1.0, ms=10.0, mo=25.0, dp=0.001, dx=0.0, dy=0.0, dz=0.0, wx=0.0, wy=0.0, wz=0.0, ns=10, exact=False)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, -0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Dipole('MAG', length=2.0, angle=0.1, e1=0.01, e2=0.05, kn=3.0, ks=-1.0, ms=10.0, mo=25.0, dp=0.001, dx=0.01, dy=0.01, dz=-0.01, wx=0.001, wy=-0.001, wz=0.001, ns=10, exact=False)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, -0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Dipole('MAG', length=2.0, angle=0.1, e1=0.01, e2=0.05, kn=3.0, ks=-1.0, ms=10.0, mo=25.0, dp=0.001, dx=0.01, dy=0.01, dz=-0.01, wx=0.001, wy=-0.001, wz=0.001, ns=10, exact=False, insertion=True)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, -0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Dipole('MAG', length=2.0, angle=0.1, e1=0.01, e2=0.05, kn=1.0, ks=-1.0, ms=5.0, mo=10.0, dp=0.001, dx=0.0, dy=0.0, dz=0.0, wx=0.0, wy=0.0, wz=0.0, ns=10, exact=True)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, -0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Dipole('MAG', length=2.0, angle=0.1, e1=0.01, e2=0.05, kn=3.0, ks=-1.0, ms=10.0, mo=25.0, dp=0.001, dx=0.01, dy=0.01, dz=-0.01, wx=0.001, wy=-0.001, wz=0.001, ns=10, exact=True)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, -0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Dipole('MAG', length=2.0, angle=0.1, e1=0.01, e2=0.05, kn=3.0, ks=-1.0, ms=10.0, mo=25.0, dp=0.001, dx=0.01, dy=0.01, dz=-0.01, wx=0.001, wy=-0.001, wz=0.001, ns=10, exact=True, insertion=True)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, -0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()
tensor([ 0.0010, -0.0005,  0.0050, -0.0010], dtype=torch.float64)
tensor([-0.0116, -0.0136,  0.0722,  0.1266], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050, -0.0010], dtype=torch.float64)
tensor([ 4.0549e-17, -4.4452e-17, -1.2663e-16,  2.5045e-16],
       dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050, -0.0010], dtype=torch.float64)
tensor([ 0.0306,  0.0215, -0.0687, -0.1470], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050, -0.0010], dtype=torch.float64)
tensor([ 3.6689e-16, -8.8438e-16, -2.6489e-15,  4.6872e-15],
       dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050, -0.0010], dtype=torch.float64)
tensor([-0.0021, -0.0006,  0.0069, -0.0007], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050, -0.0010], dtype=torch.float64)
tensor([ 3.7297e-17,  3.1550e-17, -1.0408e-17,  2.1250e-17],
       dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050, -0.0010], dtype=torch.float64)
tensor([-0.0097, -0.0101,  0.0171,  0.0200], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050, -0.0010], dtype=torch.float64)
tensor([ 1.5400e-10, -2.2230e-10, -4.3635e-10,  5.0327e-10],
       dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050, -0.0010], dtype=torch.float64)
tensor([ 0.0304,  0.0215, -0.0691, -0.1473], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050, -0.0010], dtype=torch.float64)
tensor([-6.6071e-09, -4.3597e-10,  9.8294e-09, -1.9903e-08],
       dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050, -0.0010], dtype=torch.float64)
tensor([-0.0021, -0.0006,  0.0069, -0.0008], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050, -0.0010], dtype=torch.float64)
tensor([-1.6908e-12,  1.4334e-11,  2.0711e-11, -3.7469e-11],
       dtype=torch.float64)

[8]:
# Corrector

MF = Corrector('MAG', cx=0.01, cy=0.05, dp=0.001, dx=0.0, dy=0.0, dz=0.0, wx=0.0, wy=0.0, wz=0.0)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Corrector('MAG', cx=0.01, cy=0.05, dp=0.001, dx=0.01, dy=0.01, dz=-0.01, wx=0.001, wy=-0.001, wz=0.001)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([0.0010, 0.0095, 0.0050, 0.0510], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0000e+00, -4.3368e-19,  0.0000e+00,  8.6736e-19],
       dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([0.0011, 0.0095, 0.0055, 0.0510], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 8.6736e-19, -6.5052e-19,  0.0000e+00,  1.4962e-17],
       dtype=torch.float64)

[9]:
# Gradient

MF = Gradient('MAG', kn=0.1, ks=0.5, dp=0.001, dx=0.0, dy=0.0, dz=0.0, wx=0.0, wy=0.0, wz=0.0)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF = Gradient('MAG', kn=0.1, ks=0.5, dp=0.001, dx=0.01, dy=0.01, dz=-0.01, wx=0.001, wy=-0.001, wz=0.001)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([0.0010, 0.0019, 0.0050, 0.0020], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([0., 0., 0., 0.], dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0010, -0.0031,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 6.5052e-19,  1.0842e-18, -1.7347e-18, -2.1684e-19],
       dtype=torch.float64)

[10]:
# Linear

# Note, gives correct inverse for zero vector

length = 1.0
kn = - 2.0
ks = + 1.5
dp = 0.001
Q = Quadrupole('Q', length, kn, ks, dp)

state = torch.tensor([0.0, 0.0, 0.0, 0.0], dtype=torch.float64)

matrix = torch.func.jacrev(lambda state, dp: Q(state, data={**Q.data(), **{'dp': dp}}), 0)(state, Q.dp)
vector = torch.zeros_like(state)


MF = Linear('MAG', (dp*vector).tolist(), matrix.tolist(), dp=0.001, dx=0.0, dy=0.0, dz=0.0, wx=0.0, wy=0.0, wz=0.0)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()


MF = Linear('MAG', (dp*vector).tolist(), matrix.tolist(), dp=0.001, dx=0.01, dy=0.01, dz=-0.01, wx=0.001, wy=-0.001, wz=0.001)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0056,  0.0107,  0.0026, -0.0038], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([-2.8189e-18,  0.0000e+00,  5.2042e-18,  2.1684e-18],
       dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([-0.0009, -0.0046,  0.0097,  0.0083], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 8.6736e-19,  2.9273e-18, -1.7347e-18, -8.6736e-19],
       dtype=torch.float64)

[11]:
# Marker

MF = Marker('MAG', dp=0.001, dx=0.0, dy=0.0, dz=0.0, wx=0.0, wy=0.0, wz=0.0)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()

MF =  Marker('MAG', dp=0.001, dx=0.01, dy=0.01, dz=-0.01, wx=0.001, wy=-0.001, wz=0.001)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([0., 0., 0., 0.], dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 4.3368e-19,  2.1684e-19, -1.7347e-18, -4.3368e-19],
       dtype=torch.float64)

[12]:
# BPM

xx = torch.tensor(+0.05, dtype=torch.float64)
xy = torch.tensor(+0.01, dtype=torch.float64)
yx = torch.tensor(+0.05, dtype=torch.float64)
yy = torch.tensor(-0.06, dtype=torch.float64)

MF = BPM('MAG', dp=0.001, dx=0.0, dy=0.0, dz=0.0, wx=0.0, wy=0.0, wz=0.0)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data={**MF.data(), **{'xx': xx, 'xy': xy, 'yx': yx, 'yy': yy}}, alignment=True))
print(local := MI(local, data={**MI.data(), **{'xx': xx, 'xy': xy, 'yx': yx, 'yy': yy}}, alignment=True))
print(local - state)
print()

MF =  BPM('MAG', dp=0.001, dx=0.01, dy=0.01, dz=-0.01, wx=0.001, wy=-0.001, wz=0.001)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data={**MF.data(), **{'xx': xx, 'xy': xy, 'yx': yx, 'yy': yy}}, alignment=True))
print(local := MI(local, data={**MI.data(), **{'xx': xx, 'xy': xy, 'yx': yx, 'yy': yy}}, alignment=True))
print(local - state)
print()
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0011, -0.0005,  0.0047,  0.0011], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([-2.1684e-19,  1.0842e-19,  0.0000e+00,  0.0000e+00],
       dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0054,  0.0010], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([ 2.1684e-19,  0.0000e+00,  0.0000e+00, -2.1684e-19],
       dtype=torch.float64)

[13]:
# Line

QF = Quadrupole('QF', 1.0, +0.25)
QD = Quadrupole('QD', 1.0, -0.20)
SF = Sextupole('SF', 0.25)
SD = Sextupole('SD', 0.25)
DR = Drift('DR', 0.25)
BM = Dipole('BM', 3.50, torch.pi/8.0)

MF = Line('FODO',
          [QF, DR, SF, DR, BM, DR, SD, DR, QD, DR, SD, DR, BM, DR, SF, DR],
          propagate=True,
          dp=0.001,
          exact=False,
          output=False,
          matrix = False)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()


MF = Line('FODO',
          [QF, DR, SF, DR, BM, DR, SD, DR, QD, DR, SD, DR, BM, DR, SF, DR],
          propagate=True,
          dp=0.001,
          exact=True,
          output=False,
          matrix = False)
MI = MF.inverse()

state = torch.tensor([0.001, -0.0005, 0.005, 0.001], dtype=torch.float64)

print(local := state)
print(local := MF(local, data=MF.data(), alignment=True))
print(local := MI(local, data=MI.data(), alignment=True))
print(local - state)
print()
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([-0.0043, -0.0001,  0.0121, -0.0014], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([5.5793e-16, 1.2804e-16, 1.7347e-18, 8.6736e-19], dtype=torch.float64)

tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([-0.0380, -0.0058,  0.0121, -0.0015], dtype=torch.float64)
tensor([ 0.0010, -0.0005,  0.0050,  0.0010], dtype=torch.float64)
tensor([-9.8145e-13, -1.4483e-13,  1.8322e-12, -7.0449e-13],
       dtype=torch.float64)