Optical Bloch Equations

This module contains all the fast routines for optical Bloch equations.

Here is an example with rubidum 87.

>>> import fast
>>> element = "Rb"; isotope = 87; N = 5
>>> fine_states = [fast.State(element, isotope, N, 0, 1/fast.Integer(2)),
...                fast.State(element, isotope, N, 1, 3/fast.Integer(2))]
>>> magnetic_states = fast.make_list_of_states(fine_states, "magnetic")
>>> Ne = len(magnetic_states)
>>> Nl = 2
>>> E0 = [1e2, 1e2]
>>> epsilonp = [[0.0, 0.0, 1.0], [0.0, 0.0, 1.0]]
>>> omega, gamma, r = fast.calculate_matrices(magnetic_states)
>>> omega_level = [omega[i][0] for i in range(Ne)]
>>> r = fast.helicity_to_cartesian(r, numeric=True)
>>> rm = np.array([[[r[p, i, j]*fast.symbolic.delta_greater(i, j)*a0
...                for j in range(Ne)] for i in range(Ne)]
...                for p in range(3)])
>>> def coupled2(l, i, j):
...     if r[0, i, j] != 0 or \
...        r[1, i, j] != 0 or \
...        r[2, i, j] != 0:
...         if i < j:
...             i, j = j, i
...         if magnetic_states[j].f == 1 and l == 0:
...             return 1.0
...         if magnetic_states[j].f == 2 and l == 1:
...             return 1.0
...         else:
...             return 0.0
...     else:
...         return 0.0
>>> xi = np.array([[[coupled2(l, i, j)
...                for j in range(Ne)] for i in range(Ne)]
...                for l in range(Nl)])
>>> phase = phase_transformation(Ne, Nl, rm, xi, return_equations=False)
>>> detuning_knob = [fast.symbols("delta"+str(i+1)) for i in range(Nl)]
>>> hamiltonian = fast_hamiltonian(E0, epsilonp, detuning_knob, rm,
...                                omega_level, xi, phase)
>>> detuning_knob = [0.0, 0.0]
>>> print hamiltonian(detuning_knob)/hbar_num/2/np.pi*1e-6
[[   0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    1.74562297+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    1.35215374+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
    -1.56133265+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    1.56133265+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j   -1.74562297+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    1.35215374+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   0.00000000+0.j    0.00000000+0.j    0.00000000+0.j   72.22180189+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     1.56133265+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    1.56133265+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
    72.22180189+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j   -0.60470154+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.78066633+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    1.97494695+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j   72.22180189+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j   -0.69824919+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     2.09474757+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j   72.22180189+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j   -0.60470154+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j   -0.78066633+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    1.97494695+0.j    0.00000000+0.j    0.00000000+0.j]
 [   0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j   72.22180189+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
    -1.56133265+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    1.56133265+0.j    0.00000000+0.j]
 [   0.00000000+0.j   -1.56133265+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   1.74562297+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
    -0.60470154+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j   72.22180189+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j   -0.69824919+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j   72.22180189+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   0.00000000+0.j    0.00000000+0.j   -1.74562297+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j   -0.60470154+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j   72.22180189+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    1.56133265+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
   229.16195450+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   1.35215374+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.78066633+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j  229.16195450+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   0.00000000+0.j    1.56133265+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j  229.16195450+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   0.00000000+0.j    0.00000000+0.j    1.35215374+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j   -0.78066633+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j  229.16195450+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j   -1.56133265+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
   229.16195450+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    1.56133265+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     1.97494695+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    2.09474757+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    1.97494695+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    1.56133265+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]
 [   0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j
     0.00000000+0.j    0.00000000+0.j    0.00000000+0.j    0.00000000+0.j]]
fast.bloch.define_simplification(omega_level, xi, Nl)

Return a simplifying function, its inverse, and simplified frequencies.

This implements an index iu that labels energies in a non-degenerate way.

>>> Ne = 6
>>> Nl = 2
>>> omega_level = [0.0, 100.0, 100.0, 200.0, 200.0, 300.0]
>>> xi = np.zeros((Nl, Ne, Ne))
>>> coup = [[(1, 0), (2, 0)], [(3, 0), (4, 0), (5, 0)]]
>>> for l in range(Nl):
...     for pair in coup[l]:
...         xi[l, pair[0], pair[1]] = 1.0
...         xi[l, pair[1], pair[0]] = 1.0
>>> aux = define_simplification(omega_level, xi, Nl)
>>> u, invu, omega_levelu, Neu, xiu = aux
>>> print omega_levelu
[0.0, 100.0, 200.0, 300.0]
>>> print Neu
4
>>> print xiu
[[[ 0.  1.  0.  0.]
  [ 1.  0.  0.  0.]
  [ 0.  0.  0.  0.]
  [ 0.  0.  0.  0.]]

 [[ 0.  0.  1.  1.]
  [ 0.  0.  0.  0.]
  [ 1.  0.  0.  0.]
  [ 1.  0.  0.  0.]]]
fast.bloch.detunings_code(Neu, Nl, pairs, omega_levelu, iu0, ju0)

Get the code to calculate the simplified detunings.

>>> Ne = 6
>>> Nl = 2
>>> omega_level = [0.0, 100.0, 100.0, 200.0, 200.0, 300.0]
>>> xi = np.zeros((Nl, Ne, Ne))
>>> coup = [[(1, 0), (2, 0)], [(3, 0), (4, 0), (5, 0)]]
>>> for l in range(Nl):
...     for pair in coup[l]:
...         xi[l, pair[0], pair[1]] = 1.0
...         xi[l, pair[1], pair[0]] = 1.0
>>> aux = define_simplification(omega_level, xi, Nl)
>>> u, invu, omega_levelu, Neu, xiu = aux
>>> omega_min, iu0, ju0 = find_omega_min(omega_levelu, Neu, Nl, xiu)
>>> pairs = detunings_indices(Neu, Nl, xiu)
>>> print detunings_code(Neu, Nl, pairs, omega_levelu, iu0, ju0)
    delta1_2_1 = detuning_knob[0]
    delta2_3_1 = detuning_knob[1]
    delta2_4_1 = detuning_knob[1] + (-100.0)
fast.bloch.detunings_combinations(pairs)

Return all combinations of detunings.

>>> Ne = 6
>>> Nl = 2
>>> omega_level = [0.0, 100.0, 100.0, 200.0, 200.0, 300.0]
>>> xi = np.zeros((Nl, Ne, Ne))
>>> coup = [[(1, 0), (2, 0)], [(3, 0), (4, 0), (5, 0)]]
>>> for l in range(Nl):
...     for pair in coup[l]:
...         xi[l, pair[0], pair[1]] = 1.0
...         xi[l, pair[1], pair[0]] = 1.0
>>> aux = define_simplification(omega_level, xi, Nl)
>>> u, invu, omega_levelu, Neu, xiu = aux
>>> pairs = detunings_indices(Neu, Nl, xiu)
>>> detunings_combinations(pairs)
[[(1, 0), (2, 0)], [(1, 0), (3, 0)]]
fast.bloch.detunings_indices(Neu, Nl, xiu)

Get the indices of the transitions of all fields.

They are returned in the form [[(i1, j1), (i2, j2)], …,[(i1, j1)]]. that is, one list of pairs of indices for each field.

>>> Ne = 6
>>> Nl = 2
>>> omega_level = [0.0, 100.0, 100.0, 200.0, 200.0, 300.0]
>>> xi = np.zeros((Nl, Ne, Ne))
>>> coup = [[(1, 0), (2, 0)], [(3, 0), (4, 0), (5, 0)]]
>>> for l in range(Nl):
...     for pair in coup[l]:
...         xi[l, pair[0], pair[1]] = 1.0
...         xi[l, pair[1], pair[0]] = 1.0
>>> aux = define_simplification(omega_level, xi, Nl)
>>> u, invu, omega_levelu, Neu, xiu = aux
>>> detunings_indices(Neu, Nl, xiu)
[[(1, 0)], [(2, 0), (3, 0)]]
fast.bloch.detunings_rewrite(expr, combs, omega_laser, symb_omega_levelu, omega_levelu, iu0, ju0)

Rewrite a symbolic expression in terms of allowed transition detunings.

>>> Ne = 6
>>> Nl = 2
>>> omega_level = [0.0, 100.0, 100.0, 200.0, 200.0, 300.0]
>>> xi = np.zeros((Nl, Ne, Ne))
>>> coup = [[(1, 0), (2, 0)], [(3, 0), (4, 0), (5, 0)]]
>>> for l in range(Nl):
...     for pair in coup[l]:
...         xi[l, pair[0], pair[1]] = 1.0
...         xi[l, pair[1], pair[0]] = 1.0
>>> aux = define_simplification(omega_level, xi, Nl)
>>> u, invu, omega_levelu, Neu, xiu = aux
>>> omega_min, iu0, ju0 = find_omega_min(omega_levelu, Neu, Nl, xiu)
>>> pairs = detunings_indices(Neu, Nl, xiu)
>>> combs = detunings_combinations(pairs)
>>> symb_omega_levelu, omega, gamma = define_frequencies(Neu)
>>> E0, omega_laser = define_laser_variables(Nl)

Most times it is possible to express these combinations of optical frequencies in terms of allowed transition detunings.

>>> expr = +(omega_laser[0]-(symb_omega_levelu[1]-symb_omega_levelu[0]))
>>> expr += -(omega_laser[1]-(symb_omega_levelu[3]-symb_omega_levelu[0]))
>>> expr
-omega_2 + omega_4 + varpi_1 - varpi_2
>>> detunings_rewrite(expr, combs, omega_laser, symb_omega_levelu,
...                   omega_levelu, iu0, ju0)
'+delta1_2_1-delta2_4_1'

But some times it is not possible:

>>> expr = +(omega_laser[1]-(symb_omega_levelu[1]-symb_omega_levelu[0]))
>>> expr += -(omega_laser[0]-(symb_omega_levelu[3]-symb_omega_levelu[0]))
>>> expr
-omega_2 + omega_4 - varpi_1 + varpi_2
>>> detunings_rewrite(expr, combs, omega_laser, symb_omega_levelu,
...                   omega_levelu, iu0, ju0)
'-detuning_knob[0]+detuning_knob[1]'
fast.bloch.fast_hamiltonian(Ep, epsilonp, detuning_knob, rm, omega_level, xi, theta, file_name=None)

Return a fast function that returns a Hamiltonian as a numerical array.

INPUT:

  • Ep - A list with the electric field amplitudes (real or complex).
  • epsilonp - A list of the polarization vectors of the fields

(real or complex). - detuning_knob - A list of the detunings of each field (relative to the transition of lowest energy). - rm - The below-diagonal components

of the position operator in the cartesian basis:

\[\vec{r}^{(-)}_{i j} = [ x_{ij}, y_{ij}, z_{ij} ] \hspace{1cm} \forall \hspace{1cm} 0 < j < i\]
  • omega_level - The angular frequencies of each state.
  • xi - An array whose xi[l, i, j] element is 1 if the
transition \(|i\rangle \rightarrow |j\rangle\)is driven by field l and 0 otherwise.
  • theta - A list of symbolic expressions representing a phase

transformation. - file_name - A string indicating a file to save the function’s code.

If the arguments Ep, epsilonp, and detuning_knob are symbolic amounts, the returned function will accept numeric values of Ep, epsilonp, and detuning_knob as arguments.

All quantities should be in SI units.

EXAMPLES:

We build an example using states coupled like this:

|4> — |5> — |6>
^ ^ ^ | | | | — |2> | — |3> |
2 | ^ 2 | ^ | 2
1 | | 1 | |
| | | |

————————————- |1>

With the numbers on kets labeling states and the plain numbers labeling fields.

The number of states and fields: >>> Ne = 6 >>> Nl = 2

We invent some energy levels: >>> omega_level = np.array([0.0, 100.0, 100.0, 200.0, 200.0, 300.0]) >>> omega_level = omega_level*1e6*2*np.pi

We build the symbol xi, that chooses which laser couples which transition. >>> xi = np.zeros((Nl, Ne, Ne)) >>> coup = [[(1, 0), (2, 0)], [(3, 0), (4, 0), (5, 0)]] >>> for l in range(Nl): … for pair in coup[l]: … xi[l, pair[0], pair[1]] = 1.0 … xi[l, pair[1], pair[0]] = 1.0

We invent some electric dipole matrix elements: >>> from scipy.constants import physical_constants >>> a0 = physical_constants[“Bohr radius”][0] >>> rm = np.zeros((3, Ne, Ne)) >>> for l in range(Nl): … for i in range(Ne): … for j in range(i): … if xi[l, i, j] != 0: … rm[2, i, j] = float(i)*a0

The phase transformation: >>> theta = phase_transformation(Ne, Nl, rm, xi)

We define the possible arguments: >>> from sympy import symbols, pi >>> from fast.symbolic import polarization_vector >>> detuning_knob = symbols(“delta1 delta2”) >>> detuning_knob_vals = np.array([-1.0, 3.0])*1e6*2*np.pi

>>> Ep, omega_laser = define_laser_variables(Nl)
>>> Ep_vals = [1e2, 1e2]
>>> alpha = symbols("alpha")
>>> epsilon = polarization_vector(0, pi/2, alpha, 0, 1)
>>> epsilonp = [epsilon, epsilon]
>>> epsilonp_vals = [[0.0, 0.0, 1.0], [0.0, 0.0, 1.0]]

There are 8 ways to call fast_hamiltonian:

1 .- Get a function of detunings, field amplitudes, polarizations: >>> H1 = fast_hamiltonian(Ep, epsilonp, detuning_knob, rm, … omega_level, xi, theta)

2 .- Get a function of field amplitudes, polarizations: >>> H2 = fast_hamiltonian(Ep, epsilonp, detuning_knob_vals, rm, … omega_level, xi, theta)

3 .- Get a function of detunings, polarizations: >>> H3 = fast_hamiltonian(Ep_vals, epsilonp, detuning_knob, rm, … omega_level, xi, theta)

4 .- Get a function of detunings, field amplitudes: >>> H4 = fast_hamiltonian(Ep, epsilonp_vals, detuning_knob, rm, … omega_level, xi, theta)

5 .- Get a function of detunings: >>> H5 = fast_hamiltonian(Ep_vals, epsilonp_vals, detuning_knob, rm, … omega_level, xi, theta)

6 .- Get a function of field amplitudes: >>> H6 = fast_hamiltonian(Ep, epsilonp_vals, detuning_knob_vals, rm, … omega_level, xi, theta)

7 .- Get a function of polarizations: >>> H7 = fast_hamiltonian(Ep_vals, epsilonp, detuning_knob_vals, rm, … omega_level, xi, theta)

8 .- Get a function of nothing: >>> H8 = fast_hamiltonian(Ep_vals, epsilonp_vals, detuning_knob_vals, rm, … omega_level, xi, theta)

We test all of these combinations. >>> print H1(Ep_vals, epsilonp_vals, detuning_knob_vals) … /hbar_num/2/np.pi*1e-6 [[ 0.00000000+0.j 0.63977241+0.j 1.27954481+0.j 1.91931722+0.j

2.55908963+0.j 3.19886203+0.j]
[ 0.63977241+0.j 1.00000000+0.j 0.00000000+0.j 0.00000000+0.j
0.00000000+0.j 0.00000000+0.j]
[ 1.27954481+0.j 0.00000000+0.j 1.00000000+0.j 0.00000000+0.j
0.00000000+0.j 0.00000000+0.j]
[ 1.91931722+0.j 0.00000000+0.j 0.00000000+0.j -3.00000000+0.j
0.00000000+0.j 0.00000000+0.j]
[ 2.55908963+0.j 0.00000000+0.j 0.00000000+0.j 0.00000000+0.j
-3.00000000+0.j 0.00000000+0.j]
[ 3.19886203+0.j 0.00000000+0.j 0.00000000+0.j 0.00000000+0.j
0.00000000+0.j 97.00000000+0.j]]
>>> print H2(Ep_vals, epsilonp_vals)/hbar_num/2/np.pi*1e-6
[[  0.00000000+0.j   0.63977241+0.j   1.27954481+0.j   1.91931722+0.j
    2.55908963+0.j   3.19886203+0.j]
 [  0.63977241+0.j   1.00000000+0.j   0.00000000+0.j   0.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  1.27954481+0.j   0.00000000+0.j   1.00000000+0.j   0.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  1.91931722+0.j   0.00000000+0.j   0.00000000+0.j  -3.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  2.55908963+0.j   0.00000000+0.j   0.00000000+0.j   0.00000000+0.j
   -3.00000000+0.j   0.00000000+0.j]
 [  3.19886203+0.j   0.00000000+0.j   0.00000000+0.j   0.00000000+0.j
    0.00000000+0.j  97.00000000+0.j]]
>>> print H3(epsilonp_vals, detuning_knob_vals)/hbar_num/2/np.pi*1e-6
[[  0.00000000+0.j   0.63977241+0.j   1.27954481+0.j   1.91931722+0.j
    2.55908963+0.j   3.19886203+0.j]
 [  0.63977241+0.j   1.00000000+0.j   0.00000000+0.j   0.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  1.27954481+0.j   0.00000000+0.j   1.00000000+0.j   0.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  1.91931722+0.j   0.00000000+0.j   0.00000000+0.j  -3.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  2.55908963+0.j   0.00000000+0.j   0.00000000+0.j   0.00000000+0.j
   -3.00000000+0.j   0.00000000+0.j]
 [  3.19886203+0.j   0.00000000+0.j   0.00000000+0.j   0.00000000+0.j
    0.00000000+0.j  97.00000000+0.j]]
>>> print H4(Ep_vals, detuning_knob_vals)/hbar_num/2/np.pi*1e-6
[[  0.00000000+0.j   0.63977241+0.j   1.27954481+0.j   1.91931722+0.j
    2.55908963+0.j   3.19886203+0.j]
 [  0.63977241+0.j   1.00000000+0.j   0.00000000+0.j   0.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  1.27954481+0.j   0.00000000+0.j   1.00000000+0.j   0.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  1.91931722+0.j   0.00000000+0.j   0.00000000+0.j  -3.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  2.55908963+0.j   0.00000000+0.j   0.00000000+0.j   0.00000000+0.j
   -3.00000000+0.j   0.00000000+0.j]
 [  3.19886203+0.j   0.00000000+0.j   0.00000000+0.j   0.00000000+0.j
    0.00000000+0.j  97.00000000+0.j]]
>>> print H5(detuning_knob_vals)/hbar_num/2/np.pi*1e-6
[[  0.00000000+0.j   0.63977241+0.j   1.27954481+0.j   1.91931722+0.j
    2.55908963+0.j   3.19886203+0.j]
 [  0.63977241+0.j   1.00000000+0.j   0.00000000+0.j   0.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  1.27954481+0.j   0.00000000+0.j   1.00000000+0.j   0.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  1.91931722+0.j   0.00000000+0.j   0.00000000+0.j  -3.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  2.55908963+0.j   0.00000000+0.j   0.00000000+0.j   0.00000000+0.j
   -3.00000000+0.j   0.00000000+0.j]
 [  3.19886203+0.j   0.00000000+0.j   0.00000000+0.j   0.00000000+0.j
    0.00000000+0.j  97.00000000+0.j]]
>>> print H6(Ep_vals)/hbar_num/2/np.pi*1e-6
[[  0.00000000+0.j   0.63977241+0.j   1.27954481+0.j   1.91931722+0.j
    2.55908963+0.j   3.19886203+0.j]
 [  0.63977241+0.j   1.00000000+0.j   0.00000000+0.j   0.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  1.27954481+0.j   0.00000000+0.j   1.00000000+0.j   0.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  1.91931722+0.j   0.00000000+0.j   0.00000000+0.j  -3.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  2.55908963+0.j   0.00000000+0.j   0.00000000+0.j   0.00000000+0.j
   -3.00000000+0.j   0.00000000+0.j]
 [  3.19886203+0.j   0.00000000+0.j   0.00000000+0.j   0.00000000+0.j
    0.00000000+0.j  97.00000000+0.j]]
>>> print H7(epsilonp_vals)/hbar_num/2/np.pi*1e-6
[[  0.00000000+0.j   0.63977241+0.j   1.27954481+0.j   1.91931722+0.j
    2.55908963+0.j   3.19886203+0.j]
 [  0.63977241+0.j   1.00000000+0.j   0.00000000+0.j   0.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  1.27954481+0.j   0.00000000+0.j   1.00000000+0.j   0.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  1.91931722+0.j   0.00000000+0.j   0.00000000+0.j  -3.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  2.55908963+0.j   0.00000000+0.j   0.00000000+0.j   0.00000000+0.j
   -3.00000000+0.j   0.00000000+0.j]
 [  3.19886203+0.j   0.00000000+0.j   0.00000000+0.j   0.00000000+0.j
    0.00000000+0.j  97.00000000+0.j]]
>>> print H8()/hbar_num/2/np.pi*1e-6
[[  0.00000000+0.j   0.63977241+0.j   1.27954481+0.j   1.91931722+0.j
    2.55908963+0.j   3.19886203+0.j]
 [  0.63977241+0.j   1.00000000+0.j   0.00000000+0.j   0.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  1.27954481+0.j   0.00000000+0.j   1.00000000+0.j   0.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  1.91931722+0.j   0.00000000+0.j   0.00000000+0.j  -3.00000000+0.j
    0.00000000+0.j   0.00000000+0.j]
 [  2.55908963+0.j   0.00000000+0.j   0.00000000+0.j   0.00000000+0.j
   -3.00000000+0.j   0.00000000+0.j]
 [  3.19886203+0.j   0.00000000+0.j   0.00000000+0.j   0.00000000+0.j
    0.00000000+0.j  97.00000000+0.j]]
fast.bloch.find_omega_min(omega_levelu, Neu, Nl, xiu)

Find the smallest transition frequency for each field.

>>> Ne = 6
>>> Nl = 2
>>> omega_level = [0.0, 100.0, 100.0, 200.0, 200.0, 300.0]
>>> xi = np.zeros((Nl, Ne, Ne))
>>> coup = [[(1, 0), (2, 0)], [(3, 0), (4, 0), (5, 0)]]
>>> for l in range(Nl):
...     for pair in coup[l]:
...         xi[l, pair[0], pair[1]] = 1.0
...         xi[l, pair[1], pair[0]] = 1.0
>>> aux = define_simplification(omega_level, xi, Nl)
>>> u, invu, omega_levelu, Neu, xiu = aux
>>> find_omega_min(omega_levelu, Neu, Nl, xiu)
([100.0, 200.0], [1, 2], [0, 0])
fast.bloch.phase_transformation(Ne, Nl, rm, xi, return_equations=False)

Returns a phase transformation theta_i.

The phase transformation is defined in a way such that
theta1 + omega_level1 = 0.
>>> xi = np.zeros((1, 2, 2))
>>> xi[0, 1, 0] = 1.0
>>> xi[0, 0, 1] = 1.0
>>> rm = np.zeros((3, 2, 2))
>>> rm[0, 1, 0] = 1.0
>>> rm[1, 1, 0] = 1.0
>>> rm[2, 1, 0] = 1.0
>>> phase_transformation(2, 1, rm, xi)
[-omega_1, -omega_1 - varpi_1]
fast.bloch.vectorization(Ne, Nv=1, real=False, lower_triangular=True, normalized=False)

Return functions to map matrix element indices to vectorized indices.

This function returns a function Mu that takes a pair of indices i, j spanning Ne states, and returns an index mu spanning the elements of the vectorized density matrix. If complex=True.

>>> def test_vectorization(Ne, Nv, real=False,
...                        lower_triangular=True, normalized=False):
...
...     Mu, IJ = vectorization(Ne, Nv, real, lower_triangular, normalized)
...     if normalized:
...         j0 = 1
...     else:
...         j0 = 0
...     for k in range(Nv):
...         for j in range(j0, Ne):
...             if real:
...                 muu = Mu(1, j, j, k)
...                 ss, ii, jj, kk = IJ(muu)
...                 print j, j, muu, j-ii, j-jj, k-kk, 1-ss
...             else:
...                 muu = Mu(j, j, k)
...                 ii, jj, kk = IJ(muu)
...                 print j, j, muu, j-ii, j-jj, k-kk
...         for j in range(Ne):
...             for i in range(j+1, Ne):
...                 if real:
...                     muu = Mu(1, i, j, k)
...                     ss, ii, jj, kk = IJ(muu)
...                     print i, j, muu, i-ii, j-jj, k-kk, 1-ss
...                     muu = Mu(-1, i, j, k)
...                     ss, ii, jj, kk = IJ(muu)
...                     print i, j, muu, i-ii, j-jj, k-kk, -1-ss
...                 else:
...                     muu = Mu(i, j, k)
...                     ii, jj, kk = IJ(muu)
...                     print i, j, muu, i-ii, j-jj, k-kk
...                 if not lower_triangular:
...                     if real:
...                         muu = Mu(1, j, i, k)
...                         ss, ii, jj, kk = IJ(muu)
...                         print j, i, muu, j-ii, i-jj, k-kk, 1-ss
...                         muu = Mu(-1, j, i, k)
...                         ss, ii, jj, kk = IJ(muu)
...                         print j, i, muu, j-ii, i-jj, k-kk, -1-ss
...                     else:
...                         muu = Mu(j, i, k)
...                         ii, jj, kk = IJ(muu)
...                         print i, j, muu, j-ii, i-jj, k-kk
...
>>> Ne = 3
>>> Nv = 3
>>> test_vectorization(Ne, Nv, False, False, False)
0 0 0 0 0 0
1 1 1 0 0 0
2 2 2 0 0 0
1 0 3 0 0 0
1 0 4 0 0 0
2 0 5 0 0 0
2 0 6 0 0 0
2 1 7 0 0 0
2 1 8 0 0 0
0 0 9 0 0 0
1 1 10 0 0 0
2 2 11 0 0 0
1 0 12 0 0 0
1 0 13 0 0 0
2 0 14 0 0 0
2 0 15 0 0 0
2 1 16 0 0 0
2 1 17 0 0 0
0 0 18 0 0 0
1 1 19 0 0 0
2 2 20 0 0 0
1 0 21 0 0 0
1 0 22 0 0 0
2 0 23 0 0 0
2 0 24 0 0 0
2 1 25 0 0 0
2 1 26 0 0 0
>>> test_vectorization(Ne, Nv, False, False, True)
1 1 0 0 0 0
2 2 1 0 0 0
1 0 2 0 0 0
1 0 3 0 0 0
2 0 4 0 0 0
2 0 5 0 0 0
2 1 6 0 0 0
2 1 7 0 0 0
1 1 8 0 0 0
2 2 9 0 0 0
1 0 10 0 0 0
1 0 11 0 0 0
2 0 12 0 0 0
2 0 13 0 0 0
2 1 14 0 0 0
2 1 15 0 0 0
1 1 16 0 0 0
2 2 17 0 0 0
1 0 18 0 0 0
1 0 19 0 0 0
2 0 20 0 0 0
2 0 21 0 0 0
2 1 22 0 0 0
2 1 23 0 0 0
>>> test_vectorization(Ne, Nv, False, True, False)
0 0 0 0 0 0
1 1 1 0 0 0
2 2 2 0 0 0
1 0 3 0 0 0
2 0 4 0 0 0
2 1 5 0 0 0
0 0 6 0 0 0
1 1 7 0 0 0
2 2 8 0 0 0
1 0 9 0 0 0
2 0 10 0 0 0
2 1 11 0 0 0
0 0 12 0 0 0
1 1 13 0 0 0
2 2 14 0 0 0
1 0 15 0 0 0
2 0 16 0 0 0
2 1 17 0 0 0
>>> test_vectorization(Ne, Nv, False, True, True)
1 1 0 0 0 0
2 2 1 0 0 0
1 0 2 0 0 0
2 0 3 0 0 0
2 1 4 0 0 0
1 1 5 0 0 0
2 2 6 0 0 0
1 0 7 0 0 0
2 0 8 0 0 0
2 1 9 0 0 0
1 1 10 0 0 0
2 2 11 0 0 0
1 0 12 0 0 0
2 0 13 0 0 0
2 1 14 0 0 0
>>> test_vectorization(Ne, Nv, True, False, False)
0 0 0 0 0 0 0
1 1 1 0 0 0 0
2 2 2 0 0 0 0
1 0 3 0 0 0 0
1 0 4 0 0 0 0
0 1 5 0 0 0 0
0 1 6 0 0 0 0
2 0 7 0 0 0 0
2 0 8 0 0 0 0
0 2 9 0 0 0 0
0 2 10 0 0 0 0
2 1 11 0 0 0 0
2 1 12 0 0 0 0
1 2 13 0 0 0 0
1 2 14 0 0 0 0
0 0 15 0 0 0 0
1 1 16 0 0 0 0
2 2 17 0 0 0 0
1 0 18 0 0 0 0
1 0 19 0 0 0 0
0 1 20 0 0 0 0
0 1 21 0 0 0 0
2 0 22 0 0 0 0
2 0 23 0 0 0 0
0 2 24 0 0 0 0
0 2 25 0 0 0 0
2 1 26 0 0 0 0
2 1 27 0 0 0 0
1 2 28 0 0 0 0
1 2 29 0 0 0 0
0 0 30 0 0 0 0
1 1 31 0 0 0 0
2 2 32 0 0 0 0
1 0 33 0 0 0 0
1 0 34 0 0 0 0
0 1 35 0 0 0 0
0 1 36 0 0 0 0
2 0 37 0 0 0 0
2 0 38 0 0 0 0
0 2 39 0 0 0 0
0 2 40 0 0 0 0
2 1 41 0 0 0 0
2 1 42 0 0 0 0
1 2 43 0 0 0 0
1 2 44 0 0 0 0
>>> test_vectorization(Ne, Nv, True, False, True)
1 1 0 0 0 0 0
2 2 1 0 0 0 0
1 0 2 0 0 0 0
1 0 3 0 0 0 0
0 1 4 0 0 0 0
0 1 5 0 0 0 0
2 0 6 0 0 0 0
2 0 7 0 0 0 0
0 2 8 0 0 0 0
0 2 9 0 0 0 0
2 1 10 0 0 0 0
2 1 11 0 0 0 0
1 2 12 0 0 0 0
1 2 13 0 0 0 0
1 1 14 0 0 0 0
2 2 15 0 0 0 0
1 0 16 0 0 0 0
1 0 17 0 0 0 0
0 1 18 0 0 0 0
0 1 19 0 0 0 0
2 0 20 0 0 0 0
2 0 21 0 0 0 0
0 2 22 0 0 0 0
0 2 23 0 0 0 0
2 1 24 0 0 0 0
2 1 25 0 0 0 0
1 2 26 0 0 0 0
1 2 27 0 0 0 0
1 1 28 0 0 0 0
2 2 29 0 0 0 0
1 0 30 0 0 0 0
1 0 31 0 0 0 0
0 1 32 0 0 0 0
0 1 33 0 0 0 0
2 0 34 0 0 0 0
2 0 35 0 0 0 0
0 2 36 0 0 0 0
0 2 37 0 0 0 0
2 1 38 0 0 0 0
2 1 39 0 0 0 0
1 2 40 0 0 0 0
1 2 41 0 0 0 0
>>> test_vectorization(Ne, Nv, True, True, False)
0 0 0 0 0 0 0
1 1 1 0 0 0 0
2 2 2 0 0 0 0
1 0 3 0 0 0 0
1 0 4 0 0 0 0
2 0 5 0 0 0 0
2 0 6 0 0 0 0
2 1 7 0 0 0 0
2 1 8 0 0 0 0
0 0 9 0 0 0 0
1 1 10 0 0 0 0
2 2 11 0 0 0 0
1 0 12 0 0 0 0
1 0 13 0 0 0 0
2 0 14 0 0 0 0
2 0 15 0 0 0 0
2 1 16 0 0 0 0
2 1 17 0 0 0 0
0 0 18 0 0 0 0
1 1 19 0 0 0 0
2 2 20 0 0 0 0
1 0 21 0 0 0 0
1 0 22 0 0 0 0
2 0 23 0 0 0 0
2 0 24 0 0 0 0
2 1 25 0 0 0 0
2 1 26 0 0 0 0
>>> test_vectorization(Ne, Nv, True, True, True)
1 1 0 0 0 0 0
2 2 1 0 0 0 0
1 0 2 0 0 0 0
1 0 3 0 0 0 0
2 0 4 0 0 0 0
2 0 5 0 0 0 0
2 1 6 0 0 0 0
2 1 7 0 0 0 0
1 1 8 0 0 0 0
2 2 9 0 0 0 0
1 0 10 0 0 0 0
1 0 11 0 0 0 0
2 0 12 0 0 0 0
2 0 13 0 0 0 0
2 1 14 0 0 0 0
2 1 15 0 0 0 0
1 1 16 0 0 0 0
2 2 17 0 0 0 0
1 0 18 0 0 0 0
1 0 19 0 0 0 0
2 0 20 0 0 0 0
2 0 21 0 0 0 0
2 1 22 0 0 0 0
2 1 23 0 0 0 0