def test_with_software_exact_solver(self):

        sampler = DWaveSampler(solver_features={'software': True})

        bqm = dimod.BinaryQuadraticModel.empty(dimod.SPIN)

        # plant a solution

        for v in sampler.nodelist:
            bqm.add_variable(v, .001)

        for u, v in sampler.edgelist:
            bqm.add_interaction(u, v, -1)

        resp = sampler.sample(bqm, num_reads=100)

        # the ground solution should be all spin down
        ground = dict(next(iter(resp)))

        self.assertEqual(ground, {v: -1 for v in bqm})
csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY)

# At least one qubit must be set
csp.add_constraint(or4, ['x1', 'x2', 'x3', 'x4'])

# No more than one qubit can be set
csp.add_constraint(nand, ['x1', 'x2'])
csp.add_constraint(nand, ['x1', 'x3'])
csp.add_constraint(nand, ['x1', 'x4'])
csp.add_constraint(nand, ['x2', 'x3'])
csp.add_constraint(nand, ['x2', 'x4'])
csp.add_constraint(nand, ['x3', 'x4'])

bqm = dwavebinarycsp.stitch(csp)
response = sampler.sample(bqm, num_reads=samples)

# aggregate the results
answers = {}
valid, invalid = 0, 0
for datum in response.data():
    sample, energy, num = datum
    if (csp.check(sample)):
        valid = valid + num
        result = ''
        for i in range(1, 5):
            result += str(sample['x' + str(i)])
        try:
            answers[result] += num
        except:
            answers[result] = num
Beispiel #3
0
import minorminer

# Find an embedding
embedding = minorminer.find_embedding(bqm.quadratic, target_edgelist)
if bqm and not embedding:
    raise ValueError("no embedding found")

# Apply the embedding to the factoring problem to map it to the QPU
bqm_embedded = dimod.embed_bqm(bqm, embedding, target_adjacency, 3.0)

# Request num_reads samples
kwargs = {}
kwargs['num_reads'] = 1000
if 'answer_mode' in sampler.parameters:
    kwargs['answer_mode'] = 'histogram'
response = sampler.sample(bqm_embedded, **kwargs)

# Map back to the BQM's graph (nodes labeled "a0", "b0" etc,)
response = dimod.unembed_response(response, embedding, source_bqm=bqm)
print("\nThe solution in problem variables: \n",
      next(response.data(fields=['sample'])))

## Viewing the Solution
from collections import OrderedDict

#from helpers.convert import to_base_ten


def to_base_ten(qs):
    def getbits(kyref):
        li = [ky for ky in qs.keys() if ky[0] == kyref and ky[1] < '9']
Beispiel #4
0
def execute(circuit,
            backend=None,
            config=None,
            basis_gates=None,
            coupling_map=None,
            initial_layout=None,
            shots=1024,
            max_credits=10,
            seed=None,
            qobj_id=None,
            hpc=None,
            skip_transpiler=False,
            seed_mapper=None):

    outputs = list()
    inputs = list()

    for qubit in circuit.annealergraph.qubits.keys():
        if isinstance(circuit.annealergraph.qubits[qubit], dict):
            if circuit.annealergraph.qubits[qubit]['measured'] == True:
                outputs.append(
                    circuit.annealergraph.qubits[qubit]['components'][-1])
                # can't omit output bit from being included as input, but is its put
                # first in the list, it will be zero the top portion of the readout
                inputs.append(
                    circuit.annealergraph.qubits[qubit]['components'][0])

    for qubit in circuit.annealergraph.qubits.keys():
        if isinstance(circuit.annealergraph.qubits[qubit], dict):
            if circuit.annealergraph.qubits[qubit]['measured'] == False:
                inputs.append(
                    circuit.annealergraph.qubits[qubit]['components'][0])

    sampler = DWaveSampler(
        endpoint='https://cloud.dwavesys.com/sapi',
        token='DEV-beb5d0babc40334f66b655704f1b5315917b4c41',
        solver='DW_2000Q_2_1')
    '''
    qubit_weights, coupler_weights, dwavemap = circuit.annealergraph.map_to_Dwave_graph(list(sampler._nodelist), list(sampler.edgelist))
    
    ins = list()
    outs = list()
    for name in inputs:
        ins.append(dwavemap[name][0])
    for name in outputs:
        outs.append(dwavemap[name][0])

    inputs = ins
    outputs = outs
    '''

    qubit_weights = circuit.annealergraph.qubitweights
    coupler_weights = circuit.annealergraph.couplerweights

    bqm = dimod.BinaryQuadraticModel(qubit_weights, coupler_weights, 0,
                                     dimod.BINARY)

    kwargs = {}
    if 'num_reads' in sampler.parameters:
        kwargs['num_reads'] = 100
    if 'answer_mode' in sampler.parameters:
        kwargs['answer_mode'] = 'histogram'
    print("Running...")

    response = EmbeddingComposite(sampler).sample(bqm, **kwargs)

    sampler.client.close()
    print("Done.")
    print(response.data)

    groundstate = 1000000
    for sample, energy in response.data(['sample', 'energy']):
        if energy < groundstate:
            groundstate = round(energy, 1)

    function = list()
    for sample, energy in response.data(['sample', 'energy']):
        if round(energy, 1) == groundstate:
            print(sample, round(energy, 1))
            row = []
            for inp in inputs:
                row.append(sample[inp])
            for outp in outputs:
                row.append(sample[outp])
            function.append(row)
    print('\n')

    function.sort()
    for i in range(len(function)):
        print(function[i])

    print(embedding)

    if len(circuit.annealergraph.qubitweights) < 18:
        # ExactSolver simulation
        print("\nExactSolver Check:")
        print("Simulating problem with {} qubits".format(
            len(circuit.annealergraph.qubitweights)))
        qubit_weights = circuit.annealergraph.qubitweights
        coupler_weights = circuit.annealergraph.couplerweights

        bqm = dimod.BinaryQuadraticModel(qubit_weights, coupler_weights, 0,
                                         dimod.BINARY)
        sampler = dimod.ExactSolver()

        response = sampler.sample(bqm)

        groundstate = 1000000
        for sample, energy in response.data(['sample', 'energy']):
            if energy < groundstate:
                groundstate = round(energy, 1)

        function = list()
        for sample, energy in response.data(['sample', 'energy']):
            if round(energy, 1) == groundstate:
                print(sample, round(energy, 1))
                row = []
                for inp in inputs:
                    row.append(sample[inp])
                for outp in outputs:
                    row.append(sample[outp])
                function.append(row)
        print('\n')

        function.sort()
        for i in range(len(function)):
            print(function[i])
    else:
        print("Problem to large to simulate. Used {} qubits".format(
            len(circuit.annealergraph.qubitweights)))
# Convert the binary constraint satisfaction problem to a binary quadratic model
bqm = dwavebinarycsp.stitch(csp)
                   
---------
#The next code sets up the D-Wave sampler
---------

from dwave.system.samplers import DWaveSampler
from dwave.systems.composites import Embedding Composite

sampler = EmbeddingComposite(DWaveSampler(endpoint= 'path', token= 'token', solver='SolverName'))

#Next we as for 1000 samples and separate those that satisfy the CSP from those that fail to do so.

response = sampler.sample(bqm, num_reads=1000)

# Check how many solutions meet the constraints (are valid)
valid, invalid, data = 0,0, []
for datum in response.data(['sample', 'energy', 'num_occurences']):
    if (csp.check(datum.sample)):
        valid = valid+datum.num_occurences
        for i in range(datum.num_occurences):
            data.append((datum.sample, datum.energy, '1'))
    else:
        invalid = invalid+datum.num_occurences
        for i in range(datum.num_occurences):
            data.append((datum.sample, datum.energy, '0'))
                   
print(valid, invalid)
            
def factor(P, use_saved_embedding=True):

    ####################################################################################################
    # get circuit
    ####################################################################################################

    construction_start_time = time.time()

    validate_input(P, range(2 ** 6))

    # get constraint satisfaction problem
    csp = dbc.factories.multiplication_circuit(3)

    # get binary quadratic model
    bqm = dbc.stitch(csp, min_classical_gap=.1)

    # we know that multiplication_circuit() has created these variables
    p_vars = ['p0', 'p1', 'p2', 'p3', 'p4', 'p5']

    # convert P from decimal to binary
    fixed_variables = dict(zip(reversed(p_vars), "{:06b}".format(P)))
    fixed_variables = {var: int(x) for(var, x) in fixed_variables.items()}

    # fix product qubits
    for var, value in fixed_variables.items():
        bqm.fix_variable(var, value)

    log.debug('bqm construction time: %s', time.time() - construction_start_time)

    ####################################################################################################
    # run problem
    ####################################################################################################

    sample_time = time.time()

    # get QPU sampler
    sampler = DWaveSampler()
    _, target_edgelist, target_adjacency = sampler.structure

    if use_saved_embedding:
        # load a pre-calculated embedding
        from factoring.embedding import embeddings
        embedding = embeddings[sampler.solver.id]
    else:
        # get the embedding
        embedding = minorminer.find_embedding(bqm.quadratic, target_edgelist)
        if bqm and not embedding:
            raise ValueError("no embedding found")

    # apply the embedding to the given problem to map it to the sampler
    bqm_embedded = dimod.embed_bqm(bqm, embedding, target_adjacency, 3.0)

    # draw samples from the QPU
    kwargs = {}
    if 'num_reads' in sampler.parameters:
        kwargs['num_reads'] = 50
    if 'answer_mode' in sampler.parameters:
        kwargs['answer_mode'] = 'histogram'
    response = sampler.sample(bqm_embedded, **kwargs)

    # convert back to the original problem space
    response = dimod.unembed_response(response, embedding, source_bqm=bqm)

    sampler.client.close()

    log.debug('embedding and sampling time: %s', time.time() - sample_time)

    ####################################################################################################
    # output results
    ####################################################################################################

    output = {
        "results": [],
        #    {
        #        "a": Number,
        #        "b": Number,
        #        "valid": Boolean,
        #        "numOfOccurrences": Number,
        #        "percentageOfOccurrences": Number
        #    }
        "timing": {
            "actual": {
                "qpuProcessTime": None  # microseconds
            }
        },
        "numberOfReads": None
    }

    # we know that multiplication_circuit() has created these variables
    a_vars = ['a0', 'a1', 'a2']
    b_vars = ['b0', 'b1', 'b2']

    # histogram answer_mode should return counts for unique solutions
    if 'num_occurrences' not in response.data_vectors:
        response.data_vectors['num_occurrences'] = [1] * len(response)

    # should equal num_reads
    total = sum(response.data_vectors['num_occurrences'])

    results_dict = OrderedDict()
    for sample, num_occurrences in response.data(['sample', 'num_occurrences']):
        # convert A and B from binary to decimal
        a = b = 0
        for lbl in reversed(a_vars):
            a = (a << 1) | sample[lbl]
        for lbl in reversed(b_vars):
            b = (b << 1) | sample[lbl]
        # aggregate results by unique A and B values (ignoring internal circuit variables)
        if (a, b, P) in results_dict:
            results_dict[(a, b, P)]["numOfOccurrences"] += num_occurrences
            results_dict[(a, b, P)]["percentageOfOccurrences"] = 100 * \
                results_dict[(a, b, P)]["numOfOccurrences"] / total
        else:
            results_dict[(a, b, P)] = {"a": a,
                                       "b": b,
                                       "valid": a * b == P,
                                       "numOfOccurrences": num_occurrences,
                                       "percentageOfOccurrences": 100 * num_occurrences / total}

    output['results'] = list(results_dict.values())
    output['numberOfReads'] = total
    if 'timing' in response.info:
        output['timing']['actual']['qpuProcessTime'] = response.info['timing']['qpu_access_time']

    return output
#
# Constrain qubits 0 and 5 to have the same value - and yes, we will embed
# 1 and 5 to have the same value
# q_0 + 0.5 (q_1 + q_5) - 2 q_0 q_5 - 1
#
# Constrain qubits 1 and 5 to have the same value, explicitly
# chainstrength (q_1 + q_5 - 2q_1 q_5 - 1)

numruns = 1000
chainstrength = float(sys.argv[1])
sampler = DWaveSampler(solver={'topology__type': 'chimera'})

# Add all the equations together
Q = {
    (0, 0): 2,
    (1, 1): chainstrength,
    (5, 5): chainstrength,
    (0, 4): -2,
    (1, 4): 2,
    (0, 5): -2,
    (1, 5): -2 * chainstrength
}

bqm = dimod.BinaryQuadraticModel.from_qubo(Q, offset=-2 - chainstrength)

results = sampler.sample(bqm, num_reads=numruns)

# print the results
for sample, energy in results.data(['sample', 'energy']):
    print(sample, energy)
Beispiel #8
0
        embeddedQ = embed_qubo(Q, embedding, sampler.adjacency)

        ### Energy offset
        ### エネルギー オフセット
        e_offset = lagrange_hard_shift * days * workforce(1)**2
        e_offset += lagrange_soft_nurse * nurses * duty_days**2

        ### BQM
        bqm = BinaryQuadraticModel.from_qubo(embeddedQ, offset=e_offset)
        sbqm = BinaryQuadraticModel.from_qubo(Q, offset=e_offset)

        # Sample solution
        # 解をサンプリングします
        print("Connected to {}. N = {}, D = {}".format(sampler.solver.id,
                                                       nurses, days))
        results = sampler.sample(bqm, num_reads=numSampling)
        samples = unembed_sampleset(results,
                                    embedding,
                                    sbqm,
                                    chain_break_fraction=True)

        ### Save data with pickle for analysis and reverse annealing
        ### 結果分析と逆アニーリングのため pickle を用いてデータを保存します
        fout = "results_%s_N%d_D%d_s%d.p" % (topology, nurses, days,
                                             numSampling)
        saveDict = {
            'results': results,
            'embedding': embedding,
            'bqm': sbqm,
            'samples': samples
        }
Beispiel #9
0
def execute(circuit,
            backend=None,
            config=None,
            basis_gates=None,
            coupling_map=None,
            initial_layout=None,
            shots=1024,
            max_credits=10,
            seed=None,
            qobj_id=None,
            hpc=None,
            skip_transpiler=False,
            seed_mapper=None):

    outputs = list()
    inputs = list()

    for qubit in circuit.annealergraph.qubits.keys():
        if isinstance(circuit.annealergraph.qubits[qubit], dict):
            if circuit.annealergraph.qubits[qubit]['measured'] == True:
                outputs.append(
                    circuit.annealergraph.qubits[qubit]['components'][-1])
                # can't omit output bit from being included as input, but is its put
                # first in the list, it will be zero the top portion of the readout
                inputs.append(
                    circuit.annealergraph.qubits[qubit]['components'][0])

    for qubit in circuit.annealergraph.qubits.keys():
        if isinstance(circuit.annealergraph.qubits[qubit], dict):
            if circuit.annealergraph.qubits[qubit]['measured'] == False:
                inputs.append(
                    circuit.annealergraph.qubits[qubit]['components'][0])

    circuit.annealergraph.print_chimera_graph_to_file()

    sampler = DWaveSampler(
        endpoint='https://cloud.dwavesys.com/sapi',
        token='DEV-beb5d0babc40334f66b655704f1b5315917b4c41',
        solver='DW_2000Q_2_1')

    qubit_weights = circuit.annealergraph.qubitweights
    coupler_weights = circuit.annealergraph.couplerweights

    bqm = dimod.BinaryQuadraticModel(qubit_weights, coupler_weights, 0,
                                     dimod.BINARY)

    kwargs = {}
    if 'num_reads' in sampler.parameters:
        kwargs['num_reads'] = 5000
    if 'answer_mode' in sampler.parameters:
        kwargs['answer_mode'] = 'histogram'
    #if 'annealing_time' in sampler.parameters:
    #    kwargs['annealing_time'] = 100
    print("Running...")

    response = sampler.sample(bqm, **kwargs)

    sampler.client.close()
    print("Done.")
    print(response.data)

    groundstate = 1000000
    for sample, energy in response.data(['sample', 'energy']):
        if energy < groundstate:
            groundstate = round(energy, 1)
    print("Ground State: ", groundstate)

    function = list()
    for sample, energy in response.data(['sample', 'energy']):
        if round(energy, 1) == groundstate:
            print(sample, round(energy, 1))
            row = []
            for inp in inputs:
                row.append(sample[inp])
            for outp in outputs:
                row.append(sample[outp])
            function.append(row)
    print('\n')

    function.sort()
    for i in range(len(function)):
        print(function[i])
    '''
    qubit_weights = {'targ': 4,
                     'ctl1in': 5,
                     'ctl2in': 5,
                     'outin': 8,
                     'outout': 12,
                     'ctl1out': 5,
                     'ctl2out': 5,
                     'anc': 9}
    coupler_weights = {('outin','outout'): -17,
                       ('ctl1in','ctl1out'): -10,
                       ('ctl2in','ctl2out'): -10,
                       ('anc','targ'): -9,
                       ('anc','ctl1in'): -4,
                       ('anc','ctl2in'): -5,
                       ('anc','outin'): 9,
                       ('outout','targ'): -7,
                       ('outin','ctl1out'): -2,
                       ('outin','ctl2out'): -2,
                       ('targ','ctl1out'): 2,
                       ('targ','ctl2out'): 2,
                       ('ctl1in','ctl2out'): 1}
                       
    inputs = ['targ','ctl1in','ctl2in']
    outputs = ['outout']
    '''
    if len(circuit.annealergraph.qubitweights) <= 19:
        # ExactSolver simulation
        print("\nExactSolver Check:")
        print("Simulating problem with {} qubits".format(
            len(circuit.annealergraph.qubitweights)))
        qubit_weights = circuit.annealergraph.qubitweights
        coupler_weights = circuit.annealergraph.couplerweights

        print("\nQubit Weights:")
        for key in qubit_weights.keys():
            print(key, "\t", qubit_weights[key])
        print("\nCoupler Weights")
        for key in coupler_weights.keys():
            print(key, "\t", coupler_weights[key])
        print("\n")

        bqm = dimod.BinaryQuadraticModel(qubit_weights, coupler_weights, 0,
                                         dimod.BINARY)
        sampler = dimod.ExactSolver()

        response = sampler.sample(bqm)

        groundstate = 1000000
        for sample, energy in response.data(['sample', 'energy']):
            if energy < groundstate:
                groundstate = round(energy, 1)
        print("Ground State: ", groundstate)
        function = list()
        for sample, energy in response.data(['sample', 'energy']):
            if round(energy, 1) == groundstate:
                print(sample, round(energy, 1))
                row = []
                for inp in inputs:
                    row.append(sample[inp])
                for outp in outputs:
                    row.append(sample[outp])
                function.append(row)
        print('\n')

        function.sort()
        for i in range(len(function)):
            print(function[i])
    else:
        print("Problem too large to simulate. Used {} qubits".format(
            len(circuit.annealergraph.qubitweights)))
Beispiel #10
0
class DictRep(ProbRep):
    """
    A concrete class that represents problems
    on the D-Wave as a dictionary of values.
    """
    def __init__(self, H, qpu, vartype, encoding):
        """
        Class that takes a dictionary representation of an ising-hamiltonian and submits problem to a quantum annealer

        qpu: string
            specifies quantum processing unit to be used during calculation--referring to name specifying this information in dwave config file

        vartype: string
            QUBO or Ising (all case variants acceptable)

        encoding: string
            logical or direct. If logical, embeds onto chip under the hood. If direct, assumes manual embedding and tries to put directly onto chip as is.

        H: dict
            The hamiltonian represented as a dict of the form {(0, 0): h0, (0, 1): J01, ...} OR {(0, 0): 'h0', (0, 1): 'J0', (1, 1): 'h1', ...}
        """
        # poplate run information
        super().__init__(qpu, vartype, encoding)

        # create a set of regex rules to parse h/J string keys in H
        # also creates a "rules" dictionary to relate qubit weights to relevant factor
        self.hvrule = re.compile('h[0-9]*')
        self.Jvrule = re.compile('J[0-9]*')
        self.weight_rules = {}

        # create list of qubits/ couplers and
        # dicts that map indepndent params to
        # all qubits/ couplers that have that value
        self.H = H
        self.qubits = []
        self.params_to_qubits = {}
        self.couplers = []
        self.params_to_couplers = {}
        for key, value in H.items():
            if key[0] == key[1]:
                self.qubits.append(key[0])
                if type(value) != str:
                    div_idx = -1
                else:
                    div_idx = value.find('/')
                if div_idx == -1:
                    self.weight_rules[key[0]] = 1
                else:
                    self.weight_rules[key[0]] = float(value[div_idx + 1:])
                    value = value[:div_idx]
                self.params_to_qubits.setdefault(value, []).append(key[0])
            else:
                self.couplers.append(key)
                if type(value) != str:
                    div_idx = -1
                else:
                    div_idx = value.find('/')
                if div_idx == -1:
                    self.weight_rules[key] = 1
                else:
                    self.weight_rules[key] = float(value[div_idx + 1:])
                    value = value[:div_idx]
                self.params_to_couplers.setdefault(value, []).append(key)

        self.nqubits = len(self.qubits)
        self.Hsize = 2**(self.nqubits)

        if qpu == 'dwave':
            try:
                # let OCEAN handle embedding
                if encoding == "logical":
                    # encode several times on graph
                    # based on qubits encoded
                    if len(self.qubits) <= 4:
                        self.sampler = EmbeddingComposite(
                            TilingComposite(DWaveSampler(), 1, 1, 4))
                    else:
                        self.sampler = EmbeddingComposite(DWaveSampler())

                # otherwise, assume 1-1
                else:
                    self.sampler = DWaveSampler()

            except:
                raise ConnectionError(
                    "Cannot connect to DWave sampler. Have you created a DWave config file using 'dwave config create'?"
                )

        elif qpu == 'test':
            self.sampler = dimod.SimulatedAnnealingSampler()

        elif qpu == 'numerical':
            self.processordata = loadAandB()
            self.graph = nx.Graph()
            self.graph.add_edges_from(self.couplers)
            self.data = pd.DataFrame()

        # save values/ metadata
        self.H = copy.deepcopy(H)
        if encoding == 'direct':
            self.wqubits = self.sampler.properties['qubits']
            self.wcouplers = self.sampler.properties['couplers']

    def save_config(self, fname, config_data={}):
        """
        Saves Hamiltonian configuration for future use
        """
        # if config data not supplied, at least dump Hamiltonian
        if config_data == {}:
            config_data = {'H': self.H}

        with open(fname + ".yml", 'w') as yamloutput:
            yaml.dump(config_data, yamloutput)

    def tile_H(self):
        pqubits = self.qubits
        pcouplers = self.couplers
        wqubits = self.wqubits
        wcouplers = self.wcouplers
        H = copy.deepcopy(self.H)

        for unitcell in range(1, 16 * 16):
            # create list of qubits/couplers that should be working in this unit cell
            unit_qubits = [q for q in range(8 * unitcell, 8 * (unitcell + 1))]
            unit_couplers = [[q, q + (4 - q % 4) + i] for q in unit_qubits[:4]
                             for i in range(4)]

            # ensure that all qubits and couplers are working
            if all(q in wqubits
                   for q in unit_qubits) and all(c in wcouplers
                                                 for c in unit_couplers):
                # init_state.extend(init_state[:])
                # copy the initial state
                # if so, create copies of H on other unit cells
                for q in unit_qubits:
                    if (q % 8) in pqubits:
                        H[(q, q)] = H[(q % 8, q % 8)]

                for c in unit_couplers:
                    if (c[0] % 8, c[1] % 8) in pcouplers:
                        H[tuple(c)] = H[(c[0] % 8, c[1] % 8)]

            # else:
            #init_state.extend([3 for q in range(len(unit_qubits))])

        #self.init_state = init_state
        self.H = H
        self.qubits = []
        self.params_to_qubits = {}
        self.couplers = []
        self.params_to_couplers = {}
        for key, value in H.items():
            if key[0] == key[1]:
                self.qubits.append(key[0])
                self.params_to_qubits.setdefault(value, []).append(key[0])
            else:
                self.couplers.append(key)
                self.params_to_couplers.setdefault(value, []).append(key)

    def populate_parameters(self, parameters):
        # generate all independent combinations of parameters
        self.params = []
        self.values = []
        for key, value in parameters.items():
            self.params.append(key)
            self.values.append(value)
        self.combos = list(itertools.product(*self.values))

        # format pandas DataFrame
        # columns = self.params[:]
        # columns.extend(['energy', 'state'])
        self.data = pd.DataFrame()
        self.data.H = str(self.H)
        self.data.vartype = self.vartype
        self.data.encoding = self.encoding

        return

    def call_annealer(self, **kwargs):
        """
        Calls qpu on problem encoded by H.
        cull: bool
            if true, only outputs lowest energy states,
            otherwise shows all results
        """

        # parse the input data
        # cull = kwargs.get('cull', False)  # only takes lowest energy data
        s_to_hx = kwargs.get('s_to_hx',
                             '')  # relates s to transverse-field bias
        spoint = kwargs.get(
            'spoint',
            0)  # can start sampling data midway through if interuptted

        # if H.values() only contains floats,
        # run sinlge problem as is
        if all(
                type(value) == int or type(value) == float
                for value in self.H.values()):

            if self.vartype == 'ising':
                h, J = get_dwaveH(self.H, 'ising')
                response = self.sampler.sample_ising(h, J)
                return response

            elif self.vartype == 'qubo':
                H = get_dwaveH(self.H, 'vartype')
                response = self.sampler.sample_ising(H)
                return response

        # otherwise, run a parameter sweep
        for combo in self.combos[spoint::]:
            # init single run's data/inputs
            rundata = {}
            runh = {}
            runJ = {}
            optional_args = {}
            count = 0
            # map params to values in combo
            for param in self.params:
                rundata[param] = combo[count]
                # if param is qubit param
                if self.hvrule.match(param):
                    for qubit in self.params_to_qubits[param]:
                        runh[qubit] = combo[count] / self.weight_rules[qubit]

                elif self.Jvrule.match(param):
                    for coupler in self.params_to_couplers[param]:
                        runJ[coupler] = combo[count] / self.weight_rules[
                            coupler]

                elif param == 'anneal_schedule':
                    anneal_schedule = combo[count]
                    optional_args['anneal_schedule'] = anneal_schedule
                    # if transverse field terms, get hx
                    if s_to_hx:
                        hx = s_to_hx[anneal_schedule[1][1]]
                        rundata['hx'] = hx

                elif param == 'num_reads':
                    num_reads = combo[count]
                    optional_args['num_reads'] = num_reads

                elif param == 'initial_state':
                    initial_state = combo[count]
                    optional_args['initial_state'] = initial_state

                elif param == 'reinitialize_state':
                    reinitialize_state = combo[count]
                    optional_args['reinitialize_state'] = reinitialize_state

                count += 1

            # run the sim and collect data
            if self.qpu == 'dwave':

                response = self.sampler.sample_ising(h=runh,
                                                     J=runJ,
                                                     **optional_args)

                for energy, state, num in response.data(
                        fields=['energy', 'sample', 'num_occurrences']):
                    rundata['energy'] = energy
                    rundata['state'] = tuple(state[key]
                                             for key in sorted(state.keys()))
                    for n in range(num):
                        self.data = self.data.append(rundata,
                                                     ignore_index=True)

            elif self.qpu == 'test':
                bqm = dimod.BinaryQuadraticModel.from_ising(h=runh, J=runJ)
                response = self.sampler.sample(bqm, num_reads=num_reads)
                for energy, state in response.data(
                        fields=['energy', 'sample']):
                    rundata['energy'] = energy
                    rundata['state'] = tuple(state[key]
                                             for key in sorted(state.keys()))
                    self.data = self.data.append(rundata, ignore_index=True)

            elif self.qpu == 'numerical':
                continue

        return self.data

    def visualize_graph(self):
        G = nx.Graph()
        G.add_edges_from(self.couplers)
        nx.draw_networkx(G)
        return G

    def save_data(self, filename):
        self.data.to_csv(filename, index=False)

    def get_state_plot(self,
                       figsize=(12, 8),
                       filename=None,
                       title='Distribution of Final States'):
        data = self.data
        ncount = len(data)

        plt.figure(figsize=figsize)
        ax = sns.countplot(x="state", data=data)
        plt.title(title)
        plt.xlabel('State')

        # Make twin axis
        ax2 = ax.twinx()

        # Switch so count axis is on right, frequency on left
        ax2.yaxis.tick_left()
        ax.yaxis.tick_right()

        # Also switch the labels over
        ax.yaxis.set_label_position('right')
        ax2.yaxis.set_label_position('left')

        ax2.set_ylabel('Frequency [%]')

        for p in ax.patches:
            x = p.get_bbox().get_points()[:, 0]
            y = p.get_bbox().get_points()[1, 1]
            ax.annotate('{:.1f}%'.format(100. * y / ncount), (x.mean(), y),
                        ha='center',
                        va='bottom')  # set the alignment of the text

        # Use a LinearLocator to ensure the correct number of ticks
        ax.yaxis.set_major_locator(ticker.LinearLocator(11))

        # Fix the frequency range to 0-100
        ax2.set_ylim(0, 100)
        ax.set_ylim(0, ncount)

        # And use a MultipleLocator to ensure a tick spacing of 10
        ax2.yaxis.set_major_locator(ticker.MultipleLocator(10))

        # Need to turn the grid on ax2 off, otherwise the gridlines end up on top of the bars
        # ax2.grid(None)

        if filename:
            plt.savefig(filename, dpi=300)

        return plt

    def get_ferro_diagram(self, xparam, yparam, divideby=None, title=''):
        """
        Plot the probability that output states are ferromagnetic on a contour plot
        with xaxis as xparam/divdeby and yaxis as yparam/divideby.
        """
        df = self.data
        # obtain denominator of expression (if constant value is used across-the-board)
        if divideby:
            denom = abs(df[divideby].unique()[0])
            xlabel = xparam + '/|' + divideby + '|'
            ylabel = yparam + '/|' + divideby + '|'
        else:
            denom = 1
            xlabel = xparam
            ylabel = yparam

        xs = df[xparam].unique()
        ys = df[yparam].unique()

        pfm_meshgrid = []
        # iterate over trials and obtain pFM for given xparam and yparam
        for y in ys:
            pfms = []
            for x in xs:
                # get length of unique elements in state bitstrings
                lubs = [
                    len(set(state))
                    for state in df.loc[(df[yparam] == y)
                                        & (df[xparam] == x)]['state']
                ]
                pfms.append(lubs.count(1) / len(lubs))
            pfm_meshgrid.append(pfms)

        X, Y = np.meshgrid(xs / denom, ys / denom)

        # plot the figure
        plt.figure()
        plt.title(title)
        plt.contourf(X,
                     Y,
                     pfm_meshgrid,
                     np.arange(0, 1.2, .2),
                     cmap='viridis',
                     extent=(-4, 4, 0, 4))
        cbar = plt.colorbar(ticks=np.arange(0, 1.2, .2))
        cbar.ax.set_title('$P_{FM}$')
        plt.clim(0, 1)
        plt.xlabel(xlabel)
        plt.ylabel(ylabel)

        return plt

    def diag_H(self):
        """
        Returns probability of each state.
        """
        numericH = get_numeric_H(self)
        HZ = numericH['HZ']
        gs = gs_calculator(HZ)
        num_qubits = len(self.qubits)
        Hsize = 2**(num_qubits)
        probs = np.array([abs(gs[i].flatten()[0])**2 for i in range(Hsize)])

        return probs

    def nf_anneal(self, schedule):
        """
        Performs a numeric forward anneal on H using QuTip.

        inputs:
        ---------
        schedule - a numeric anneal schedule defined with anneal length

        outputs:
        ---------
        probs - probability of each output state as a list ordered in canconically w.r.t. tensor product
        """
        times, svals = schedule

        # create a numeric representation of H
        ABfuncs = time_interpolation(schedule, self.processordata)
        numericH = get_numeric_H(self)
        A = ABfuncs['A(t)']
        B = ABfuncs['B(t)']
        HX = numericH['HX']
        HZ = numericH['HZ']
        # "Analytic" or function H(t)
        analH = lambda t: A(t) * HX + B(t) * HZ
        # Define list_H for QuTiP
        listH = [[HX, A], [HZ, B]]

        # perform a numerical forward anneal on H
        results = qt.sesolve(listH, gs_calculator(analH(0)), times)
        probs = np.array([
            abs(results.states[-1][i].flatten()[0])**2
            for i in range(self.Hsize)
        ])

        return probs

    def nr_anneal(self, schedule, init_state):
        """
        Performs a numeric reverse anneal on H using QuTip.

        inputs:
        ---------
        schedule - a numeric anneal schedule
        init_state - the starting state for the reverse anneal listed as string or list
        e.g. '111' or [010]

        outputs:
        ---------
        probs - probability of each output state as a list ordered in canconically w.r.t. tensor product
        """
        times, svals = schedule

        # create a numeric representation of H
        ABfuncs = time_interpolation(schedule, self.processordata)
        numericH = get_numeric_H(self)
        A = ABfuncs['A(t)']
        B = ABfuncs['B(t)']
        HX = numericH['HX']
        HZ = numericH['HZ']
        # Define list_H for QuTiP
        listH = [[HX, A], [HZ, B]]

        # create a valid QuTip initial state
        qubit_states = [qts.ket([int(i)]) for i in init_state]
        QuTip_init_state = qt.tensor(*qubit_states)

        # perform a numerical reverse anneal on H
        results = qt.sesolve(listH, QuTip_init_state, times)
        probs = np.array([
            abs(results.states[-1][i].flatten()[0])**2
            for i in range(self.Hsize)
        ])

        return probs

    def frem_anneal(self, schedules, partition, HR_init_state):
        """
        Performs a numeric FREM anneal on H using QuTip.

        inputs:
        ---------
        schedules - a numeric annealing schedules [reverse, forward]
        partition - a parition of H in the form [HR, HF]
        init_state - the starting state for the reverse anneal listed as string or list
        e.g. '111' or [010]

        outputs:
        ---------
        probs - probability of each output state as a list ordered in canconically w.r.t. tensor product
        """

        # retrieve useful quantities from input data
        f_sch, r_sch = schedules
        times = f_sch[0]
        HR = DictRep(H=partition['HR'],
                     qpu='numerical',
                     vartype='ising',
                     encoding='logical')
        HF = DictRep(H=partition['HF'],
                     qpu='numerical',
                     vartype='ising',
                     encoding='logical')
        Rqubits = partition['Rqubits']

        # prepare the initial state
        statelist = []
        fidx = 0
        ridx = 0
        for qubit in self.qubits:
            # if part of HR, give assigned value by user
            if qubit in Rqubits:
                statelist.append(qts.ket(HR_init_state[ridx]))
                ridx += 1
            # otherwise, put in equal superposition (i.e. gs of x-basis)
            else:
                xstate = (qts.ket('0') - qts.ket('1')).unit()
                statelist.append(xstate)
                fidx += 1
        init_state = qto.tensor(*statelist)

        # Create the numeric Hamiltonian for HR
        ABfuncs = time_interpolation(r_sch, self.processordata)
        numericH = get_numeric_H(HR)
        A = ABfuncs['A(t)']
        B = ABfuncs['B(t)']
        HX = numericH['HX']
        HZ = numericH['HZ']
        # Define list_H for QuTiP
        listHR = [[HX, A], [HZ, B]]

        # create the numeric Hamiltonian for HF
        ABfuncs = time_interpolation(f_sch, self.processordata)
        numericH = get_numeric_H(HF)
        A = ABfuncs['A(t)']
        B = ABfuncs['B(t)']
        HX = numericH['HX']
        HZ = numericH['HZ']
        # "Analytic" or function H(t)
        analHF = lambda t: A(t) * HX + B(t) * HZ
        # Define list_H for QuTiP
        listHF = [[HX, A], [HZ, B]]

        # create the total Hamitlontian of HF + HR
        list_totH = listHR + listHF

        # run the numerical simulation and find probabilities of each state
        frem_results = qt.sesolve(list_totH, init_state, times)
        probs = np.array([
            abs(frem_results.states[-1][i].flatten()[0])**2
            for i in range(self.Hsize)
        ])

        return probs

    def frem_comparison(self, T, sval, ftr):
        """
        Performs FREM algorithm and compares it to direct forward annealing.

        inputs:
        ---------
        T: total anneal time
        sval: svalue to go to in reverse annealing/ frem anneal
        ftr: the ratio of time spent in reverse and forward in frem

        outputs:
        ---------
        KL_div - the KL divergence of forward and FREM annealing w.r.t. diagonalization
        """
        f_sch = make_numeric_schedule(.1, **{'direction': 'forward', 'ta': T})
        r_sch = make_numeric_schedule(
            .1, **{
                'direction': 'reverse',
                'ta': ftr * T,
                'sa': sval,
                'tq': (1 - ftr) * T
            })

        # first, do direct diag on H
        # then extract non-zero entires ("gs" entries)
        dprobs = self.diag_H()
        nonzeroidxs = np.nonzero(dprobs)
        gs_dprobs = dprobs[nonzeroidxs]

        # perform forward anneal
        fprobs = self.nf_anneal(f_sch)
        gs_fprobs = fprobs[nonzeroidxs]

        # next, find a random partition of H into HR/HF
        partition = random_partition(self)
        # get qubits that belong to HR
        Rqubits = partition['Rqubits']
        # find the most probable state of Rqubits from forward anneal
        init_state = ml_measurement(fprobs, self.nqubits)

        # perform reverse anneal using initial state guess
        rprobs = self.nr_anneal(r_sch, init_state)
        gs_rprobs = rprobs[nonzeroidxs]

        # find initial state of sub-system (i.e. Rqubits)
        sub_system_state = []
        for (idx, qs) in enumerate(init_state):
            if idx in Rqubits:
                sub_system_state.append(qs)
        sub_init_state = ''.join([str(i) for i in sub_system_state])

        # perform FREM anneal
        fremprobs = self.frem_anneal([f_sch, r_sch], partition, sub_init_state)
        gs_fremprobs = fremprobs[nonzeroidxs]

        # save data in a pandas dataframe
        fdata = {
            'method': 'forward',
            'T': T,
            's': sval,
            'ftr': ftr,
            'part_size': self.nqubits,
            'probs': fprobs,
            'KL_div': entropy(dprobs, fprobs),
            'gs_KL_div': entropy(gs_dprobs, gs_fprobs),
            'gs_prob': sum(gs_fprobs)
        }

        rdata = {
            'method': 'reverse',
            'T': T,
            's': sval,
            'ftr': ftr,
            'part_size': self.nqubits,
            'probs': rprobs,
            'KL_div': entropy(dprobs, rprobs),
            'gs_KL_div': entropy(gs_dprobs, gs_rprobs),
            'gs_prob': sum(gs_rprobs)
        }

        fremdata = {
            'method': 'frem',
            'T': T,
            's': sval,
            'ftr': ftr,
            'part_size': len(Rqubits),
            'probs': fremprobs,
            'KL_div': entropy(dprobs, fremprobs),
            'gs_KL_div': entropy(gs_dprobs, gs_fremprobs),
            'gs_prob': sum(gs_fremprobs)
        }

        self.data = self.data.append(fdata, ignore_index=True)
        self.data = self.data.append(rdata, ignore_index=True)
        self.data = self.data.append(fremdata, ignore_index=True)

        return {'fdata': fdata, 'rdata': rdata, 'fremdata': fremdata}

    def sudden_anneal_test(self):
        pass

    def get_QUBO_rep(self):
        pass

    def get_Ising_rep(self):
        pass
        
        fname = "results_%s_N%d_D%d_s%d.p" % (topology, nurses, days, numSampling)
        previous = pickle.load(open(fname, "rb"))

        initial = previous['results'].first.sample

        embedding = previous['embedding']
        embeddedQ = embed_qubo(Q, embedding, sampler.adjacency)

        ### Energy offset
        ### エネルギー オフセット
        e_offset = lagrange_hard_shift * days * workforce(1) ** 2
        e_offset += lagrange_soft_nurse * nurses * duty_days ** 2

        ### BQM
        bqm = BinaryQuadraticModel.from_qubo(embeddedQ, offset=e_offset)
        sbqm = BinaryQuadraticModel.from_qubo(Q, offset=e_offset)
        
        # Sample solution
        # 解をサンプリングします
        print("Connected to {}. N = {}, D = {}".format(sampler.solver.id, nurses, days))
        results = sampler.sample(bqm, num_reads=numSampling, initial_state=initial, reinitialize_state=reinitialize, anneal_schedule=schedule)
        samples = unembed_sampleset(results, embedding, sbqm, chain_break_fraction=True)

        ### Save data with pickle for analysis
        ### 結果分析のため pickle を用いてデータを保存します
        fout = "reinitialized_reverse_results_%s_N%d_D%d_s%d.p" % (topology, nurses, days, numSampling)
        saveDict = {'results' : results, 'embedding' : embedding, 'bqm': sbqm, 'samples' : samples}
        pickle.dump(saveDict, open(fout, "wb"))

Beispiel #12
0
def execute(circuit, backend = None,
            config=None, basis_gates=None, coupling_map=None, initial_layout=None,
            shots=1024, max_credits=10, seed=None, qobj_id=None, hpc=None,
            skip_transpiler=False, seed_mapper=None):

    outputs = list()
    inputs = list()
    
    qubit_biases = circuit.annealergraph.qubitbiases
    coupler_strengths = circuit.annealergraph.couplerstrengths

    print("\nDone building embedding.")
    print("\t# qubits: ", len(qubit_biases))
    print("\t# couplers: ", len(coupler_strengths))
    print("\t# non-gate couplers: {}\n".format(len(coupler_strengths)-circuit.annealergraph.numgatecouplers))

    for qubit in circuit.annealergraph.qubits.keys():
        if isinstance(circuit.annealergraph.qubits[qubit], dict):
            if circuit.annealergraph.qubits[qubit]['measured'] == True:
                outputs.append(circuit.annealergraph.qubits[qubit]['components'][-1])
                # can't omit output bit from being included as input, but is its put
                # first in the list, it will be zero the top portion of the readout
                ans = input("Constrain input of measured qubit {} to be 0 (y/n)? ".format(qubit))
                if ans == 'y':
                    change = circuit.annealergraph.qubits[qubit]['components'][0]
                    circuit.annealergraph.qubitbiases[change] = circuit.annealergraph.qubitbiases[change] + 5
                else:
                    inputs.append(circuit.annealergraph.qubits[qubit]['components'][0])

    for qubit in circuit.annealergraph.qubits.keys():
        if isinstance(circuit.annealergraph.qubits[qubit], dict):
            if circuit.annealergraph.qubits[qubit]['measured'] == False:
                ans = input("Constrain input of unmeasured qubit {} to be 0 (y/n)? ".format(qubit))
                if ans == 'y':
                    change = circuit.annealergraph.qubits[qubit]['components'][0]
                    circuit.annealergraph.qubitbiases[change] = circuit.annealergraph.qubitbiases[change] + 5
                else:
                    inputs.append(circuit.annealergraph.qubits[qubit]['components'][0])
            
    circuit.annealergraph.print_chimera_graph_to_file()
 
    samp = input("\nHow many samples? ")
    samp = int(samp)

    if 'source' in sys.argv:
        writedwavesource(circuit, circuit.annealergraph.token, samp, inputs, outputs)

    if ('run' in sys.argv) or (len(sys.argv)==1):
        try:
            import dimod
            from dwave.system.samplers import DWaveSampler
            from dwave.cloud.exceptions import SolverOfflineError
            from dwave.system.composites import EmbeddingComposite
            import minorminer
        except:
            print('Dwave Ocean not installed - cannot run or simulate generated embeddings. Run with "source" command line argument or install DWave Ocean.')
            return

        sampler = DWaveSampler(endpoint='https://cloud.dwavesys.com/sapi', token = circuit.annealergraph.token, solver = 'DW_2000Q_2_1')
        bqm = dimod.BinaryQuadraticModel(qubit_biases, coupler_strengths, 0, dimod.BINARY)
        print(qubit_biases)
        print(coupler_strengths)
        kwargs = {}
        if 'num_reads' in sampler.parameters:
            kwargs['num_reads'] = samp
        if 'answer_mode' in sampler.parameters:
            kwargs['answer_mode'] = 'histogram'
        #if 'annealing_time' in sampler.parameters:
        #    kwargs['annealing_time'] = 100
        print("\nRunning...")
    
        response = sampler.sample(bqm, **kwargs)

        sampler.client.close()
        print("Done.")
        print(response.data)

        groundstate = 1000000
        for sample, energy in response.data(['sample','energy']):
            if energy<groundstate:
                groundstate = round(energy,1)
        print("Ground State: ", groundstate)

        function = list()
        for sample, energy in response.data(['sample', 'energy']):
            if round(energy,1) == groundstate:
                print(sample, round(energy,1))
                row = []
                for inp in inputs:
                    row.append(sample[inp])
                for outp in outputs:
                    row.append(sample[outp])
                function.append(row)
        print('\n')
    
        function.sort()
        for i in range(len(function)):
            print(function[i])

    if 'sim' in sys.argv:
        try:
            import dimod
            from dwave.system.samplers import DWaveSampler
            from dwave.cloud.exceptions import SolverOfflineError
            from dwave.system.composites import EmbeddingComposite
            import minorminer
        except:
            print('Dwave Ocean not installed - cannot run or simulate generated embedding. Run with "source" command line argument or install DWave Ocean.')
            return


        ans = 'y'
        if len(circuit.annealergraph.qubitbiases) > 19:
            ans = input("WARNING: Embedding uses {} qubits - ExactSolver simulation could take way too long or cause your computer to crash. Type 'y' to continue: ".format(len(circuit.annealergraph.qubitbiases)))
        
        if ans == 'y' or ans == 'Y':
            print("Simulating problem with {} qubits".format(len(circuit.annealergraph.qubitbiases)))
            qubit_biases = circuit.annealergraph.qubitbiases
            coupler_strengths = circuit.annealergraph.couplerstrengths
        
            print("\nQubit Biases:")
            for key in qubit_biases.keys():
                print(key, "\t", qubit_biases[key])
            print("\nCoupler Strengths:")
            for key in coupler_strengths.keys():
                print(key, "\t", coupler_strengths[key])
            print("\n")

            bqm = dimod.BinaryQuadraticModel(qubit_biases, coupler_strengths, 0, dimod.BINARY)
            sampler = dimod.ExactSolver()
    
            response = sampler.sample(bqm)

            groundstate = 1000000
            for sample, energy in response.data(['sample','energy']):
                if energy<groundstate:
                    groundstate = round(energy,1)
        
            print("Ground State: ", groundstate)
            function = list()
            for sample, energy in response.data(['sample', 'energy']):
                if round(energy,1) == groundstate:
                    print(sample, round(energy,1))
                    row = []
                    for inp in inputs:
                        row.append(sample[inp])
                    for outp in outputs:
                        row.append(sample[outp])
                    function.append(row)
            print('\n')

            function.sort()
            for i in range(len(function)):
                print(function[i])
        else:
            print('Quitting.')
Beispiel #13
0
                       token=token,
                       solver='DW_2000Q_2_1')

bqm = dimod.BinaryQuadraticModel(qubit_biases, coupler_strengths, 0,
                                 dimod.BINARY)

kwargs = {}
if 'num_reads' in sampler.parameters:
    kwargs['num_reads'] = numofsamples
if 'answer_mode' in sampler.parameters:
    kwargs['answer_mode'] = 'histogram'
#if 'annealing_time' in sampler.parameters:
#    kwargs['annealing_time'] = 100
print('\nRunning...')

response = sampler.sample(bqm, **kwargs)

sampler.client.close()
print('Done.')
print(response.data)

groundstate = 1000000
for sample, energy in response.data(['sample', 'energy']):
    if energy < groundstate:
        groundstate = round(energy, 1)
print('Ground State: ', groundstate)

function = list()
for sample, energy in response.data(['sample', 'energy']):
    if round(energy, 1) == groundstate:
        print(sample, round(energy, 1))
Beispiel #14
0

if manual_embed:
	# Pick the method for fixing broken chains.
	from dwave.embedding.chain_breaks import majority_vote # weighted_random
	method = majority_vote
	# Submit the job via an embedded BinaryQuadraticModel.
	from dimod import BinaryQuadraticModel as BQM
	from dwave.embedding import embed_bqm, unembed_sampleset
	# Generate a BQM from the QUBO.
	q = BQM.from_qubo(qubo)
	# Embed the BQM onto the target structure.
	embedded_q = embed_bqm(q, embedding, adjacency) # chain_strength=chain_strength, smear_vartype=dimod.SPIN
	# Collect the sample output.
	response = unembed_sampleset(
	   sampler.sample(embedded_q, num_reads=num_samples),
	   embedding, q, chain_break_method=method,
	   chain_break_fraction=True)
else:
	# Use a FixedEmbeddingComposite if we don't care about chains.
	from dwave.system.composites import FixedEmbeddingComposite
	system_composite = FixedEmbeddingComposite(sampler, embedding)
	response = system_composite.sample_qubo(qubo, num_reads=num_samples)


constant = 0

# Cycle through the results and yield them to the caller.
for out in response.data():
	# Get the output from the data.
	bits = (out.sample[b] for b in sorted(out.sample))