Commit 1fa65dc3 authored by Paul's avatar Paul
Browse files

initial commit with python library code but no notebooks

parent 1cec4c48
Loading
Loading
Loading
Loading

Dockerfile

0 → 100644
+29 −0
Original line number Diff line number Diff line
from continuumio/miniconda3

run apt-get update

run apt-get -y install libboost-dev cmake cmake-curses-gui g++

run conda install -n base pip cython boost xarray dask netCDF4 bottleneck numpy pandas tqdm jupyterlab networkx matplotlib seaborn scipy \
    && /opt/conda/bin/pip install dwave-ocean-sdk dwave_networkx dwave-cloud-client

run echo 'export PYTHONPATH=${PYTHONPATH}:/home/python/' >> ~/.bashrc \
    && echo 'export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/opt/conda/lib/' >> ~/.bashrc \
    && echo 'source activate base' >> ~/.bashrc \
    && echo 'alias python=/opt/conda/bin/python' >> ~/.bashrc

run git clone https://github.com/rmcantin/bayesopt \
    && cd bayesopt/python/ && cython -3 --cplus bayesopt.pyx && cd .. \
    && cmake -DBAYESOPT_PYTHON_INTERFACE=ON -DPYTHON_LIBRARY=/opt/conda/lib/libpython3.7m.so -DPYTHON_INCLUDE_DIR=/opt/conda/include/python3.7m \
    && make && make install

run conda install -c conda-forge ipywidgets \
    && conda install nodejs

run jupyter labextension install @jupyter-widgets/jupyterlab-manager

run conda install -c conda-forge nlopt

run conda install -c conda-forge ffmpeg 

#CMD ["/bin/bash"]
+2 −2
Original line number Diff line number Diff line
# QA-SS
# Shastry-Sutherland Lattice Simulations on Quantum Hardware

Code to reproduce the results found in "Simulating the Shastry-Sutherland Ising Model using Quantum Annealing." Manuscript can be found at https://arxiv.org/abs/2003.01019. 
 No newline at end of file
Housing code to simulate the Shastry-Sutherland lattice on D-wave's quantum processor.

docker-compose.yml

0 → 100644
+14 −0
Original line number Diff line number Diff line
version: '2'

services:
  dwave-ss:
    image: dwave:latest
    command: "/bin/bash -c 'jupyter lab --no-browser --ip='0.0.0.0' --port=9000 --allow-root --notebook-dir=/home --NotebookApp.token=\"\"'"
    volumes:
      - ./:/home
      - /var/run/docker.sock:/var/run/docker.sock
      - ~/Research/dwave.conf:/root/.config/dwave/dwave.conf # Adding dwave config to container
    ports:
      - 9000:9000
    environment:
      - SHELL=/bin/bash
+345 −0
Original line number Diff line number Diff line
import numpy as np
import scipy as scp
import pandas as pd
import dwave_networkx as dnx
from itertools import product
from Utilities import *


def SS_correlations(logical_graph, corr_df):
    """
    Calculates the mean correlations between the physical qubits
    that represent logical qubits.
    """

    _qubits, _J1, _J2, _J3 = get_couplers_scales(logical_graph)

    dimer = pd.Series(index=corr_df.index)
    square = pd.Series(index=corr_df.index)
    qubit = pd.Series(index=corr_df.index)


    for idx, corr in corr_df.iterrows():
        # Get the average qubit correlations
        square[idx] = corr[_J1].mean()
        dimer[idx] = corr[_J2].mean()
        qubit[idx] = corr[_J3].mean()


    return qubit, dimer, square

def SS_core_correlations(logical_graph, corr_df, core_i_range=None, core_j_range=None):
    """
    Calculates the mean correlations between the physical qubits
    that represent logical qubits present in a given logical core region.
    """

    unit_cell_qubits = list(product(range(2), range(4)))  # To make sets
    core_region = list(product(core_i_range,core_j_range))

    core_qubits = [cell+qubit for qubit in unit_cell_qubits for cell in core_region]

    # Define the base (m x m) chimera graph and harwdware graph:
    cg = dnx.chimera_graph(16, coordinates=True)

    core_subgraph = cg.subgraph(core_qubits)
    core_edges = core_subgraph.edges(sorted(core_subgraph.nodes))
    core_edges = [linear_index_edge(e) for e in core_edges]

    core_corr_df = corr_df[[col for col in corr_df.columns if col in core_edges]]

    _qubits, _J1, _J2, _J3 = get_couplers_scales(logical_graph)

    core_J1 = {k:v for k,v in _J1.items() if k in core_edges}
    core_J2 = {k:v for k,v in _J2.items() if k in core_edges}
    core_J3 = {k:v for k,v in _J3.items() if k in core_edges}

    core_dimer = pd.Series(index=core_corr_df.index)
    core_square = pd.Series(index=core_corr_df.index)
    core_qubit = pd.Series(index=core_corr_df.index)


    for idx, corr in corr_df.iterrows():
        # Get the average qubit correlations
        core_square[idx] = corr[core_J1].mean()
        core_dimer[idx] = corr[core_J2].mean()
        core_qubit[idx] = corr[core_J3].mean()


    return core_qubit, core_dimer, core_square

def SS_core_magnetization(logical_graph, mag_df, core_i_range=None, core_j_range=None):
    """
    Calculates the mean magnetization in a given logical core region.
    """

    unit_cell_qubits = list(product(range(2), range(4)))  # To make sets
    core_region = list(product(core_i_range,core_j_range))

    core_qubits = [cell+qubit for qubit in unit_cell_qubits for cell in core_region]
    core_qubits = [linear_index_qubit(q) for q in core_qubits]
    core_mag_df = mag_df[[col for col in mag_df.columns if col in core_qubits]]


    return core_mag_df.mean(axis=1)


def get_structure_factor(logical_graph, solution_array, positions, q_range=(0,2*np.pi), num_q_points = 100, burn_in=0):
    """
    Calculates structure factor.

    Parameters
    ----------
    logical_graph : networkx.Graph
        The logical graph that encodes the embedding.

    solution_array : numpy.ndarray
        The raw solution vector

    positions : dict
        The positions of logical qubits in an embedding of the logical_graph in
        R^3.

    q_range : tuple (default (0,2*np.pi))
        The domain in q-space (a.k.a. k-space, recipricol space, fourier space)

    num_q_points : int (default 100)
        The mesh in q-space.

    burn_in : int (default 0)
        The burn_in number for quantum evolution monte carlo.

    Returns
    -------

    q1,q2 : np.ndarray
        The grid in q-space.

    Sq : np.ndarray
        The fourier amplitudes that represent the structure factor.

    """

    log_to_phys = {log: linear_index_qubit(phys) for log,data in logical_graph.nodes(data=True) for phys in data['physical'].nodes}
    log_to_phys_array = np.array([log_to_phys[l] for l in sorted(log_to_phys)])
    order = logical_graph.order()
    assert len(log_to_phys)==order
    ijs = np.array(list(product(range(logical_graph.order()), range(logical_graph.order()))))

    pos_array = np.array([positions[l] for l in sorted(positions)])

    ris = pos_array[ijs[:,0],:].T
    rjs = pos_array[ijs[:,1],:].T
    rijs = ris-rjs

    phys_is = log_to_phys_array[ijs[:,0]]
    phys_js = log_to_phys_array[ijs[:,1]]

    cij = np.zeros((len(ijs)))
    num_k = solution_array.shape[0]

    start = burn_in if burn_in else 0
    for k in range(num_k):
        cij[:] += np.mean(solution_array[k,-start:,phys_is]*solution_array[k,-start:,phys_js], axis=1)
    cij = cij/solution_array.shape[0]



    q_mesh = np.linspace(q_range[0],q_range[1], num_q_points)
    q1, q2 = np.meshgrid(q_mesh,q_mesh)
    qs = np.vstack((q1.flatten(),q2.flatten())).T
    Sq = np.zeros(num_q_points**2)

    #Sq = c_ft(qs, Sq, rijs,cij,order)
    for l,q in enumerate(qs):
        qdotr = np.dot(q,rijs)
        #Sq[l] = np.sum(cij*np.cos(qdotr))/emb.order()+1j*np.sum(cij*np.sin(qdotr))/emb.order()
        #Sq[l] = np.sum(cij*np.exp(1j*qdotr))
        Sq[l] = np.sum(cij*np.cos(qdotr))/order # The sin is an odd function so it will cancel itself out.

    Sq = Sq.reshape((num_q_points, num_q_points))

    return q1, q2, Sq



def get_structure_factor_slice(logical_graph, solution_array, positions, qx_range=(0,2*np.pi),qy_range=0, num_q_points = 100, burn_in=0):
    """
    Calculates structure factor.

    Parameters
    ----------
    logical_graph : networkx.Graph
        The logical graph that encodes the embedding.

    solution_array : numpy.ndarray
        The raw solution vector

    positions : dict
        The positions of logical qubits in an embedding of the logical_graph in
        R^3.
    
    qx_range : scalar or tuple (default (0,2*np.pi))
        The x domain in q-space (a.k.a. k-space, reciprical space, Fourier space)
        
    qy_range : scalar or tuple (default 0)
        The x domain in q-space (a.k.a. k-space, reciprical space, Fourier space)

    num_q_points : int (default 100)
        The mesh in q-space.

    burn_in : int (default 0)
        The burn_in number for quantum evolution monte carlo.

    Returns
    -------

    q1,q2 : np.ndarray
        The grid in q-space.

    Sq : np.ndarray
        The fourier amplitudes that represent the structure factor.

    """

    log_to_phys = {log: linear_index_qubit(phys) for log,data in logical_graph.nodes(data=True) for phys in data['physical'].nodes}
    log_to_phys_array = np.array([log_to_phys[l] for l in sorted(log_to_phys)])
    order = logical_graph.order()
    assert len(log_to_phys)==order
    ijs = np.array(list(product(range(logical_graph.order()), range(logical_graph.order()))))

    pos_array = np.array([positions[l] for l in sorted(positions)])

    ris = pos_array[ijs[:,0],:].T
    rjs = pos_array[ijs[:,1],:].T
    rijs = ris-rjs

    phys_is = log_to_phys_array[ijs[:,0]]
    phys_js = log_to_phys_array[ijs[:,1]]

    cij = np.zeros((len(ijs)))
    num_k = solution_array.shape[0]

    start = burn_in if burn_in else 0
    for k in range(num_k):
        cij[:] += np.mean(solution_array[k,-start:,phys_is]*solution_array[k,-start:,phys_js], axis=1)
    cij = cij/solution_array.shape[0]


    if type(qx_range) == tuple:
        qx_mesh = np.linspace(qx_range[0],qx_range[1], num_q_points)
        qs = np.array([[qx,qy_range] for qx in qx_mesh])
    else:
        qy_mesh = np.linspace(qy_range[0],qy_range[1], num_q_points)        
        qs = np.array([[qx_range,qy] for qy in qy_mesh])
        
    #q1, q2 = np.meshgrid(qx_mesh,qy_mesh)
    #qs = np.vstack((q1.flatten(),q2.flatten())).T
    Sq = np.zeros(num_q_points)
    #Sq = c_ft(qs, Sq, rijs,cij,order)
    for l,q in enumerate(qs):
        qdotr = np.dot(q,rijs)
        #Sq[l] = np.sum(cij*np.cos(qdotr))/emb.order()+1j*np.sum(cij*np.sin(qdotr))/emb.order()
        #Sq[l] = np.sum(cij*np.exp(1j*qdotr))
        Sq[l] = np.sum(cij*np.cos(qdotr))/order # The sin is an odd function so it will cancel itself out.

    #Sq = Sq.reshape((num_q_points, num_q_points))

    return qs[:,0], qs[:,1], Sq



def get_structure_factor_path(logical_graph, solution_array, positions, q_path_points, num_q_points_per_path = 100, burn_in=0):
    """
    Calculates structure factor.

    Parameters
    ----------
    logical_graph : networkx.Graph
        The logical graph that encodes the embedding.

    solution_array : numpy.ndarray
        The raw solution vector

    positions : dict
        The positions of logical qubits in an embedding of the logical_graph in
        R^3.
    
    q_segments : list of pairs
        The line segments in q-space (a.k.a. k-space, reciprical space, Fourier space). 
        Example: [((0,0),(0,pi)),((0,pi),(pi,pi)),((pi,pi),(0,0))].

    num_q_points_per_path : int (default 100)
        The mesh over the path in q-space.

    burn_in : int (default 0)
        The burn_in number for quantum evolution monte carlo.

    Returns
    -------

    q1,q2 : np.ndarray
        The grid in q-space.

    Sq : np.ndarray
        The fourier amplitudes that represent the structure factor.

    """

    log_to_phys = {log: linear_index_qubit(phys) for log,data in logical_graph.nodes(data=True) for phys in data['physical'].nodes}
    log_to_phys_array = np.array([log_to_phys[l] for l in sorted(log_to_phys)])
    order = logical_graph.order()
    assert len(log_to_phys)==order
    ijs = np.array(list(product(range(logical_graph.order()), range(logical_graph.order()))))

    pos_array = np.array([positions[l] for l in sorted(positions)])

    ris = pos_array[ijs[:,0],:].T
    rjs = pos_array[ijs[:,1],:].T
    rijs = ris-rjs

    phys_is = log_to_phys_array[ijs[:,0]]
    phys_js = log_to_phys_array[ijs[:,1]]

    cij = np.zeros((len(ijs)))
    num_k = solution_array.shape[0]

    start = burn_in if burn_in else 0
    for k in range(num_k):
        cij[:] += np.mean(solution_array[k,-start:,phys_is]*solution_array[k,-start:,phys_js], axis=1)
    cij = cij/solution_array.shape[0]

    q_point_array = np.array(q_path_points)
    q_mesh = np.ones((q_point_array.shape[0]*num_q_points_per_path,2))
    
    for i,point in enumerate(q_point_array):
        origin = point[0,:]
        target = point[1,:]
        vector = target-origin
        vector_mag = np.linalg.norm(vector)
        if vector_mag == 0:
            step_vector = vector
        else:
            step_vector = vector/vector_mag
        step = vector_mag/num_q_points_per_path

        for j in range(num_q_points_per_path):
            k = j+i*num_q_points_per_path
            q_mesh[k] = origin+step_vector*step*j
            

    qs = q_mesh
        
    #q1, q2 = np.meshgrid(qx_mesh,qy_mesh)
    #qs = np.vstack((q1.flatten(),q2.flatten())).T
    Sq = np.zeros(qs.shape[0])
    #Sq = c_ft(qs, Sq, rijs,cij,order)
    for l,q in enumerate(qs):
        qdotr = np.dot(q,rijs)
        #Sq[l] = np.sum(cij*np.cos(qdotr))/emb.order()+1j*np.sum(cij*np.sin(qdotr))/emb.order()
        #Sq[l] = np.sum(cij*np.exp(1j*qdotr))
        Sq[l] = np.sum(cij*np.cos(qdotr))/order # The sin is an odd function so it will cancel itself out.

    #Sq = Sq.reshape((num_q_points, num_q_points))

    return qs, Sq
 No newline at end of file
+3 −0
Original line number Diff line number Diff line
# __init__ for Analysis.py

from .analysis import *
Loading