Exemple #1
0
    def test_poorly_conditioned(self):
        """ Testing against a single poorly-conditioned matrix.
        Generated as a random 6x6 array, and then divided the first row and column by 1e6
        """
        mat = np.array([[
            6.6683264e-07, 6.3376014e-07, 4.5754601e-07, 7.1252750e-07,
            7.5942456e-07, 5.9028134e-07
        ],
                        [
                            5.7484930e-07, 6.5606222e-01, 6.5073522e-01,
                            2.4251825e-01, 1.0735555e-01, 2.6956707e-01
                        ],
                        [
                            6.1098206e-07, 4.0445840e-01, 5.6152644e-01,
                            5.8278476e-01, 8.0418942e-01, 7.7306821e-01
                        ],
                        [
                            8.5656473e-07, 4.3833014e-01, 5.7838875e-01,
                            2.4317287e-01, 1.6641302e-01, 3.9590950e-01
                        ],
                        [
                            4.4858020e-07, 1.1731434e-01, 7.3598305e-01,
                            4.5670520e-01, 5.8185932e-01, 9.4438709e-01
                        ],
                        [
                            4.1073805e-07, 9.6286350e-02, 7.7365790e-01,
                            1.3120009e-01, 9.3908360e-01, 1.4665616e-01
                        ]])

        phi = expm(mat)
        out_scipy = expm_scipy(mat)
        assert_arrays_equal(out_scipy, phi, decimal=8)
def passwordAttack(e, n):
    N = buildPassTable(e, n)
    for weakPass in D:
        ePass = expm(weakPass, e, n)
        if ePass in N.keys():
            print("Match! Name: {}, Password: {}".format(
                N[ePass][0], weakPass))
Exemple #3
0
 def test_expm_one_large_element(self):
     """ one value slightly swamping the rest """
     a = np.array(
         [[0.1, 0.02, 0.003], [1.875, 0.12, 0.11], [0.1234567, 0, 0.3]],
         dtype=np.float64)
     phi = expm(a)
     out_scipy = expm_scipy(a)
     assert_arrays_equal(out_scipy, phi, decimal=12)
Exemple #4
0
 def test_expm_one_huge_element(self):
     """ one value swamping the rest """
     a = np.array(
         [[999.875, 0.2, 0.3], [0.1, 0.002, 0.001], [0.01, 0, -0.003]],
         dtype=np.float64)
     phi = expm(a)
     out_scipy = expm_scipy(a)
     assert_arrays_equal(out_scipy, phi, decimal=12)
Exemple #5
0
 def test_expm_nearly_identity(self):
     """ nearly the identity matrix """
     a = np.array(
         [[1.0012, 0, 0.0003], [0.0075, 0.9876543, 0.0011], [0, 0, 0.9873]],
         dtype=np.float64)
     phi = expm(a)
     out_scipy = expm_scipy(a)
     assert_arrays_equal(out_scipy, phi, decimal=12)
Exemple #6
0
 def initRho(self, trotter_order=2):
     tau, device, dtype, model = self.params[
         -1], self.device, self.dtype, self.model
     #print("Generate initial rho({}) via Trotter decomp.\n".format(tau))
     if trotter_order == 1:
         # get Hamiltonian
         H = self.getHamilton()
         # local trotter gate
         rho = expm(-tau * H).view(2, 2, 2, 2)
         rho = torch.einsum('ijkl->ikjl', rho).contiguous().view(4, 4)
         # svd & truncate the 0 values
         U, S, V = torch.svd(rho)
         # trotter gate in form of two tensor contraction
         hl = (U @ torch.diag(torch.sqrt(S))).view(2, 2, 4)
         hr = (V @ torch.diag(torch.sqrt(S))).view(2, 2, 4)
         # local tensor of initial mpo, index order: [l,r,d,u]
         Ta = torch.tensordot(hr, hl, ([0], [1])).permute(1, 3, 2,
                                                          0).contiguous()
         Tb = torch.tensordot(hr, hl, ([1], [0])).permute(1, 3, 0,
                                                          2).contiguous()
     elif trotter_order == 2:
         # get Hamiltonian
         H = self.getHamilton()
         # local trotter gate
         rho = expm(-tau * H).view(2, 2, 2, 2)
         rho = torch.einsum('ijkl->ikjl', rho).contiguous().view(4, 4)
         # half local trotter gate
         rho_half = expm(-tau * H / 2).view(2, 2, 2, 2)
         rho_half = torch.einsum('ijkl->ikjl',
                                 rho_half).contiguous().view(4, 4)
         # svd
         U, S, V = torch.svd(rho)
         U2, S2, V2 = torch.svd(rho_half)
         # trotter gate in form of two tensor contraction
         hl = (U @ torch.diag(torch.sqrt(S))).view(2, 2, 4)
         hr = (V @ torch.diag(torch.sqrt(S))).view(2, 2, 4)
         hl2 = (U2 @ torch.diag(torch.sqrt(S2))).view(2, 2, 4)
         hr2 = (V2 @ torch.diag(torch.sqrt(S2))).view(2, 2, 4)
         # local tensor of initial mpo, index order: [l,r,d,u]
         Ta = torch.einsum('ijk,jlm,lno->okmin', hr2, hl,
                           hr2).contiguous().view(16, 4, 2, 2)
         Tb = torch.einsum('ijk,jlm,lno->mokin', hl2, hr,
                           hl2).contiguous().view(4, 16, 2, 2)
     else:
         raise Exception('only 1st and 2nd trotter are available!')
     return Ta, Tb
Exemple #7
0
 def test_expm_random_non_zero_floats(self):
     """ arbitrarily large values, and some negatives """
     a = np.array([[99.23452, 2.0000234523, 0.0003, 378.2362],
                   [1.00001, 8754.236, 1.1007, 33.333333],
                   [111, 0.00034, 3922.323, -999.333],
                   [-1234.5678, -0.00034, 333.65, 13]],
                  dtype=np.float64)
     phi = expm(a)
     out_scipy = expm_scipy(a)
     assert_arrays_equal(out_scipy, phi, decimal=12)
 def compute(self,A,h=1):
     if not type(A) is np.ndarray:
         raise TypeError('Pade approximation only supports type(A) == np.ndarray')
     if self.CppFlag:
         import expmat as e
         self.expA = np.zeros_like(A)
         e.expmc(h*A,self.expA)
     else:
         from scipy.linalg import expm
         self.expA = expm(A)
     return self.expA
Exemple #9
0
    def test_expm_random_sparse(self):
        """ Testing against a large set of random 2D matricies with defined sparsity
        """
        np.random.seed(7)

        for size in range(5, 40):
            for d in [x / 100 for x in range(10, 90)]:
                mat = sparse.random(size, size, density=d).toarray()
                phi = expm(mat)
                out_scipy = expm_scipy(mat)
                assert_arrays_equal(out_scipy, phi, decimal=7)
Exemple #10
0
 def compute(self,A,h=1):
     if not type(A) is np.ndarray:
         raise TypeError('Pade approximation only supports type(A) == np.ndarray')
     try:
         from expm import expm
     except ImportError:
         # use scipy implementation as fallback
         print "ImportError generated when trying to import function 'expm' from module 'expm'!"
         print "using scipy.linalg.expm instead"
         from scipy.linalg import expm
     self.expA = expm(h*A)
     return self.expA
Exemple #11
0
def default_expectation_value(ham,
                              t,
                              state,
                              log_file="qmla_log.log",
                              log_identifier="Expecation Value"):
    """
    Default probability calculation: | <state.transpose | e^{-iHt} | state> |**2

    Returns the expectation value computed by evolving the input state with
        the provided Hamiltonian operator.

    :param np.array ham: Hamiltonian needed for the time-evolution
    :param float t: Evolution time
    :param np.array state: Initial state to evolve and measure on
    :param str log_file: (optional) path of the log file
    :param str log_identifier: (optional) identifier for the log

    :return: probability of measuring the input state after Hamiltonian evolution
    """

    probe_bra = state.conj().T
    u = expm(-1j * ham * t)
    # h = hexp.LinalgUnitaryEvolvingMatrix(
    #     ham,
    #     evolution_time = t,
    # )
    # u = h.expm()

    # h = hexp.UnitaryEvolvingMatrix(
    #     ham,
    #     evolution_time = t,
    # )
    # u = h.expm()

    u_psi = np.dot(u, state)
    expectation_value = np.dot(probe_bra, u_psi)  # in general a complex number
    prob_of_measuring_input_state = np.abs(expectation_value)**2

    # check that probability is reasonable (0 <= P <= 1)
    ex_val_tol = 1e-9
    if prob_of_measuring_input_state > (
            1 + ex_val_tol) or prob_of_measuring_input_state < (0 -
                                                                ex_val_tol):
        log_print(
            [
                "prob_of_measuring_input_state > 1 or < 0 (={}) at t={}\n Probe={}"
                .format(prob_of_measuring_input_state, t, repr(state))
            ],
            log_file=log_file,
            log_identifier=log_identifier,
        )
        raise NameError("Unphysical expectation value")
    return prob_of_measuring_input_state
Exemple #12
0
 def apply(self,v,A=None,h=1):
     T = v.dtype
     nrm = np.linalg.norm(v)
     v = v/nrm
     n = np.max(v.shape)
     from expint.util import arnoldi
     from scipy.linalg import expm
     V = np.zeros((n,self.k), dtype=T)
     H = np.zeros((self.k+1,self.k), dtype=T)
     V,H = arnoldi(A,v,self.k)
     result = nrm*np.dot(V,expm(h*H[:self.k,:self.k])[:,0])
     result.shape = (max(result.shape),1)
     return result
Exemple #13
0
 def apply(self,v,A=None,h=1):
     nrm = np.linalg.norm(v)
     v = v/nrm
     if self.CppFlag:
         from expint.lib.carnoldi import arnoldi
         V,H = arnoldi(A,v,self.k)
     else:
         from expint.util import arnoldi
         V,H = arnoldi(A,v,self.k)
     
     from scipy.linalg import expm
     result = nrm*np.dot(V,expm(h*H[:self.k,:self.k])[:,0])
     result.shape = (max(result.shape),1)
     return result
def buildPassTable(e, n):
    infile = open('passwords.txt')
    records = infile.readlines()
    infile.close()

    N = {}
    for record in records:
        record = record[1:-2]  #remove ( and )
        (name, salt, spwd) = record.split(',')
        salt, spwd = eval(salt), eval(spwd)
        eSalt = expm(salt, e, n)
        invSalt = inv(eSalt, n)
        key = (spwd * invSalt) % n
        N[key] = (name, salt)
    return N
def make_inversion_gate(num_qubits):
    r"""
    returns the inversion gate for the Hahn eco evolution as numpy array

    :parameter num_qubits: size of the inversion gate required

    :output : inversion gate
    """
    from scipy import linalg
    sigma_z = np.array([[1 + 0.j, 0 + 0.j], [0 + 0.j, -1 + 0.j]])
    hahn_angle = np.pi / 2
    hahn_gate = np.kron(hahn_angle * sigma_z, np.eye(2**(num_qubits - 1)))
    # inversion_gate = qutip.Qobj(-1.0j * hahn_gate).expm().full()
    inversion_gate = expm(-1j * hahn_gate)

    return inversion_gate
Exemple #16
0
def random_initialised_qubit_for_hahn_sequence(
    hahn_rotation = None
):
    pauli_y = np.array([
        [0,-1j], 
        [1j, 0]
    ])
    spin_qubit = np.array([1,0]) # prepared in |0>
    if hahn_rotation is None: 
        hahn_rotation = np.random.uniform(-1, 1)
    hahn_angle = hahn_rotation*(np.pi/2)

    hahn_gate = expm(
        -1j * hahn_angle * pauli_y
    )

    spin_qubit = np.dot(hahn_gate, spin_qubit)
    return spin_qubit
Exemple #17
0
def n_qubit_hahn_evolution(
    ham,
    t,
    state,
    second_time_evolution_factor=1,
    pi_rotation="y",
    precision=1e-10,
    log_file=None,
    log_identifier=None,
):
    r"""
    n qubits time evolution for Hahn-echo measurement returning measurement probability for input state

    :param ham: Hamiltonian needed for the time-evolution
    :type ham: np.array()
    :param t: Evolution time
    :type t: float()
    :param state: Initial state to evolve and measure on
    :type state: float()
    :param precision: (optional) chosen precision for expectation value, default 1e-10
    :type precision: float()
    :param log_file: (optional) path of the log file for logging errors
    :type log_file: str()
    :param log_identifier: (optional) identifier for the log
    :type log_identifier: str()

    :output: probability of measuring input state after time t
    """

    import numpy as np
    import qmla.model_building_utilities
    from scipy import linalg

    num_qubits = int(np.log2(np.shape(ham)[0]))

    if pi_rotation == "y":
        from qmla.shared_functionality.hahn_y_gates import (
            precomputed_hahn_y_inversion_gates, )

        inversion_gate = precomputed_hahn_y_inversion_gates[num_qubits]
    elif pi_rotation == "z":
        from qmla.shared_functionality.hahn_inversion_gates import (
            precomputed_hahn_z_inversion_gates, )

        inversion_gate = precomputed_hahn_z_inversion_gates[num_qubits]

    # inversion_gate = make_inversion_gate_rotate_y(num_qubits)

    # want to evolve for t, then apply Hahn inversion gate,
    # then again evolution for (S * t)
    # where S = 2 in standard Hahn evolution,
    # S = 1 for long time dynamics study
    first_unitary_time_evolution = expm(-1j * ham * t)
    second_unitary_time_evolution = np.linalg.matrix_power(
        first_unitary_time_evolution, second_time_evolution_factor)

    total_evolution = np.dot(
        second_unitary_time_evolution,
        np.dot(inversion_gate, first_unitary_time_evolution),
    )

    ev_state = np.dot(total_evolution, state)
    nm = np.linalg.norm(ev_state)
    if np.abs(1 - nm) > 1e-5:
        print(
            "\n\n[n qubit Hahn]\n norm ev state:",
            nm,
            "\nt=",
            t,
            "\nprobe=",
            repr(state),
        )
        print("\nev state:\n", repr(ev_state))
        print("\nham:\n", repr(ham))
        print("\nHam element[0,2]:\n", ham[0][2])
        print("\ntotal evolution:\n", repr(total_evolution))
        print("\nfirst unitary:\n", first_unitary_time_evolution)
        print("\nsecond unitary:\n", second_unitary_time_evolution)
        print("\ninversion_gate:\n", inversion_gate)

    density_matrix = np.kron(ev_state, (ev_state.T).conj())
    dim_hilbert_space = 2**num_qubits
    density_matrix = np.reshape(density_matrix,
                                [dim_hilbert_space, dim_hilbert_space])

    # qdm = qutip.Qobj(density_matrix, dims=[[2],[2]])
    # reduced_matrix_qutip = qdm.ptrace(0).full()

    # below methods give different results for reduced_matrix
    # reduced_matrix = qdm.ptrace(0).full()

    to_trace = list(range(num_qubits - 1))
    reduced_matrix = partial_trace(density_matrix, to_trace)

    density_mtx_initial_state = np.kron(state, state.conj())

    density_mtx_initial_state = np.reshape(
        density_mtx_initial_state, [dim_hilbert_space, dim_hilbert_space])
    reduced_density_mtx_initial_state = partial_trace(
        density_mtx_initial_state, to_trace)
    projection_onto_initial_den_mtx = np.dot(reduced_density_mtx_initial_state,
                                             reduced_matrix)
    expect_value = np.abs(np.trace(projection_onto_initial_den_mtx))

    # expect_value is projection onto |+>
    # for this case Pr(0) refers to projection onto |->
    # so return 1 - expect_value
    likelihood = 1 - expect_value

    if likelihood > 1 or likelihood < 0:
        print("Unphysical expectation value:", likelihood)

    return likelihood
Exemple #18
0
from expm import expm
from scipy.linalg import expm as lexpm

num_iterations = 100
t_expm = 0
t_lexpm = 0

for i in range(num_iterations):

    model_params = {
        'FH-hopping-sum_up_1h2_1h3_2h4_3h4_d4': np.random.uniform(0, 1),
        'FH-onsite-sum_1_2_3_4_d4': np.random.uniform(0, 1),
        'FH-hopping-sum_down_1h2_1h3_2h4_3h4_d4': np.random.uniform(0, 1)
    }
    model = sum([
        model_params[term] * qmla.model_building_utilities.compute(term)
        for term in model_params
    ])

    t = np.random.uniform(0, 100)
    start_expm = time.time()
    u = expm(-1j * model * t)
    t_expm += time.time() - start_expm

    start_lexpm = time.time()
    u = lexpm(-1j * model * t)
    t_lexpm += time.time() - start_expm

print("Total times taken:\n \texpm={} \n\tlexpm={} \n\tSpeedup={}".format(
    np.round(t_expm, 2), np.round(t_lexpm, 2), np.round(t_lexpm / t_expm, 2)))
Exemple #19
0
 def forward(ctx, A):
     B = expm(A)
     ctx.save_for_backward(A, B)
     return B
Exemple #20
0
def hahn_evolution(ham,
                   t,
                   state,
                   precision=1e-10,
                   log_file=None,
                   log_identifier=None):
    r"""
    Hahn echo evolution and expectation value.

    Returns the expectation value computed by evolving the input state with
    the Hamiltonian corresponding to the Hahn eco evolution. NB: In this case, the assumption is that the
    value measured is 1 and the expectation value corresponds to the probability of
    obtaining 1.

    :param np.array ham: Hamiltonian needed for the time-evolution
    :param float t: Evolution time
    :param np.array state: Initial state to evolve and measure on
    :param float precision: precision required of the expectation value
        when using custom exponentiation function. TODO deprecated; remove
    :param str log_file: (optional) path of the log file
    :param str log_identifier: (optional) identifier for the log

    :return: expectation value of the evolved state

    """

    # NOTE this is always projecting onto |+>
    # okay for experimental data with spins in NV centre
    import numpy as np
    from scipy import linalg
    from qmla.shared_functionality.probe_set_generation import random_probe

    inversion_gate = np.array([
        [0.0 - 1.0j, 0.0 + 0.0j, 0.0 + 0.0j, 0.0 + 0.0j],
        [0.0 + 0.0j, 0.0 - 1.0j, 0.0 + 0.0j, 0.0 + 0.0j],
        [0.0 + 0.0j, 0.0 + 0.0j, 0.0 + 1.0j, 0.0 + 0.0j],
        [0.0 + 0.0j, 0.0 + 0.0j, 0.0 + 0.0j, 0.0 + 1.0j],
    ])

    # TODO Hahn gate here does not include pi/2 term
    # is it meant to???? as below
    # inversion_gate = inversion_gate * np.pi/2
    even_time_split = False
    if even_time_split:
        # unitary_time_evolution = h.exp_ham(
        #     ham,
        #     t,
        #     precision=precision
        # )
        unitary_time_evolution = (qutip.Qobj(-1j * ham * t).expm().full()
                                  )  # TODO deprecated

        total_evolution = np.dot(
            unitary_time_evolution,
            np.dot(inversion_gate, unitary_time_evolution))
    else:
        first_unitary_time_evolution = expm(-1j * ham * t)
        second_unitary_time_evolution = np.linalg.matrix_power(
            first_unitary_time_evolution, 2)

        total_evolution = np.dot(
            second_unitary_time_evolution,
            np.dot(inversion_gate, first_unitary_time_evolution),
        )

    #    print("total ev:\n", total_evolution)
    ev_state = np.dot(total_evolution, state)

    nm = np.linalg.norm(ev_state)
    if np.abs(1 - nm) > 1e-5:
        print("[hahn] norm ev state:", nm, "\t t=", t)
        raise NameError("Non-unit norm")

    density_matrix = np.kron(ev_state, (ev_state.T).conj())
    density_matrix = np.reshape(density_matrix, [4, 4])
    reduced_matrix = partial_trace_out_second_qubit(density_matrix,
                                                    qubits_to_trace=[1])

    plus_state = np.array([1, 1]) / np.sqrt(2)
    # from 1000 counts - Poissonian noise = 1/sqrt(1000) # should be ~0.03
    noise_level = 0.00

    random_noise = noise_level * random_probe(1)
    noisy_plus = plus_state + random_noise
    norm_factor = np.linalg.norm(noisy_plus)
    noisy_plus = noisy_plus / norm_factor
    bra = noisy_plus.conj().T

    rho_state = np.dot(reduced_matrix, noisy_plus)
    expect_value = np.abs(np.dot(bra, rho_state))
    #    print("Hahn. Time=",t, "\t ex = ", expect_value)
    # print("[Hahn evolution] projecting onto:", repr(bra))
    return 1 - expect_value  # because we actually project onto |-> in experiment
Exemple #21
0
     expA = zeros_like(A)
     
     t = time.time()
     e.expm(A,expA) # call C version with Eigen Pade approx.
     ctime = min(ctime, time.time()-t)
 
 # time scipy version
 for r in range(Preps):
     t = time.time()
     expA2 = expm(A)
     ptime = min(ptime, time.time()-t)
 
 # time new python version
 for r in range(P2reps):
     t = time.time()
     expA3 = e2.expm(A)
     p2time = min(p2time, time.time()-t)
 
 Tc.append(ctime)
 Tp.append(ptime)
 Tp2.append(p2time)
 speedup = ptime/p2time
 cpeedup = ptime/ctime
 print "C (Eigen): %1.4f"%ctime,"  scipy: %1.4f"%ptime,"  new python: %1.4f"%p2time,"  Python speedup: %1.4f, %1.1f%%"%(speedup,100*(speedup-1)/speedup),"  C++ speedup: %1.4f, %1.1f%%"%(cpeedup,100*(cpeedup-1)/cpeedup)
 
 normA = norm(expA-expA2)/norm(expA) # "relative" norm
 normA2 =norm(expA3-expA2)/norm(expA3) # "relative" norm
 epsilon = 1e-5
 if normA > epsilon or normA2 > epsilon:
     print "A-A2 or A3-A2 is not small (%f or %f > %f)!"%(normA,normA2,epsilon)
 del A, expA, expA2, expA3
Exemple #22
0
 def test_expm_random_integers(self):
     """ a simple, arbitrary matrix """
     a = np.array([[1, 2, 3], [1, 2, 1.1], [1, 0, 3]], dtype=np.float64)
     phi = expm(a)
     out_scipy = expm_scipy(a)
     assert_arrays_equal(out_scipy, phi, decimal=12)
Exemple #23
0
 def test_expm_all_ones(self):
     """ Test against a matrix of all ones """
     a = np.ones((33, 33), dtype='float64')
     phi = expm(a)
     out_scipy = expm_scipy(a)
     assert_arrays_equal(out_scipy, phi, decimal=12)
Exemple #24
0
 def test_expm_all_zeros(self):
     """ Test against a matrix of all zeros """
     a = np.zeros((20, 20), dtype='float32')
     phi = expm(a)
     out_scipy = expm_scipy(a)
     assert_arrays_equal(out_scipy, phi, decimal=12)
Exemple #25
0
 def test_expm_smallish_floats(self):
     """ This is just some arbitrary set of small-ish floats """
     a = np.arange(1, 17, dtype='float64').reshape(4, 4) / 1e3
     phi = expm(a)
     out_scipy = expm_scipy(a)
     assert_arrays_equal(out_scipy, phi, decimal=12)