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 componentsof 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 whosexi[l, i, j]
element is 1 if the
transition \(|i\rangle \rightarrow |j\rangle\)is driven by fieldl
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:
- 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