From 2f11e0e6be87fa2557b72ccc7327be31e9cb605e Mon Sep 17 00:00:00 2001 From: yu yamashiro Date: Mon, 22 Apr 2019 19:26:49 +0900 Subject: [PATCH 1/4] add initilize of spin function to c++ code --- src/method/classical_ising.cpp | 12 +++++++ src/method/classical_ising.h | 3 ++ src/method/quantum_ising.cpp | 20 ++++++++++++ src/method/quantum_ising.h | 4 +++ tests/cxxtest.cpp | 59 ++++++++++++++++++++++++---------- 5 files changed, 81 insertions(+), 17 deletions(-) diff --git a/src/method/classical_ising.cpp b/src/method/classical_ising.cpp index 604f667eb..ee72dec9c 100644 --- a/src/method/classical_ising.cpp +++ b/src/method/classical_ising.cpp @@ -14,6 +14,18 @@ namespace openjij { uid = std::uniform_int_distribution<>{0,(int)spins.size()-1}; } + ClassicalIsing::ClassicalIsing(const graph::Dense& interaction, graph::Spins& spins) + : spins(spins), interaction(interaction), urd{0.0, 1.0}{ + //random number generator + std::random_device rd; + mt = std::mt19937(rd()); + uid = std::uniform_int_distribution<>{0,(int)spins.size()-1}; + } + + void ClassicalIsing::initialze_spins(){ + spins = interaction.gen_spin(); + } + double ClassicalIsing::update(double beta, const std::string& algo){ double totaldE = 0; size_t num_spins = spins.size(); diff --git a/src/method/classical_ising.h b/src/method/classical_ising.h index ffd685feb..9f2876f8e 100644 --- a/src/method/classical_ising.h +++ b/src/method/classical_ising.h @@ -21,6 +21,9 @@ namespace openjij { public: ClassicalIsing(const graph::Dense& interaction); + ClassicalIsing(const graph::Dense& interaction, graph::Spins& spins); + + void initialze_spins(); virtual double update(double beta, const std::string& algo = "") override; diff --git a/src/method/quantum_ising.cpp b/src/method/quantum_ising.cpp index 614371650..f5a7d6b2b 100644 --- a/src/method/quantum_ising.cpp +++ b/src/method/quantum_ising.cpp @@ -12,6 +12,26 @@ namespace openjij { return (a+spins.size())%spins.size(); } + void QuantumIsing::initilize_spins(){ + for (auto& elem : spins){ + elem = interaction.gen_spin(); + } + } + + QuantumIsing::QuantumIsing(const graph::Dense& interaction, size_t num_trotter_slices, graph::Spins& classical_spins) + :spins(num_trotter_slices), interaction(interaction), urd{0.0, 1.0}{ + for(auto& elem : spins){ + elem = classical_spins; + + //random number generators + std::random_device rd; + mt = std::mt19937(rd()); + uid = std::uniform_int_distribution<>{0, (int)elem.size()-1}; + uid_trotter = std::uniform_int_distribution<>{0, (int)num_trotter_slices-1}; + } + assert(spins.size() != 0 and spins[0].size() != 0); + } + QuantumIsing::QuantumIsing(const graph::Dense& interaction, size_t num_trotter_slices) :spins(num_trotter_slices), interaction(interaction), urd{0.0, 1.0}{ //TODO: add exception diff --git a/src/method/quantum_ising.h b/src/method/quantum_ising.h index 296fe5148..09594bad0 100644 --- a/src/method/quantum_ising.h +++ b/src/method/quantum_ising.h @@ -27,6 +27,10 @@ namespace openjij { public: QuantumIsing(const graph::Dense& interaction, size_t num_trotter_slices); + QuantumIsing(const graph::Dense& interaction, size_t num_trotter_slices, graph::Spins& classical_spins); + + void initilize_spins(); + virtual double update(double beta, double gamma, const std::string& algo = "") override; diff --git a/tests/cxxtest.cpp b/tests/cxxtest.cpp index 5cb1b00be..d1996b0c4 100644 --- a/tests/cxxtest.cpp +++ b/tests/cxxtest.cpp @@ -43,24 +43,49 @@ TEST(OpenJijTest, spin_matrix){ // EXPECT_ANY_THROW({int_mat(4, 0) = 1.0;}); } -// TEST(OpenJijTest, energy){ -// int N = 3; -// openjij::Spins spins(N, 1); -// openjij::SquareMatrix int_mat{N, 0.0}; -// // H = -s0 * s1 - s1 * s2 - s0 - s2 -// int_mat(0, 0) = -1.0; -// int_mat(0, 1) = -1.0; -// int_mat(1, 0) = -1.0; -// int_mat(1, 2) = -1.0; -// int_mat(2, 1) = -1.0; -// int_mat(2, 2) = -1.0; - -// openjij::sampler::Sampler samp(int_mat); -// double energy = samp.calc_energy(spins); -// ASSERT_EQ(energy, -4.0); +TEST(OpenJijTest, classicalIsing_initilize){ + size_t N=10; + openjij::graph::Dense dense(N); + openjij::method::ClassicalIsing cising(dense); + openjij::graph::Spins spins = cising.get_spins(); + + cising.initialze_spins(); + + openjij::graph::Spins new_spins = cising.get_spins(); + + EXPECT_NE(spins, new_spins); + + // input initial state + openjij::graph::Spins init_spins(N, 1); + openjij::method::ClassicalIsing input_cising(dense, init_spins); + spins = input_cising.get_spins(); + EXPECT_EQ(init_spins, spins); +} + +TEST(OpenJijTest, quantumIsing_initilize){ + size_t N=10; + size_t trotter = 5; + openjij::graph::Dense dense(N); + openjij::method::QuantumIsing qising(dense, trotter); + openjij::method::TrotterSpins spins = qising.get_spins(); + + qising.initilize_spins(); + + openjij::method::TrotterSpins new_spins = qising.get_spins(); + + for(int i=0; i < spins.size(); i++){ + EXPECT_NE(spins[i], new_spins[i]); + } + + // input initial state + openjij::graph::Spins init_classical_spins(N, 1); + openjij::method::QuantumIsing input_qising(dense, trotter, init_classical_spins); + spins = input_qising.get_spins(); + for(openjij::graph::Spins c_spin : spins){ + EXPECT_EQ(init_classical_spins, c_spin); + } +} -// } -// //--------------------------------------------- // // ---------- Updater Test ------------------------- // class UpdaterTest: public ::testing::Test{ From c6c91ee7b8d9facd17099961e5fb17733867f985 Mon Sep 17 00:00:00 2001 From: yu yamashiro Date: Mon, 22 Apr 2019 20:58:08 +0900 Subject: [PATCH 2/4] add pybind interface --- openjij/main.cpp | 8 ++++++-- src/method/classical_ising.cpp | 2 +- src/method/classical_ising.h | 2 +- tests/cxxtest.cpp | 2 +- tests/test.py | 14 ++++++++++++++ 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/openjij/main.cpp b/openjij/main.cpp index e90435fc9..fbb903e6c 100644 --- a/openjij/main.cpp +++ b/openjij/main.cpp @@ -126,15 +126,19 @@ PYBIND11_MODULE(cxxjij, m){ py::class_(m_method, "ClassicalIsing") .def(py::init&>(), "other"_a) .def(py::init&>(), "other"_a) + .def(py::init&, graph::Spins&>(), "other"_a, "init_state"_a) .def("simulated_annealing", &method::ClassicalIsing::simulated_annealing, "beta_min"_a, "beta_max"_a, "step_length"_a, "step_num"_a, "algo"_a="") - .def("get_spins", &method::ClassicalIsing::get_spins); + .def("get_spins", &method::ClassicalIsing::get_spins) + .def("initilize_spins", &method::ClassicalIsing::initilize_spins); //QuantumIsing py::class_(m_method, "QuantumIsing") .def(py::init&, size_t>(), "other"_a, "num_trotter_slices"_a) .def(py::init&, size_t>(), "other"_a, "num_trotter_slices"_a) + .def(py::init&, size_t, graph::Spins&>(), "other"_a, "num_trotter_slices"_a, "init_state"_a) .def("simulated_quantum_annealing", &method::QuantumIsing::simulated_quantum_annealing, "beta"_a, "gamma_min"_a, "gamma_max"_a, "step_length"_a, "step_num"_a, "algo"_a="") - .def("get_spins", &method::QuantumIsing::get_spins); + .def("get_spins", &method::QuantumIsing::get_spins) + .def("initilize_spins", &method::QuantumIsing::initilize_spins); #ifdef USE_CUDA py::class_(m_method, "ChimeraGPUQuantum") diff --git a/src/method/classical_ising.cpp b/src/method/classical_ising.cpp index ee72dec9c..86c35328c 100644 --- a/src/method/classical_ising.cpp +++ b/src/method/classical_ising.cpp @@ -22,7 +22,7 @@ namespace openjij { uid = std::uniform_int_distribution<>{0,(int)spins.size()-1}; } - void ClassicalIsing::initialze_spins(){ + void ClassicalIsing::initilize_spins(){ spins = interaction.gen_spin(); } diff --git a/src/method/classical_ising.h b/src/method/classical_ising.h index 9f2876f8e..f838058c5 100644 --- a/src/method/classical_ising.h +++ b/src/method/classical_ising.h @@ -23,7 +23,7 @@ namespace openjij { ClassicalIsing(const graph::Dense& interaction); ClassicalIsing(const graph::Dense& interaction, graph::Spins& spins); - void initialze_spins(); + void initilize_spins(); virtual double update(double beta, const std::string& algo = "") override; diff --git a/tests/cxxtest.cpp b/tests/cxxtest.cpp index d1996b0c4..ae7cbb129 100644 --- a/tests/cxxtest.cpp +++ b/tests/cxxtest.cpp @@ -49,7 +49,7 @@ TEST(OpenJijTest, classicalIsing_initilize){ openjij::method::ClassicalIsing cising(dense); openjij::graph::Spins spins = cising.get_spins(); - cising.initialze_spins(); + cising.initilize_spins(); openjij::graph::Spins new_spins = cising.get_spins(); diff --git a/tests/test.py b/tests/test.py index 98d345cd5..67f6e9fd1 100644 --- a/tests/test.py +++ b/tests/test.py @@ -2,6 +2,7 @@ import numpy as np import openjij as oj +import cxxjij as cj # class UtilsTest(unittest.TestCase): @@ -85,6 +86,19 @@ def test_gpu_sqa(self): chimera = gpu_sampler._chimera_graph(model, chimera_L=10) +class CXXTest(unittest.TestCase): + def test_system(self): + N = 10 + graph = cj.graph.Dense(N) + q_ising = cj.method.QuantumIsing(graph, 3) + spins = q_ising.get_spins() + q_ising.initilize_spins() + new_spins = q_ising.get_spins() + for spin, n_spin in zip(spins, new_spins): + not_eq = spins == new_spins + self.assertFalse(not_eq) + + if __name__ == '__main__': # test is currently disabled. TODO: write test! unittest.main() From a6ec52531c4dfcdad3a6ff2642b0cd9ab146ede9 Mon Sep 17 00:00:00 2001 From: yu yamashiro Date: Mon, 22 Apr 2019 21:31:43 +0900 Subject: [PATCH 3/4] add set spins --- openjij/main.cpp | 6 ++++-- src/method/classical_ising.cpp | 3 +++ src/method/classical_ising.h | 1 + src/method/quantum_ising.cpp | 9 +++++++++ src/method/quantum_ising.h | 2 +- tests/cxxtest.cpp | 9 +++++++++ tests/test.py | 5 +++++ 7 files changed, 32 insertions(+), 3 deletions(-) diff --git a/openjij/main.cpp b/openjij/main.cpp index fbb903e6c..89a01aa90 100644 --- a/openjij/main.cpp +++ b/openjij/main.cpp @@ -129,7 +129,8 @@ PYBIND11_MODULE(cxxjij, m){ .def(py::init&, graph::Spins&>(), "other"_a, "init_state"_a) .def("simulated_annealing", &method::ClassicalIsing::simulated_annealing, "beta_min"_a, "beta_max"_a, "step_length"_a, "step_num"_a, "algo"_a="") .def("get_spins", &method::ClassicalIsing::get_spins) - .def("initilize_spins", &method::ClassicalIsing::initilize_spins); + .def("initilize_spins", &method::ClassicalIsing::initilize_spins) + .def("set_spins", &method::ClassicalIsing::set_spins, "initial_state"_a); //QuantumIsing py::class_(m_method, "QuantumIsing") @@ -138,7 +139,8 @@ PYBIND11_MODULE(cxxjij, m){ .def(py::init&, size_t, graph::Spins&>(), "other"_a, "num_trotter_slices"_a, "init_state"_a) .def("simulated_quantum_annealing", &method::QuantumIsing::simulated_quantum_annealing, "beta"_a, "gamma_min"_a, "gamma_max"_a, "step_length"_a, "step_num"_a, "algo"_a="") .def("get_spins", &method::QuantumIsing::get_spins) - .def("initilize_spins", &method::QuantumIsing::initilize_spins); + .def("initilize_spins", &method::QuantumIsing::initilize_spins) + .def("set_spins", &method::QuantumIsing::set_spins, "initial_state"_a); #ifdef USE_CUDA py::class_(m_method, "ChimeraGPUQuantum") diff --git a/src/method/classical_ising.cpp b/src/method/classical_ising.cpp index 86c35328c..54cc42191 100644 --- a/src/method/classical_ising.cpp +++ b/src/method/classical_ising.cpp @@ -25,6 +25,9 @@ namespace openjij { void ClassicalIsing::initilize_spins(){ spins = interaction.gen_spin(); } + void ClassicalIsing::set_spins(graph::Spins& initial_spins){ + spins = initial_spins; + } double ClassicalIsing::update(double beta, const std::string& algo){ double totaldE = 0; diff --git a/src/method/classical_ising.h b/src/method/classical_ising.h index f838058c5..53cbf8fd0 100644 --- a/src/method/classical_ising.h +++ b/src/method/classical_ising.h @@ -24,6 +24,7 @@ namespace openjij { ClassicalIsing(const graph::Dense& interaction, graph::Spins& spins); void initilize_spins(); + void set_spins(graph::Spins& initial_spins); virtual double update(double beta, const std::string& algo = "") override; diff --git a/src/method/quantum_ising.cpp b/src/method/quantum_ising.cpp index f5a7d6b2b..34a190ea9 100644 --- a/src/method/quantum_ising.cpp +++ b/src/method/quantum_ising.cpp @@ -18,6 +18,15 @@ namespace openjij { } } + void QuantumIsing::set_spins(graph::Spins& initial_spin){ + if(spins[0].size() != initial_spin.size()){ + throw "Exception : spin size not match."; + } + for (auto& elem : spins){ + elem = initial_spin; + } + } + QuantumIsing::QuantumIsing(const graph::Dense& interaction, size_t num_trotter_slices, graph::Spins& classical_spins) :spins(num_trotter_slices), interaction(interaction), urd{0.0, 1.0}{ for(auto& elem : spins){ diff --git a/src/method/quantum_ising.h b/src/method/quantum_ising.h index 09594bad0..07ca7fa0f 100644 --- a/src/method/quantum_ising.h +++ b/src/method/quantum_ising.h @@ -30,7 +30,7 @@ namespace openjij { QuantumIsing(const graph::Dense& interaction, size_t num_trotter_slices, graph::Spins& classical_spins); void initilize_spins(); - + void set_spins(graph::Spins& initial_spin); virtual double update(double beta, double gamma, const std::string& algo = "") override; diff --git a/tests/cxxtest.cpp b/tests/cxxtest.cpp index ae7cbb129..ac5968e6e 100644 --- a/tests/cxxtest.cpp +++ b/tests/cxxtest.cpp @@ -84,6 +84,15 @@ TEST(OpenJijTest, quantumIsing_initilize){ for(openjij::graph::Spins c_spin : spins){ EXPECT_EQ(init_classical_spins, c_spin); } + + openjij::graph::Spins c_spin(N, 1); + qising.set_spins(c_spin); + for(openjij::graph::Spins cc_spins : qising.get_spins()){ + EXPECT_EQ(cc_spins, c_spin); + } + + openjij::graph::Spins small_state(5, 1); + ASSERT_ANY_THROW(qising.set_spins(small_state)); } diff --git a/tests/test.py b/tests/test.py index 67f6e9fd1..8a883988a 100644 --- a/tests/test.py +++ b/tests/test.py @@ -98,6 +98,11 @@ def test_system(self): not_eq = spins == new_spins self.assertFalse(not_eq) + initial_state = [1] * N + q_ising.set_spins(initial_state) + for spin in q_ising.get_spins(): + self.assertEqual(initial_state, spin) + if __name__ == '__main__': # test is currently disabled. TODO: write test! From eb468172f70e77cd9fc96a94fe6b2b28305d4636 Mon Sep 17 00:00:00 2001 From: yu yamashiro Date: Mon, 22 Apr 2019 21:35:02 +0900 Subject: [PATCH 4/4] fix typo --- openjij/main.cpp | 4 ++-- src/method/classical_ising.cpp | 2 +- src/method/classical_ising.h | 2 +- src/method/quantum_ising.cpp | 2 +- src/method/quantum_ising.h | 2 +- tests/cxxtest.cpp | 8 ++++---- tests/test.py | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/openjij/main.cpp b/openjij/main.cpp index 89a01aa90..07c809edd 100644 --- a/openjij/main.cpp +++ b/openjij/main.cpp @@ -129,7 +129,7 @@ PYBIND11_MODULE(cxxjij, m){ .def(py::init&, graph::Spins&>(), "other"_a, "init_state"_a) .def("simulated_annealing", &method::ClassicalIsing::simulated_annealing, "beta_min"_a, "beta_max"_a, "step_length"_a, "step_num"_a, "algo"_a="") .def("get_spins", &method::ClassicalIsing::get_spins) - .def("initilize_spins", &method::ClassicalIsing::initilize_spins) + .def("initialize_spins", &method::ClassicalIsing::initialize_spins) .def("set_spins", &method::ClassicalIsing::set_spins, "initial_state"_a); //QuantumIsing @@ -139,7 +139,7 @@ PYBIND11_MODULE(cxxjij, m){ .def(py::init&, size_t, graph::Spins&>(), "other"_a, "num_trotter_slices"_a, "init_state"_a) .def("simulated_quantum_annealing", &method::QuantumIsing::simulated_quantum_annealing, "beta"_a, "gamma_min"_a, "gamma_max"_a, "step_length"_a, "step_num"_a, "algo"_a="") .def("get_spins", &method::QuantumIsing::get_spins) - .def("initilize_spins", &method::QuantumIsing::initilize_spins) + .def("initialize_spins", &method::QuantumIsing::initialize_spins) .def("set_spins", &method::QuantumIsing::set_spins, "initial_state"_a); #ifdef USE_CUDA diff --git a/src/method/classical_ising.cpp b/src/method/classical_ising.cpp index 54cc42191..3eac8fc59 100644 --- a/src/method/classical_ising.cpp +++ b/src/method/classical_ising.cpp @@ -22,7 +22,7 @@ namespace openjij { uid = std::uniform_int_distribution<>{0,(int)spins.size()-1}; } - void ClassicalIsing::initilize_spins(){ + void ClassicalIsing::initialize_spins(){ spins = interaction.gen_spin(); } void ClassicalIsing::set_spins(graph::Spins& initial_spins){ diff --git a/src/method/classical_ising.h b/src/method/classical_ising.h index 53cbf8fd0..40360dd24 100644 --- a/src/method/classical_ising.h +++ b/src/method/classical_ising.h @@ -23,7 +23,7 @@ namespace openjij { ClassicalIsing(const graph::Dense& interaction); ClassicalIsing(const graph::Dense& interaction, graph::Spins& spins); - void initilize_spins(); + void initialize_spins(); void set_spins(graph::Spins& initial_spins); virtual double update(double beta, const std::string& algo = "") override; diff --git a/src/method/quantum_ising.cpp b/src/method/quantum_ising.cpp index 34a190ea9..9f43025a4 100644 --- a/src/method/quantum_ising.cpp +++ b/src/method/quantum_ising.cpp @@ -12,7 +12,7 @@ namespace openjij { return (a+spins.size())%spins.size(); } - void QuantumIsing::initilize_spins(){ + void QuantumIsing::initialize_spins(){ for (auto& elem : spins){ elem = interaction.gen_spin(); } diff --git a/src/method/quantum_ising.h b/src/method/quantum_ising.h index 07ca7fa0f..9f18a155f 100644 --- a/src/method/quantum_ising.h +++ b/src/method/quantum_ising.h @@ -29,7 +29,7 @@ namespace openjij { QuantumIsing(const graph::Dense& interaction, size_t num_trotter_slices); QuantumIsing(const graph::Dense& interaction, size_t num_trotter_slices, graph::Spins& classical_spins); - void initilize_spins(); + void initialize_spins(); void set_spins(graph::Spins& initial_spin); virtual double update(double beta, double gamma, const std::string& algo = "") override; diff --git a/tests/cxxtest.cpp b/tests/cxxtest.cpp index ac5968e6e..cd18009d8 100644 --- a/tests/cxxtest.cpp +++ b/tests/cxxtest.cpp @@ -43,13 +43,13 @@ TEST(OpenJijTest, spin_matrix){ // EXPECT_ANY_THROW({int_mat(4, 0) = 1.0;}); } -TEST(OpenJijTest, classicalIsing_initilize){ +TEST(OpenJijTest, classicalIsing_initialize){ size_t N=10; openjij::graph::Dense dense(N); openjij::method::ClassicalIsing cising(dense); openjij::graph::Spins spins = cising.get_spins(); - cising.initilize_spins(); + cising.initialize_spins(); openjij::graph::Spins new_spins = cising.get_spins(); @@ -62,14 +62,14 @@ TEST(OpenJijTest, classicalIsing_initilize){ EXPECT_EQ(init_spins, spins); } -TEST(OpenJijTest, quantumIsing_initilize){ +TEST(OpenJijTest, quantumIsing_initialize){ size_t N=10; size_t trotter = 5; openjij::graph::Dense dense(N); openjij::method::QuantumIsing qising(dense, trotter); openjij::method::TrotterSpins spins = qising.get_spins(); - qising.initilize_spins(); + qising.initialize_spins(); openjij::method::TrotterSpins new_spins = qising.get_spins(); diff --git a/tests/test.py b/tests/test.py index 8a883988a..ff9f52f59 100644 --- a/tests/test.py +++ b/tests/test.py @@ -92,7 +92,7 @@ def test_system(self): graph = cj.graph.Dense(N) q_ising = cj.method.QuantumIsing(graph, 3) spins = q_ising.get_spins() - q_ising.initilize_spins() + q_ising.initialize_spins() new_spins = q_ising.get_spins() for spin, n_spin in zip(spins, new_spins): not_eq = spins == new_spins