Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Features/init state #19

Merged
merged 4 commits into from
Apr 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 8 additions & 2 deletions openjij/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,21 @@ PYBIND11_MODULE(cxxjij, m){
py::class_<method::ClassicalIsing>(m_method, "ClassicalIsing")
.def(py::init<const graph::Dense<double>&>(), "other"_a)
.def(py::init<const graph::Sparse<double>&>(), "other"_a)
.def(py::init<const graph::Sparse<double>&, 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("initialize_spins", &method::ClassicalIsing::initialize_spins)
.def("set_spins", &method::ClassicalIsing::set_spins, "initial_state"_a);

//QuantumIsing
py::class_<method::QuantumIsing>(m_method, "QuantumIsing")
.def(py::init<const graph::Dense<double>&, size_t>(), "other"_a, "num_trotter_slices"_a)
.def(py::init<const graph::Sparse<double>&, size_t>(), "other"_a, "num_trotter_slices"_a)
.def(py::init<const graph::Sparse<double>&, 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("initialize_spins", &method::QuantumIsing::initialize_spins)
.def("set_spins", &method::QuantumIsing::set_spins, "initial_state"_a);

#ifdef USE_CUDA
py::class_<method::ChimeraGPUQuantum>(m_method, "ChimeraGPUQuantum")
Expand Down
15 changes: 15 additions & 0 deletions src/method/classical_ising.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@ namespace openjij {
uid = std::uniform_int_distribution<>{0,(int)spins.size()-1};
}

ClassicalIsing::ClassicalIsing(const graph::Dense<double>& 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::initialize_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;
size_t num_spins = spins.size();
Expand Down
4 changes: 4 additions & 0 deletions src/method/classical_ising.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ namespace openjij {

public:
ClassicalIsing(const graph::Dense<double>& interaction);
ClassicalIsing(const graph::Dense<double>& interaction, graph::Spins& spins);

void initialize_spins();
void set_spins(graph::Spins& initial_spins);

virtual double update(double beta, const std::string& algo = "") override;

Expand Down
29 changes: 29 additions & 0 deletions src/method/quantum_ising.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,35 @@ namespace openjij {
return (a+spins.size())%spins.size();
}

void QuantumIsing::initialize_spins(){
for (auto& elem : spins){
elem = interaction.gen_spin();
}
}

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<double>& 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<double>& interaction, size_t num_trotter_slices)
:spins(num_trotter_slices), interaction(interaction), urd{0.0, 1.0}{
//TODO: add exception
Expand Down
4 changes: 4 additions & 0 deletions src/method/quantum_ising.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ namespace openjij {

public:
QuantumIsing(const graph::Dense<double>& interaction, size_t num_trotter_slices);
QuantumIsing(const graph::Dense<double>& interaction, size_t num_trotter_slices, graph::Spins& classical_spins);

void initialize_spins();
void set_spins(graph::Spins& initial_spin);

virtual double update(double beta, double gamma, const std::string& algo = "") override;

Expand Down
68 changes: 51 additions & 17 deletions tests/cxxtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,24 +43,58 @@ 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<double> 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_initialize){
size_t N=10;
openjij::graph::Dense<double> dense(N);
openjij::method::ClassicalIsing cising(dense);
openjij::graph::Spins spins = cising.get_spins();

cising.initialize_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_initialize){
size_t N=10;
size_t trotter = 5;
openjij::graph::Dense<double> dense(N);
openjij::method::QuantumIsing qising(dense, trotter);
openjij::method::TrotterSpins spins = qising.get_spins();

qising.initialize_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);
}

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));
}

// }
// //---------------------------------------------

// // ---------- Updater Test -------------------------
// class UpdaterTest: public ::testing::Test{
Expand Down
19 changes: 19 additions & 0 deletions tests/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import numpy as np

import openjij as oj
import cxxjij as cj

# class UtilsTest(unittest.TestCase):

Expand Down Expand Up @@ -85,6 +86,24 @@ 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.initialize_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)

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!
unittest.main()