Using precompute tables

First lets define our imports, the lookup table file paths, and the parameters of the precompute Bragg pulses. Then we will load in the actual precompute tables.

[1]:
import numpy as np
from numba import jit, float64
from mwave.integrate import make_kvec, make_phi, bloch, phase_fnc_constant
from mwave.precompute import load_precomputed_gbragg

# Define parameters used to generate precompute table, these can optionally be passed into the load_precomputed_gbragg function
nbragg = 4
sigma = 0.259658916
tau_factor = 5

# Make a kvector
kvec, _, _ = make_kvec(0,nbragg)

# Try loading just the single frequency precompute table, then the combined single and multifrequency one
lookup_single_fname = 'single_bragg_sig0.260.h5'
lookup_multi_fname = 'multi_bragg_sig0.260.h5'

pgbragg_single = load_precomputed_gbragg(lookup_single_fname, table_sigma=sigma)
pgbragg_both = load_precomputed_gbragg(lookup_single_fname, lookup_multi_fname, table_sigma=sigma, table_modulation_frequency=8*nbragg)
Loading single frequency Bragg precompute table, this could take a while...
Precompute table loaded! Performing checks...
Checks passed!
Loading single frequency Bragg precompute table, this could take a while...
Precompute table loaded! Performing checks...
Checks passed!
Loading multifrequency Bragg precompute table, this could take a while...
Precompute table loaded! Performing checks...
Checks passed!

Now that we have loaded in our precompute tables, lets construct a function that takes the same arguments as pgbragg_single and pgbragg_both but directly computes the output wavefunction instead of using the lookup table.

[2]:
def gbragg(kvec, k0, sigma, omega, delta, delta_phase, mod_freq=None, mod_phase=0.0):

    # To stop edge effects effecting us when we compare to the precompute table we should actually use a much larger kvec
    inner_kvec = make_kvec(0,0,npad=50)[0]

    tfinal = 2*tau_factor*sigma

    if mod_freq:
        # mod_freq not None, use multi-Bragg

        @jit(float64(float64, float64[:]))
        def multi_omega_fnc(t, args):
            omega, sigma, t0, mod_freq, mod_phase = args
            return 2*np.cos(mod_freq*t + mod_phase)*omega*np.exp(-np.square(t-t0)/(2*(sigma**2)))

        sol = bloch(inner_kvec, make_phi(inner_kvec, k0/2), tfinal, delta, multi_omega_fnc, np.array([omega, sigma, tfinal/2, mod_freq, mod_phase]), phase_fnc_constant, np.array([delta_phase]))

        return sol.y[np.isin(inner_kvec, kvec),-1]

    else:
        # mod_freq is None, use single Bragg

        @jit(float64(float64, float64[:]))
        def omega_fnc_gaussian(t, args):
            omega, sigma, t0 = args
            return omega*np.exp(-np.square(t-t0)/(2*(sigma**2)))

        sol = bloch(inner_kvec, make_phi(inner_kvec, k0/2), tfinal, delta, omega_fnc_gaussian, np.array([omega, sigma, tfinal/2]), phase_fnc_constant, np.array([delta_phase]))

        return sol.y[np.isin(inner_kvec, kvec),-1]

Now that we have the direct and precomputed functions we and print out the differences between them. Lets start with a single frequency pulse.

[11]:
# Randomly sample parameters to cehck precompute table against
omega = np.random.rand()*45
k0 = 2*int(np.random.rand()*10-5)
delta = 4*nbragg + np.random.rand()*8 - 4
delta_phase = np.random.rand()*2*np.pi

# Compare direct computation to precomputed values
gb = gbragg(kvec, k0, sigma, omega, delta, delta_phase, 0.0, 0.0)
gbp = pgbragg_single(kvec, k0, sigma, np.array([omega]), np.array([delta]), delta_phase)
gbbp = pgbragg_both(kvec, k0, sigma, np.array([omega]), np.array([delta]), delta_phase)

# Print absolute differences
print('directly computed populations')
print(np.abs(gb[:])**2)
print('pgbragg_single')
print(f'phase deviations err {np.angle(gb[:])-np.angle(gbp[0,:])}')
print(f'population err {np.abs(gb[:])**2-np.abs(gbp[0,:])**2}')
print('\npgbragg_both')
print(f'phase deviations err {np.angle(gb[:])-np.angle(gbbp[0,:])}')
print(f'population err {np.abs(gb[:])**2-np.abs(gbbp[0,:])**2}')
directly computed populations
[7.73693526e-28 1.64408211e-26 6.69012041e-26 5.04494003e-25
 1.32733681e-24 6.56453256e-25 4.77292244e-24 3.74553216e-15
 5.11763100e-06 1.71478211e-03 4.99429309e-01 1.22978914e-01
 6.17643911e-02 5.66803520e-02 2.42007799e-01 1.54192069e-02
 1.26301855e-07 4.66194478e-17 4.93461050e-26 3.71251858e-26
 3.61496358e-26 2.61121489e-26 2.13290728e-26 3.63420981e-27
 7.39412202e-28]
pgbragg_single
phase deviations err [ 3.46198814e+00  4.40103642e+00  3.09117904e+00  6.20975992e-01
  2.51852691e-01  5.67958471e-02  1.43584660e-01 -2.71233819e-05
  2.57268540e-06 -2.72409143e-06  1.04484705e-06 -1.43832199e-07
  1.42969206e-06 -2.52064104e-06 -1.46709459e-07 -4.04860789e-06
  4.88389526e-05  4.74291736e-05  2.93782326e+00  2.19176450e+00
 -4.17334862e+00  1.85944392e+00 -6.60228378e-01 -4.38346450e+00
 -1.69580328e+00]
population err [-1.30244564e-27 -3.65248032e-24 -2.10536952e-25  1.11149705e-25
  1.83284151e-25  7.33429647e-26 -2.94150736e-25 -1.90206410e-19
  3.87883412e-11  3.40942213e-09 -2.40721744e-06 -2.54747354e-07
  9.49739348e-08  3.87778559e-07  3.19901486e-06  4.14241384e-07
  8.88351312e-12 -4.70473960e-21 -7.01075715e-26 -3.66908404e-28
  3.45642530e-27  1.40626575e-26  2.09893035e-26 -1.13502310e-26
  7.39412202e-28]

pgbragg_both
phase deviations err [ 3.46198814e+00  4.40103642e+00  3.09117904e+00  6.20975992e-01
  2.51852691e-01  5.67958471e-02  1.43584660e-01 -2.71233819e-05
  2.57268540e-06 -2.72409143e-06  1.04484705e-06 -1.43832199e-07
  1.42969206e-06 -2.52064104e-06 -1.46709459e-07 -4.04860789e-06
  4.88389526e-05  4.74291736e-05  2.93782326e+00  2.19176450e+00
 -4.17334862e+00  1.85944392e+00 -6.60228378e-01 -4.38346450e+00
 -1.69580328e+00]
population err [-1.30244564e-27 -3.65248032e-24 -2.10536952e-25  1.11149705e-25
  1.83284151e-25  7.33429647e-26 -2.94150736e-25 -1.90206410e-19
  3.87883412e-11  3.40942213e-09 -2.40721744e-06 -2.54747354e-07
  9.49739348e-08  3.87778559e-07  3.19901486e-06  4.14241384e-07
  8.88351312e-12 -4.70473960e-21 -7.01075715e-26 -3.66908404e-28
  3.45642530e-27  1.40626575e-26  2.09893035e-26 -1.13502310e-26
  7.39412202e-28]

This looks good. We have small population errors across the board, and our phase errors are only large when we have zero (i.e. 1e-12) population.

Now lets test a multi-frequency pulse.

[4]:
# Randomly sample parameters to cehck precompute table against
omega = np.random.rand()*45
k0 = 2*int(np.random.rand()*10-5)
nbloch = 0
delta = 4*nbragg + np.random.rand()*8 - 4
delta_phase = np.random.rand()*2*np.pi
mod_freq = 8*nbragg
mod_phase = 0

# Compare direct computation to precomputed values# Randomly sample parameters to cehck precompute table against

gb = gbragg(kvec, k0, sigma, omega, delta, delta_phase, mod_freq, mod_phase)
gbp = pgbragg_both(kvec, k0, sigma, np.array([omega]), np.array([delta]), delta_phase, mod_freq, mod_phase)

# Print absolute differences
print('directly computed populations')
print(np.abs(gb[:])**2)
print(f'phase deviations err {np.angle(gb[:])-np.angle(gbp[0,:])}')
print(f'population err {np.abs(gb[:])**2-np.abs(gbp[0,:])**2}')
directly computed populations
[6.51229483e-27 1.42337890e-25 1.03835926e-23 8.99007802e-17
 4.97042019e-11 1.74890545e-06 2.98260346e-02 5.18788503e-01
 1.27193768e-01 2.50302236e-01 6.70009950e-02 2.90726271e-03
 2.32270533e-03 1.48546635e-03 4.89464087e-05 2.55653484e-05
 3.62237932e-06 9.45748110e-06 6.93521332e-05 1.42954031e-05
 3.76057016e-08 2.84426433e-12 9.74848077e-18 1.02040308e-22
 3.00026708e-29]
phase deviations err [-4.26092646e+00  4.57348857e-01 -2.04220612e-01  1.27582364e-03
  6.75143828e-04  1.06487428e-05  5.11554111e-05 -3.62033632e-06
 -7.65706056e-07 -2.72753603e-05  1.37881045e-04  3.85593508e-04
 -5.90606717e-04  3.06754976e-03  4.53087003e-03  5.34724102e-03
 -1.09391735e-02  6.21637377e-02  1.34753156e-02  1.47683890e-01
  3.39391490e-01  3.71658534e-01  8.64316677e-01 -5.05147400e+00
  1.13114902e+00]
population err [-8.07988713e-28  4.01502118e-26 -2.50159970e-25  4.02479076e-19
  7.30890560e-14  6.05804583e-10  2.53960916e-06  6.50810047e-06
  2.56293970e-07  2.21832720e-05  6.17576041e-05  7.59193636e-06
  1.02596731e-05 -9.32421292e-07  1.11665033e-06  1.22015972e-06
  3.83786712e-07  2.04471964e-06  2.19419212e-05  5.15005244e-06
  1.19979719e-08  2.12826809e-12  2.16218882e-18  5.71925680e-23
  6.70548038e-30]

Same deal–our phase errors are only large when we have zero (i.e. 1e-12) population.