def test_bimodal_cluster_sampling_statistics(self): bqm = dimod.BQM.from_qubo({'ab': 1, 'bd': 1, 'dc': 1, 'ca': 1}) nodes = sorted(bqm.variables) s1 = State.from_samples(dict(zip(nodes, [0, 1, 0, 0])), bqm) s2 = State.from_samples(dict(zip(nodes, [0, 0, 1, 0])), bqm) exp1 = SampleSet.from_samples_bqm(dict(zip(nodes, [0, 0, 0, 0])), bqm) exp2 = SampleSet.from_samples_bqm(dict(zip(nodes, [0, 1, 1, 0])), bqm) icm = IsoenergeticClusterMove(seed=None) inp = States(s1, s2) exp = [exp1, exp2] # split between [exp1, exp2] and [exp2, exp1] as output samples # should be ~50% cnt = 0 n = 100 for _ in range(n): res = icm.run(inp).result() r1, r2 = pluck(res, 'samples') # test responses are valid self.assertIn(r1, exp) self.assertIn(r2, exp) # verify total samples energy doesn't change after ICM self.assertEqual(self.total_energy(inp), self.total_energy(res)) # count responses if r1 == exp1 and r2 == exp2: cnt += 1 self.assertLess(cnt, 0.75 * n) self.assertGreater(cnt, 0.25 * n)
def test_hstack_empty(self): s1 = SampleSet.empty() s2 = SampleSet.empty() exp = SampleSet.empty() res = hstack_samplesets(s1, s2) self.assertEqual(res, exp)
def test_updated(self): a = SampleSet.from_samples([1,0,1], 'SPIN', 0) b = SampleSet.from_samples([0,1,0], 'SPIN', 0) s1 = State(samples=a) s2 = State(samples=b, emb={'a': {'b': 1}}, debug={'x': 1}) s3 = State(debug={'x': {'y': {'z': [1]}}}) # test simple replace self.assertDictEqual(s1.updated(), s1) self.assertDictEqual(s1.updated(samples=b), State(samples=b)) self.assertDictEqual(s2.updated(emb={'b': 1}).emb, {'b': 1}) self.assertDictEqual(s1.updated(samples=b, debug=dict(x=1), emb={'a': {'b': 1}}), s2) # test recursive merge of `debug` self.assertDictEqual(s1.updated(debug=dict(x=1)).debug, {'x': 1}) self.assertDictEqual(s2.updated(debug=dict(x=2)).debug, {'x': 2}) self.assertDictEqual(s2.updated(debug=dict(y=2)).debug, {'x': 1, 'y': 2}) self.assertDictEqual(s2.updated(debug=dict(y=2)).debug, {'x': 1, 'y': 2}) self.assertDictEqual(s3.updated(debug={'x': {'y': {'z': [2]}}}).debug, {'x': {'y': {'z': [2]}}}) self.assertDictEqual(s3.updated(debug={'x': {'y': {'w': 2}}}).debug, {'x': {'y': {'z': [1], 'w': 2}}}) # test clear self.assertEqual(s2.updated(emb=None).emb, None) self.assertEqual(s2.updated(debug=None).debug, None)
def test_hstack(self): a = SampleSet.from_samples( [{'a': 0, 'b': 1, 'c': 0}, {'a': 1, 'b': 0, 'c': 1}], vartype='BINARY', energy=[0, 1]) b = SampleSet.from_samples( [{'d': 1, 'e': 0, 'f': 1}, {'d': 0, 'e': 1, 'f': 0}], vartype='BINARY', energy=[1, 0]) c = SampleSet.from_samples( [{'d': -1, 'e': 1, 'f': 1}], vartype='SPIN', energy=0) m = a.hstack(b, c) self.assertEqual(len(m), 1) self.assertDictEqual(dict(m.first.sample), {'a': 0, 'b': 1, 'c': 0, 'd': 0, 'e': 1, 'f': 1})
def test_default(self): """First subsample is combined with the first sample.""" state = State.from_samples(self.samples, self.problem).updated( subproblem=self.subproblem, subsamples=SampleSet.from_samples_bqm(self.subsamples, self.subproblem)) nextstate = SplatComposer().next(state) sample = {'a': 1, 'b': -1, 'c': 1} self.assertEqual(nextstate.samples, SampleSet.from_samples_bqm(sample, self.problem))
def test_traits_enforced(self): """Sample composers require `problem`, `samples` and `subsamples`.""" with self.assertRaises(traits.StateTraitMissingError): SplatComposer().run(State()).result() with self.assertRaises(traits.StateTraitMissingError): SplatComposer().run(State(problem=True)).result() self.assertTrue( # problem and samples are included by default SplatComposer().run(State( problem=self.problem, subproblem=self.subproblem, samples=SampleSet.from_samples_bqm(self.samples, self.problem), subsamples=SampleSet.from_samples_bqm(self.subsamples, self.subproblem))).result())
def test_default(self): """All subsamples are combined with all the samples.""" state = State.from_samples(self.samples, self.problem).updated( subproblem=self.subproblem, subsamples=SampleSet.from_samples_bqm(self.subsamples, self.subproblem)) nextstate = SplatComposer().next(state) self.assertEqual( nextstate.samples, SampleSet.from_samples_bqm(self.composed, self.problem))
def next(self, state, **runopts): bqm = state.subproblem sample = random_sample(bqm) sampleset = SampleSet.from_samples(sample, vartype=bqm.vartype, energy=bqm.energy(sample)) return state.updated(subsamples=sampleset)
def test_hstack_one(self): ss = dimod.SampleSet.from_samples({'a': 1}, vartype='BINARY', energy=0) emp = SampleSet.empty() self.assertEqual(hstack_samplesets(ss), ss) self.assertEqual(hstack_samplesets(ss, emp), ss) self.assertEqual(hstack_samplesets(emp, ss), ss) self.assertEqual(hstack_samplesets(ss, ss), ss)
def test_default(self): """Subsamples are copied to samples.""" state = State( subproblem=None, subsamples=SampleSet.from_samples_bqm(self.samples, self.problem)) nextstate = IdentityComposer().next(state) self.assertEqual(state.subsamples, nextstate.samples)
def test_small_lattice(self): graph = nx.generators.lattice.grid_2d_graph(5, 5) bqm = dimod.generators.uniform(graph, vartype=dimod.BINARY, low=1, high=1) nodes = sorted(bqm.variables) s1 = State.from_samples( dict( zip(nodes, [ 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0 ])), bqm) s2 = State.from_samples( dict( zip(nodes, [ 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0 ])), bqm) exp1 = SampleSet.from_samples_bqm( dict( zip(nodes, [ 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0 ])), bqm) exp2 = SampleSet.from_samples_bqm( dict( zip(nodes, [ 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0 ])), bqm) icm = IsoenergeticClusterMove(seed=1234) inp = States(s1, s2) res = icm.run(inp).result() self.assertEqual(res[0].samples, exp1) self.assertEqual(res[1].samples, exp2) # verify total samples energy doesn't change after ICM self.assertEqual(self.total_energy(inp), self.total_energy(res))
def next(self, state, **runopts): # update the first sample in `state.sampleset`, inplace # XXX: assume one global sample, one subsample # TODO: generalize sample = next(iter(state.samples.change_vartype(state.subsamples.vartype).samples())) subsample = next(iter(state.subsamples.samples())) composed_sample = updated_sample(sample, subsample) composed_energy = state.problem.energy(composed_sample) return state.updated( samples=SampleSet.from_samples(composed_sample, state.samples.vartype, composed_energy))
def test_empty(self): "At least one input sample is required." bqm = dimod.BQM.from_ising({}, {'ab': 1}) inp = State(problem=bqm, samples=None) with self.assertRaises(ValueError): ExplodeSamples().run(inp).result() inp = State(problem=bqm, samples=SampleSet.empty()) with self.assertRaises(ValueError): ExplodeSamples().run(inp).result()
def test_vstack(self): a = SampleSet.from_samples( [{'a': 1, 'b': 0, 'c': 0}, {'a': 0, 'b': 1, 'c': 0}], vartype='BINARY', energy=[3, 1]) b = SampleSet.from_samples( [{'a': 0, 'b': 0, 'c': 1}, {'a': 1, 'b': 0, 'c': 1}], vartype='BINARY', energy=[2, 0]) c = SampleSet.from_samples( [{'a': -1, 'b': 1, 'c': -1}], vartype='SPIN', energy=4) m = a.vstack(b, c) self.assertEqual(len(m), 5) self.assertEqual( list(m.samples()), [ {'a': 1, 'b': 0, 'c': 1}, # b[1], en=0 {'a': 0, 'b': 1, 'c': 0}, # a[1], en=1 {'a': 0, 'b': 0, 'c': 1}, # b[0], en=2 {'a': 1, 'b': 0, 'c': 0}, # a[0], en=3 {'a': 0, 'b': 1, 'c': 0} # c[0] in BINARY, en=4 ] )
def spread(samples): """Multiplies each sample its num_occurrences times.""" record = samples.record labels = samples.variables sample = np.repeat(record.sample, repeats=record.num_occurrences, axis=0) energy = np.repeat(record.energy, repeats=record.num_occurrences, axis=0) num_occurrences = np.ones(sum(record.num_occurrences)) return SampleSet.from_samples(samples_like=(sample, labels), vartype=samples.vartype, energy=energy, num_occurrences=num_occurrences, info=copy.deepcopy(samples.info))
def next(self, state, **runopts): # update the first sample in `state.sampleset`, inplace # XXX: assume one global sample, one subsample # TODO: generalize sample = next( iter( state.samples.change_vartype( state.subsamples.vartype).samples())) subsample = next(iter(state.subsamples.samples())) sample_energy = state.problem.energy(sample) composed_sample = updated_sample(sample, subsample) composed_energy = state.problem.energy(composed_sample) logger.debug("{name} subsample (len={sslen}) -> sample (len={slen}), " "sample energy changed {old_en} -> {new_en}".format( name=self.name, sslen=len(subsample), slen=len(sample), old_en=sample_energy, new_en=composed_energy)) return state.updated(samples=SampleSet.from_samples( composed_sample, state.samples.vartype, composed_energy))
def next(self, states, **runopts): state_thesis, state_antithesis = states bqm = state_thesis.problem thesis = dict(state_thesis.samples.first.sample) thesis_en = state_thesis.samples.first.energy antithesis = dict(state_antithesis.samples.first.sample) synthesis = thesis.copy() synthesis_en = thesis_en # input sanity check # TODO: convert to hard input validation assert len(thesis) == len(antithesis) assert state_thesis.problem == state_antithesis.problem diff = {v for v in thesis if thesis[v] != antithesis[v]} while diff: flip_energies = flip_energy_gains(bqm, thesis, diff) en, v = flip_energies[-1] diff.remove(v) thesis[v] = antithesis[v] thesis_en += en if thesis_en <= synthesis_en: # note EQ also, because we want the latest thesis synthesis = thesis.copy() synthesis_en = thesis_en synthesis_samples = SampleSet.from_samples_bqm(synthesis, bqm) # calculation sanity check assert synthesis_samples.first.energy == synthesis_en return state_thesis.updated(samples=synthesis_samples)
def test_from_samples_bqm(self): bqm = dimod.BinaryQuadraticModel({}, {'ab': 1}, 0, dimod.SPIN) ss = SampleSet.from_samples_bqm({'a': 1, 'b': -1}, bqm) self.assertEqual(ss.first.energy, -1)
def test_empty(self): empty = SampleSet.empty() self.assertEqual(len(empty), 0) impliedempty = SampleSet() self.assertEqual(impliedempty, empty)
def test_default(self): ss = dimod.SampleSet.from_samples([1], dimod.SPIN, [0]) self.assertEqual( ss, SampleSet(ss.record, ss.variables, ss.info, ss.vartype))