def test_single_symplectic(i, n):
    """
    Tests a single symplectic matrix
    """
    M = symplectic.symplectic(i, n)
    L = symplectic.get_lambda(n)
    result = (M.T @ L @ M) % 2
    result = ((result == L).all())
    return result
예제 #2
0
def store_all_two_qubit_gates():
    m = 2
    qubit_gates = dict()
    qubit_matrices = dict()

    for i in range(symplectic.numberofsymplectic(m)):
        S = symplectic.symplectic(i, m)
        S = decompose.transform_symplectic(S)
        gates = decompose.decompose_state(chp_py.CHP_Simulation(m, S))
        qubit_gates[i] = gates
        qubit_matrices[i] = S

    save_data(qubit_gates, "two_qubit_gates")
    save_data(qubit_matrices, "two_qubit_matrices")
def test_collision_probability():
    """
    Test cases for the collision probability algorithm
    Returns True if passed all test cases, otherwise returns False
    """
    print("Testing: collision probability algorithm")
    # n = number of qubits, m = size of qubit gate
    for n in range(1, 10):
        # sim1 is fast and sim2 is slow, as sim2 uses exponential
        # storage and runtime
        sim1 = chp_py.CHP_Simulation(n)
        sim2 = slow_sim.Slow_Simulation(n)

        for m in range(1, min(n, 5)):
            for j in range(100):
                # Get a random symplectic of size 2m x 2m
                i = np.random.randint(symplectic.numberofsymplectic(m))
                S = symplectic.symplectic(i, m)
                S = decompose.transform_symplectic(S)

                # Get m random qubits
                qubits = np.arange(m)
                np.random.shuffle(qubits)
                qubits = qubits[:m]

                # Get the gates and matrix represention of S
                gates = decompose.decompose_state(chp_py.CHP_Simulation(m, S))
                gates = decompose.change_gates(gates, qubits)

                decompose.apply_gates(gates, sim1)
                decompose.apply_gates(gates, sim2)

                k_1 = int(-sim1.log_collision_probability)
                k_2 = np.round(-np.log2(sim2.collision_probability))
                result = (k_1 == k_2)

                if not result:
                    print("Failed: collision probability algorithm returned " +
                          "incorrect result with n = " + str(n) + " and m = " +
                          str(m))
                    return False

    print("Passed: collision probability algorithm passed all tests\n")
    return True
def test_chp_py():
    """
    Test cases for the functions in chp_py.py
    Returns True if passed all test cases, otherwise returns False
    """
    print("Testing: chp_py.py")
    # n = number of qubits, m = size of qubit gate
    for n in range(1, 50):
        # Create two simulations
        # sim1 uses decomposed gates and sim2 uses matrix multiplication
        # apply 100 random gates to each one
        sim1 = chp_py.CHP_Simulation(n)
        sim2 = chp_py.CHP_Simulation(n)

        for m in range(1, min(n, 5)):
            for j in range(100):
                # Get a random symplectic of size 2m x 2m
                i = np.random.randint(symplectic.numberofsymplectic(m))
                S = symplectic.symplectic(i, m)
                S = decompose.transform_symplectic(S)

                # Get m random qubits
                qubits = np.arange(m)
                np.random.shuffle(qubits)
                qubits = qubits[:m]

                # Get the gates and matrix represention of S
                gates = decompose.decompose_state(chp_py.CHP_Simulation(m, S))
                gates = decompose.change_gates(gates, qubits)
                M = decompose.symplectic_to_matrix(S, n, qubits)

                sim1.apply_gates(gates)
                sim2.state = (sim2.state @ M) % 2
                result = (sim1.state == sim2.state).all()

                if not result:
                    print("Failed: found two simulations with different " +
                          "states for n = " + str(n))
                    return False

    print("Passed: chp_py.py passed all tests\n")
    return True
    def apply_random_symplectic(self, qubits):
        """
        Generates a random symplectic gate and then applies it
        to the qubits in the list qubits
        """
        # Here m is the number of qubits that the gate will be applied to
        # while n is the total number of qubits in the simulation
        m = len(qubits)

        # Generate a random symplectic matrix that is
        # symplectic with L = direct_sum_{j=1}^n X
        i = np.random.randint(symplectic.numberofsymplectic(m))
        S = symplectic.symplectic(i, m)

        # Convert this symplectic matrix to one that is symplectic
        # with L = [[0, I], [I, 0]]
        S = decompose.transform_symplectic(S)

        # Lastly, apply this to our state
        self.apply_symplectic(S, qubits)
def test_decompose():
    """
    Test cases for the functions in decompose.py
    Returns True if passed all test cases, otherwise returns False
    """
    print("Testing: decompose.py")

    for n in range(1, 6):
        top = np.hstack((np.zeros((n, n)), np.identity(n)))
        bottom = np.hstack((np.identity(n), np.zeros((n, n))))
        L = np.vstack((top, bottom))

        for j in range(500):
            # Get a random symplectic
            i = np.random.randint(symplectic.numberofsymplectic(n))
            S = symplectic.symplectic(i, n)
            S = decompose.transform_symplectic(S)

            # Make sure the transformation worked
            result = (S.T @ L @ S) % 2
            result = ((result == L).all())
            if not result:
                print("Failed: could not transform symplectic " +
                      "matrix with (n, i)= " + str((n, i)))
                return False

            # Make sure we can decompose it
            # Applying the decomposed gates to the identity should give us S
            gates = decompose.decompose_state(chp_py.CHP_Simulation(n, S))
            new_sim = chp_py.CHP_Simulation(n)
            new_sim.apply_gates(gates)
            result = (new_sim.state == S).all()

            if not result:
                print("Failed: found a bad decomposition for " +
                      "symplectic matrix with (n, i)= " + str((n, i)))
                return False

    print("Passed: decompose.py passed all tests\n")
    return True
예제 #7
0
def trajectory(n,duration,pos,ang,burn,x0,y0,px0,py0):
    """Integrate trajectory for the reduced 3-body problem.

    Args:
        n (int): Positions stored.
        duration (float): Time duration of simulation.
        x0 (float): Initial x-coordinate
        y0 (float): Initial y-coordinate
        px0 (float): Initial generalized x-momentum
        py0 (float): Initial generalized y-momentum

    Returns:
        Tuple of time-, x-, y-, px- and py lists.
    
    """
    print("# Running trajectory.")

    # Initialize arrays
    tlist = np.linspace(0,duration,n)
    xlist = np.zeros(n)
    ylist = np.zeros(n)
    pxlist = np.zeros(n)
    pylist = np.zeros(n)
    errlist = np.zeros(n)
    hlist = np.zeros(n)
    info = np.zeros(2)

    # Find orbits
    runtime = time.time()
    status = symplectic(n,duration,x0,y0,px0,py0,xlist,ylist,pxlist,pylist,errlist,hlist,info)
    runtime = time.time()-runtime

    # Display result
    print_search_results(status,pos,ang,burn,x0,y0,px0,py0,info[0],info[1])
    print("# Runtime = %3.2fs" % (runtime))
    return tlist,xlist,ylist,pxlist,pylist,errlist,hlist
예제 #8
0
from symplectic import symplectic
import matplotlib.pyplot as plt
from poincare import hh_sos
import numpy as np

H = lambda q, p: .5 * (np.dot(q, q) + np.dot(p, p)) + (q[0]**2) * q[1] - (
    1 / 3) * q[1]**3

dHdp = lambda p: p
dHdq = lambda q: q + np.array([2 * q[0] * q[1], q[0]**2 - q[1]**2])

fig2 = symplectic(dHdq, [0.12, 0.12], [0.12, 0.12])
# fig3 = symplectic(dHdq, [0.0, 0.0], [np.sqrt(2*0.1592), 0.0], tf=10000)
fig3c = symplectic(dHdq, [0.0, 0.0], [np.sqrt(2 * 0.1592), 0.0])
fig4 = symplectic(dHdq, [0.0, 0.0], [np.sqrt(2 * 0.11783), 0.0])
fig4b = symplectic(dHdq, [0.0, 0.0], [np.sqrt(2 * 0.117835), 0.0])

qp = np.array([next(fig2) for _ in range(1000000)])
# np.save("fig2_oneside.npy", qp)
q, p = hh_sos(qp[:, 0], qp[:, 1])
plt.scatter(q, p, marker=".")
plt.title("Fig 3c")
plt.show()
예제 #9
0
def hohmann(threads,n):
    """Finding Hohmann trajectory for the reduced 3-body problem.

    Args:
        n (int): Positions stored.

    Returns:
        Tuple of time-, x-, y-, px- and py lists.
    
    """

    print("# Running Hohmann.")

    # Hohmann trajectory < 6 days
    duration = 6/unit_time
    best_total_dv = 1e9
    positions = 100
    angles = 1
    burns = 200
    pos = -3*pi/4
    ang = 0
    burn = 3.11/unit_vel # Forward Hohmann
    #burn_low = -3.14/unit_vel # Reverse Hohmann

    # Super fast Hohmann trajectory < 1 days
    #duration = 3/unit_time
    #best_total_dv = 1e9
    #positions = 10
    #angles = 10
    #burns = 200
    #pos = -3*pi/4
    #ang = 0
    #burn = 3.7/unit_vel # Forward Hohmann

    pos_range = pi/4
    ang_range = pi/8
    burn_range = 0.1/unit_vel

    # Start search
    searches = 0
    max_searches = 5
    while searches < max_searches:
        runtime = time.time()
        searches += 1
        print("############## Search %i ###############" % (searches))
        print("# pos              = %f" % (pos))
        print("# ang              = %f" % (ang))
        print("# burn             = %f" % (burn))
        pos_low = pos-pos_range
        pos_high = pos+pos_range
        ang_low = ang-ang_range
        ang_high = ang+ang_range
        burn_low = burn-burn_range
        burn_high = burn+burn_range
        stat,pos,ang,burn,x0,y0,px0,py0,dv,toa = search_mt(threads,1,duration,positions,angles,burns,pos_low,pos_high,ang_low,ang_high,burn_low,burn_high)

        if stat < 0:
            total_dv = abs(burn)+dv
            if best_total_dv > total_dv:
                best_total_dv = total_dv
                best_stat = stat
                best_pos = pos
                best_ang = ang
                best_burn = burn
                best_x0 = x0
                best_y0 = y0
                best_px0 = px0
                best_py0 = py0
                best_dv = dv
                best_toa = toa
            else:
                break

        pos_range *= 0.1
        ang_range *= 0.1
        burn_range *= 0.1

        runtime = time.time()-runtime
        print("# Search runtime   = %3.2fs" % (runtime))

    # Print best result
    print("################ Best ################")
    print("# Best dV(total)   = %f km/s" % (best_total_dv*unit_vel))
    print_search_results(best_stat,best_pos,best_ang,best_burn,best_x0,best_y0,best_px0,best_py0,best_dv,best_toa)

    # Initialize arrays
    tlist = np.linspace(0,duration,n)
    xlist = np.zeros(n)
    ylist = np.zeros(n)
    pxlist = np.zeros(n)
    pylist = np.zeros(n)
    errlist = np.zeros(n)
    hlist = np.zeros(n)
    info = np.zeros(2)

    # Do trajectory
    duration = 10/unit_time
    status = symplectic(n,duration,x0,y0,px0,py0,xlist,ylist,pxlist,pylist,errlist,hlist,info)

    return tlist,xlist,ylist,pxlist,pylist,errlist,hlist
예제 #10
0
def refine(threads,n,duration,pos,ang,burn,x0,y0,px0,py0):
    """Integrate trajectory for the reduced 3-body problem.

    Args:
        n (int): Positions stored.
        duration (float): Time duration of simulation.
        x0 (float): Initial x-coordinate
        y0 (float): Initial y-coordinate
        px0 (float): Initial generalized x-momentum
        py0 (float): Initial generalized y-momentum

    Returns:
        Tuple of time-, x-, y-, px- and py lists.
    
    """
    print("# Running refine.")

    # Low-energy-long trajectory < 200 days
    #duration = 200/unit_time
    # Low-energy-short trajectory < 47 days
    #duration = 47/unit_time
    best_total_dv = 1e9
    best_toa = 0
    positions = 15
    angles = 15
    burns = 15

    # Divide circular earth orbit into 8 parts
    pos_range = 2*pi/16*0.1
    ang_range = pi/100*0.1
    burn_range = 0.1/unit_vel*0.1
    
    # Start search
    searches = 0
    max_searches = 10
    while searches < max_searches:
        runtime = time.time()
        searches += 1
        print("############## Search %i ###############" % (searches))
        print("# pos              = %f" % (pos))
        print("# ang              = %f" % (ang))
        print("# burn             = %f" % (burn))
        pos_low = pos-pos_range
        pos_high = pos+pos_range
        ang_low = ang-ang_range
        ang_high = ang+ang_range
        burn_low = burn-burn_range
        burn_high = burn+burn_range
        stat,pos,ang,burn,x0,y0,px0,py0,dv,toa = search_mt(threads,1,duration,positions,angles,burns,pos_low,pos_high,ang_low,ang_high,burn_low,burn_high)

        if stat < 0:
            total_dv = abs(burn)+dv
            if best_total_dv > total_dv:
                best_total_dv = total_dv
                best_stat = stat
                best_pos = pos
                best_ang = ang
                best_burn = burn
                best_x0 = x0
                best_y0 = y0
                best_px0 = px0
                best_py0 = py0
                best_dv = dv
                best_toa = toa
            else:
                break
            
        pos_range *= 0.1
        ang_range *= 0.1
        burn_range *= 0.1

        runtime = time.time()-runtime
        print("# Search runtime   = %3.2fs" % (runtime))

    # Print best result
    print("################ Best ################")
    print("# Best dV(total)   = %f km/s" % (best_total_dv*unit_vel))
    print_search_results(best_stat,best_pos,best_ang,best_burn,best_x0,best_y0,best_px0,best_py0,best_dv,best_toa)

    # Initialize arrays
    tlist = np.linspace(0,duration,n)
    xlist = np.zeros(n)
    ylist = np.zeros(n)
    pxlist = np.zeros(n)
    pylist = np.zeros(n)
    errlist = np.zeros(n)
    hlist = np.zeros(n)
    info = np.zeros(2)

    # Do trajectory
    duration = toa+(2.0*pi*lunar_orbit/lunar_orbit_vel)/(unit_time*day)
    status = symplectic(n,duration,x0,y0,px0,py0,xlist,ylist,pxlist,pylist,errlist,hlist,info)
    #exit()
    return tlist,xlist,ylist,pxlist,pylist,errlist,hlist
예제 #11
0
def low_energy_parts8(threads,n):
    """Finding low energy transfer trajectory for the reduced 3-body problem.

    Args:
        n (int): Positions stored.

    Returns:
        Tuple of time-, x-, y-, px- and py lists.
    
    """

    print("# Running low_energy_parts8.")

    # Low-energy-short trajectory < 47 days
    duration = 200/unit_time
    best_total_dv = 1e9
    best_toa = 0
    positions = 55
    angles = 1
    burns = 55

    # Divide circular earth orbit into 8 parts
    for i in range(0,8):
        pos = i*pi/4
        ang = 0
        #burn = 3.12/unit_vel # moon
        burn = 3.09/unit_vel # L1
        pos_range = 2*pi/16
        ang_range = pi/2
        burn_range = 0.1/unit_vel
    
        # Start search
        searches = 0
        max_searches = 3
        while searches < max_searches:
            runtime = time.time()
            searches += 1
            print("############## Search %i ###############" % (searches))
            print("# pos              = %f" % (pos))
            print("# ang              = %f" % (ang))
            print("# burn             = %f" % (burn))
            pos_low = pos-pos_range
            pos_high = pos+pos_range
            ang_low = ang-ang_range
            ang_high = ang+ang_range
            burn_low = burn-burn_range
            burn_high = burn+burn_range
            stat,pos,ang,burn,x0,y0,px0,py0,dv,toa = search_mt(threads,1,duration,positions,angles,burns,pos_low,pos_high,ang_low,ang_high,burn_low,burn_high)

            if stat < 0:
                total_dv = abs(burn)+dv
                if best_total_dv > total_dv:
                    best_total_dv = total_dv
                    best_stat = stat
                    best_pos = pos
                    best_ang = ang
                    best_burn = burn
                    best_x0 = x0
                    best_y0 = y0
                    best_px0 = px0
                    best_py0 = py0
                    best_dv = dv
                    best_toa = toa
                else:
                    break

            pos_range *= 0.1
            ang_range *= 0.1
            burn_range *= 0.1

            runtime = time.time()-runtime
            print("# Search runtime   = %3.2fs" % (runtime))

    # Print best result
    if best_total_dv < 1e9:
        print("################ Best ################")
        print("# Best dV(total)   = %f km/s" % (best_total_dv*unit_vel))
        print_search_results(best_stat,best_pos,best_ang,best_burn,best_x0,best_y0,best_px0,best_py0,best_dv,best_toa)

    # Initialize arrays
    tlist = np.linspace(0,duration,n)
    xlist = np.zeros(n)
    ylist = np.zeros(n)
    pxlist = np.zeros(n)
    pylist = np.zeros(n)
    errlist = np.zeros(n)
    hlist = np.zeros(n)
    info = np.zeros(2)

    # Do trajectory
    #duration = toa+(2.0*pi*lunar_orbit/lunar_orbit_vel)/(unit_time*day)
    status = symplectic(n,duration,x0,y0,px0,py0,xlist,ylist,pxlist,pylist,errlist,hlist,info)
    #exit()
    return tlist,xlist,ylist,pxlist,pylist,errlist,hlist
예제 #12
0
def low_energy(threads,n):
    """Finding low energy transfer trajectory for the reduced 3-body problem.

    Args:
        n (int): Positions stored.

    Returns:
        Tuple of time-, x-, y-, px- and py lists.
    
    """

    print("# Running low_energy.")

    # Low-energy trajectory < 200 days
    duration = 200/unit_time
    best_total_dv = 1e9
    positions = 100
    angles = 1
    burns = 200
    pos = -3*pi/4
    ang = 0
    burn = 3.12/unit_vel
    pos_range = pi
    ang_range = 0
    burn_range = 0.01/unit_vel

    # Start search
    searches = 0
    max_searches = 1
    while searches < max_searches:
        runtime = time.time()
        searches += 1
        print("############## Search %i ###############" % (searches))
        print("# pos              = %f" % (pos))
        print("# ang              = %f" % (ang))
        print("# burn             = %f" % (burn))
        pos_low = pos-pos_range
        pos_high = pos+pos_range
        ang_low = ang-ang_range
        ang_high = ang+ang_range
        burn_low = burn-burn_range
        burn_high = burn+burn_range
        stat,pos,ang,burn,x0,y0,px0,py0,dv,toa = search_mt(threads,1,duration,positions,angles,burns,pos_low,pos_high,ang_low,ang_high,burn_low,burn_high)

        if stat < 0:
            total_dv = abs(burn)+dv
            if best_total_dv > total_dv:
                best_total_dv = total_dv
                best_stat = stat
                best_pos = pos
                best_ang = ang
                best_burn = burn
                best_x0 = x0
                best_y0 = y0
                best_px0 = px0
                best_py0 = py0
                best_dv = dv
                best_toa = toa
            else:
                break

        pos_range *= 0.1
        ang_range *= 0.1
        burn_range *= 0.1

        runtime = time.time()-runtime
        print("# Search runtime   = %3.2fs" % (runtime))

    # Initialize arrays
    tlist = np.linspace(0,duration,n)
    xlist = np.zeros(n)
    ylist = np.zeros(n)
    pxlist = np.zeros(n)
    pylist = np.zeros(n)
    errlist = np.zeros(n)
    hlist = np.zeros(n)
    info = np.zeros(2)

    # Do trajectory
    duration = toa+(2.0*pi*lunar_orbit/lunar_orbit_vel)/(unit_time*day)
    status = symplectic(n,duration,x0,y0,px0,py0,xlist,ylist,pxlist,pylist,errlist,hlist,info)
    exit()
    return tlist,xlist,ylist,pxlist,pylist,errlist,hlist
예제 #13
0
from symplectic import symplectic, thirds, ab, fifth
import matplotlib.pyplot as plt
from poincare import poincare, hh_sos
import numpy as np

H = lambda q, p: .5 * (np.dot(q, q) + np.dot(p, p)) + (q[0]**2) * q[1] - (
    1 / 3) * q[1]**3

dHdp = lambda p: p
dHdq = lambda q: q + np.array([2 * q[0] * q[1], q[0]**2 - q[1]**2])

for E in np.linspace(1 / 12, 1 / 6, 10):
    gen = symplectic(dHdq, [0.0, 0.0], [np.sqrt(2 * E), 0.0])
    qp = np.array([next(gen) for _ in range(50000)])
    q, p = hh_sos(qp[:, 0], qp[:, 1])
    plt.scatter(q, p, marker=".", label=f"{E}")
plt.legend()
plt.show()
예제 #14
0
파일: search.py 프로젝트: gandalfsaxe/leto
def search(thread, threads, n, duration, positions, angles, burns):

    #print("Start thread=%i" % (thread))

    # Initialize arrays
    xlist = np.zeros(n)
    ylist = np.zeros(n)
    pxlist = np.zeros(n)
    pylist = np.zeros(n)
    errlist = np.zeros(n)
    hlist = np.zeros(n)
    info = np.zeros(2)

    # Search for orbits
    trials = len(positions) * len(angles) * len(burns)
    ld1 = len(angles) * len(burns)
    ld2 = len(burns)
    trial = 0
    hit_earth = 0
    hit_moon = 0
    best_status = 1e9
    progress = -1
    i = thread
    while i < trials:

        # One-to-one mapping of i -> (pos_i,ang_i,burn_i)
        pos_i = i // ld1
        ang_i = (i - pos_i * ld1) // ld2
        burn_i = i - pos_i * ld1 - ang_i * ld2
        i += threads

        # Find launch setup
        pos = positions[pos_i]
        ang = angles[ang_i]
        burn = burns[burn_i]

        # Calculate initial conditions
        r = leo_orbit / unit_len
        x0 = np.cos(pos) * r
        y0 = np.sin(pos) * r
        rx = -y0 / r
        ry = x0 / r
        vx = (leo_orbit_vel / unit_vel) * rx
        vy = (leo_orbit_vel / unit_vel) * ry
        x0 += earth_pos_x
        bx = np.cos(ang) * rx - np.sin(ang) * ry
        by = np.sin(ang) * rx + np.cos(ang) * ry
        px0 = (
            burn / abs(burn)
        ) * vx + burn * bx - y0  # Sign of burn decides rotational direction of launch
        py0 = (burn / abs(burn)) * vy + burn * by + x0

        # Call symplectic integration
        # status > 0     : Closest distance to moon achieved
        # status < 0     : Hit the moon using status=dV(moon)-10000 to get into orbit
        # status == 100  : Collided with earth
        #if thread == 1:
        #    print(n,duration,x0,y0,px0,py0)
        status = symplectic(n, duration, x0, y0, px0, py0, xlist, ylist,
                            pxlist, pylist, errlist, hlist, info)
        if status == 100:
            hit_earth += 1
        if status < 0:
            hit_moon += 1
        if status < best_status:
            best_status = status
            best_pos = pos
            best_ang = ang
            best_burn = burn
            best_x0 = x0
            best_y0 = y0
            best_px0 = px0
            best_py0 = py0
            best_dv = info[0]
            best_toa = info[1]

        # Show progress
        if thread == 0:  # only thread 0
            if (100 * trial / (1 + trials // threads)) // 10 > progress:
                progress = (100 * trial / (1 + trials // threads)) // 10
                print(progress * 10, end="% ")
                sys.stdout.flush()
            trial += 1
        #if thread == 13:
        #   print("thread=%i status=%f best_status=%f trial=%i(%i) pos=%f ang=%f burn=%f" % (thread,status,best_status,trial,trials,pos,ang,burn))

    #print("End thread=%i" % (thread))

    return best_status, best_pos, best_ang, best_burn, best_x0, best_y0, best_px0, best_py0, best_dv, best_toa, hit_earth, hit_moon