Loading examples/qsim/TdWorkflowHeisenbergModel.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -34,7 +34,7 @@ int main(int argc, char **argv) { // *steps // 20 auto workflow = qsim::getWorkflow( "td-evolution", {{"method", "trotter"}, {"dt", 3.0}, {"steps", 20}}); "td-evolution", {{"dt", 3.0}, {"steps", 20}}); // Result should contain the observable expectation value along Trotter steps. auto result = workflow->execute(problemModel); Loading lib/qsim/base/qcor_qsim.cpp +39 −27 Original line number Diff line number Diff line Loading @@ -39,9 +39,12 @@ ModelBuilder::createModel(Observable *obs, const HeterogeneousMap ¶ms) { QuantumSimulationModel ModelBuilder::createModel(ModelType type, const HeterogeneousMap ¶ms) { if (type == ModelType::Heisenberg) { HeisenbergModel hs_model; hs_model.fromDict(params); if (!hs_model.validateModel()) { // Static internal HeisenbergModel struct // (keep alive to form time-depenedent Hamiltonian operator) static std::unique_ptr<HeisenbergModel> hs_model; hs_model = std::make_unique<HeisenbergModel>(); hs_model->fromDict(params); if (!hs_model->validateModel()) { qcor::error( "Failed to validate the input parameters for the Heisenberg model."); } Loading @@ -49,38 +52,41 @@ ModelBuilder::createModel(ModelType type, const HeterogeneousMap ¶ms) { QuantumSimulationModel model; // Observable = average magnetization auto observable = new qcor::PauliOperator; for (int i = 0; i < hs_model.num_spins; ++i) { (*observable) += ((1.0/hs_model.num_spins) * Z(i)); for (int i = 0; i < hs_model->num_spins; ++i) { (*observable) += ((1.0/hs_model->num_spins) * Z(i)); } model.observable = observable; qsim::TdObservable H = [&](double t) { qcor::PauliOperator tdOp; for (int i = 0; i < hs_model.num_spins - 1; ++i) { if (hs_model.Jx != 0.0) { tdOp += (hs_model.Jx * (X(i) * X(i + 1))); for (int i = 0; i < hs_model->num_spins - 1; ++i) { if (hs_model->Jx != 0.0) { tdOp += ((hs_model->Jx / hs_model->H_BAR) * (X(i) * X(i + 1))); } if (hs_model.Jy != 0.0) { tdOp += (hs_model.Jy * (Y(i) * Y(i + 1))); if (hs_model->Jy != 0.0) { tdOp += ((hs_model->Jy / hs_model->H_BAR) * (Y(i) * Y(i + 1))); } if (hs_model.Jz != 0.0) { tdOp += (hs_model.Jz * (Z(i) * Z(i + 1))); if (hs_model->Jz != 0.0) { tdOp += ((hs_model->Jz / hs_model->H_BAR) * (Z(i) * Z(i + 1))); } } std::function<double(double)> time_dep_func; if (hs_model.time_func) { time_dep_func = hs_model.time_func; if (hs_model->time_func) { time_dep_func = hs_model->time_func; } else { time_dep_func = [&](double time) { return std::cos(hs_model.freq * time); }; } if (hs_model.h_ext != 0.0) { for (int i = 0; i < hs_model.num_spins; ++i) { if (hs_model.ext_dir == "X") { tdOp += (hs_model.h_ext * time_dep_func(t) * X(i)); } else if (hs_model.ext_dir == "Y") { tdOp += (hs_model.h_ext * time_dep_func(t) * Y(i)); time_dep_func = [&](double time) { return std::cos(hs_model->freq * time); }; } if (hs_model->h_ext != 0.0) { for (int i = 0; i < hs_model->num_spins; ++i) { if (hs_model->ext_dir == "X") { tdOp += ((hs_model->h_ext / hs_model->H_BAR) * time_dep_func(t) * X(i)); } else if (hs_model->ext_dir == "Y") { tdOp += ((hs_model->h_ext / hs_model->H_BAR) * time_dep_func(t) * Y(i)); } else { tdOp += (hs_model.h_ext * time_dep_func(t) * Z(i)); tdOp += ((hs_model->h_ext / hs_model->H_BAR) * time_dep_func(t) * Z(i)); } } } Loading @@ -90,12 +96,12 @@ ModelBuilder::createModel(ModelType type, const HeterogeneousMap ¶ms) { model.hamiltonian = H; // Non-zero initial spin state: if (std::find(hs_model.initial_spins.begin(), hs_model.initial_spins.end(), 1) != hs_model.initial_spins.end()) { if (std::find(hs_model->initial_spins.begin(), hs_model->initial_spins.end(), 1) != hs_model->initial_spins.end()) { auto initialSpinPrep = qcor::__internal__::create_composite("InitialSpin"); auto provider = qcor::__internal__::get_provider(); for (int i = 0; i < hs_model.initial_spins.size(); ++i) { if (hs_model.initial_spins[i] == 1) { for (int i = 0; i < hs_model->initial_spins.size(); ++i) { if (hs_model->initial_spins[i] == 1) { initialSpinPrep->addInstruction(provider->createInstruction("X", i)); } } Loading Loading @@ -147,14 +153,20 @@ void ModelBuilder::HeisenbergModel::fromDict(const HeterogeneousMap ¶ms) { } }; // Handle exact types (int, double) getKeyIfExists(Jx, "Jx"); getKeyIfExists(Jy, "Jy"); getKeyIfExists(Jz, "Jz"); getKeyIfExists(ext_dir, "ext_dir"); getKeyIfExists(h_ext, "h_ext"); getKeyIfExists(H_BAR, "H_BAR"); getKeyIfExists(num_spins, "num_spins"); getKeyIfExists(initial_spins, "initial_spins"); getKeyIfExists(time_func, "time_func"); getKeyIfExists(freq, "freq"); // Handle string-like if (params.stringExists("ext_dir")) { ext_dir = params.getString("ext_dir"); } } } // namespace qsim } // namespace qcor No newline at end of file lib/qsim/base/qcor_qsim.hpp +3 −1 Original line number Diff line number Diff line Loading @@ -91,9 +91,11 @@ public: double Jy = 0.0; double Jz = 0.0; double h_ext = 0.0; // Support for H_BAR normalization double H_BAR = 1.0; // "X", "Y", or "Z" std::string ext_dir = "Z"; size_t num_spins = 2; int num_spins = 2; std::vector<int> initial_spins; // Time-dependent freq. // Default to using the cosine function. Loading python/examples/qsim_heisenberg_model.py 0 → 100644 +29 −0 Original line number Diff line number Diff line import sys, os from pathlib import Path sys.path.insert(1, str(Path.home()) + "/.xacc") from qcor import * import numpy as np import matplotlib.pyplot as plt # Demonstrate Heisenberg model (ArQTiC format) input problemModel = qsim.ModelBuilder.createModel(ModelType.Heisenberg, {'Jz': 0.01183898, 'h_ext': 0.01183898, 'freq': 0.0048, 'ext_dir': 'X', 'num_spins': 3}) # Run TD workflow: workflow = qsim.getWorkflow( 'td-evolution', {'dt': 3.0, 'steps': 20}) result = workflow.execute(problemModel) # Plot the result: t = np.linspace(0, 60, 21) y = result["exp-vals"] axes = plt.axes() axes.plot(t, y) axes.set_xlim([0,60]) axes.set_ylim([0,1]) # Save the plot to a file: os.chdir(os.path.dirname(os.path.abspath(__file__))) plt.savefig("avg_magnetization_plot.pdf") No newline at end of file python/py-qcor.cpp +12 −2 Original line number Diff line number Diff line Loading @@ -732,8 +732,18 @@ PYBIND11_MODULE(_pyqcor, m) { [](qcor::PauliOperator &obs) { return qcor::qsim::ModelBuilder::createModel(obs); }, ""); "") .def( "createModel", [](qcor::qsim::ModelBuilder::ModelType type, PyHeterogeneousMap ¶ms) { auto nativeHetMap = heterogeneousMapConvert(params); return qcor::qsim::ModelBuilder::createModel(type, nativeHetMap); }, "Create a model of a supported type."); py::enum_<qcor::qsim::ModelBuilder::ModelType>(m, "ModelType") .value("Heisenberg", qcor::qsim::ModelBuilder::ModelType::Heisenberg) .export_values(); // CostFunctionEvaluator bindings py::class_<qcor::qsim::CostFunctionEvaluator, std::shared_ptr<qcor::qsim::CostFunctionEvaluator>, Loading Loading
examples/qsim/TdWorkflowHeisenbergModel.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -34,7 +34,7 @@ int main(int argc, char **argv) { // *steps // 20 auto workflow = qsim::getWorkflow( "td-evolution", {{"method", "trotter"}, {"dt", 3.0}, {"steps", 20}}); "td-evolution", {{"dt", 3.0}, {"steps", 20}}); // Result should contain the observable expectation value along Trotter steps. auto result = workflow->execute(problemModel); Loading
lib/qsim/base/qcor_qsim.cpp +39 −27 Original line number Diff line number Diff line Loading @@ -39,9 +39,12 @@ ModelBuilder::createModel(Observable *obs, const HeterogeneousMap ¶ms) { QuantumSimulationModel ModelBuilder::createModel(ModelType type, const HeterogeneousMap ¶ms) { if (type == ModelType::Heisenberg) { HeisenbergModel hs_model; hs_model.fromDict(params); if (!hs_model.validateModel()) { // Static internal HeisenbergModel struct // (keep alive to form time-depenedent Hamiltonian operator) static std::unique_ptr<HeisenbergModel> hs_model; hs_model = std::make_unique<HeisenbergModel>(); hs_model->fromDict(params); if (!hs_model->validateModel()) { qcor::error( "Failed to validate the input parameters for the Heisenberg model."); } Loading @@ -49,38 +52,41 @@ ModelBuilder::createModel(ModelType type, const HeterogeneousMap ¶ms) { QuantumSimulationModel model; // Observable = average magnetization auto observable = new qcor::PauliOperator; for (int i = 0; i < hs_model.num_spins; ++i) { (*observable) += ((1.0/hs_model.num_spins) * Z(i)); for (int i = 0; i < hs_model->num_spins; ++i) { (*observable) += ((1.0/hs_model->num_spins) * Z(i)); } model.observable = observable; qsim::TdObservable H = [&](double t) { qcor::PauliOperator tdOp; for (int i = 0; i < hs_model.num_spins - 1; ++i) { if (hs_model.Jx != 0.0) { tdOp += (hs_model.Jx * (X(i) * X(i + 1))); for (int i = 0; i < hs_model->num_spins - 1; ++i) { if (hs_model->Jx != 0.0) { tdOp += ((hs_model->Jx / hs_model->H_BAR) * (X(i) * X(i + 1))); } if (hs_model.Jy != 0.0) { tdOp += (hs_model.Jy * (Y(i) * Y(i + 1))); if (hs_model->Jy != 0.0) { tdOp += ((hs_model->Jy / hs_model->H_BAR) * (Y(i) * Y(i + 1))); } if (hs_model.Jz != 0.0) { tdOp += (hs_model.Jz * (Z(i) * Z(i + 1))); if (hs_model->Jz != 0.0) { tdOp += ((hs_model->Jz / hs_model->H_BAR) * (Z(i) * Z(i + 1))); } } std::function<double(double)> time_dep_func; if (hs_model.time_func) { time_dep_func = hs_model.time_func; if (hs_model->time_func) { time_dep_func = hs_model->time_func; } else { time_dep_func = [&](double time) { return std::cos(hs_model.freq * time); }; } if (hs_model.h_ext != 0.0) { for (int i = 0; i < hs_model.num_spins; ++i) { if (hs_model.ext_dir == "X") { tdOp += (hs_model.h_ext * time_dep_func(t) * X(i)); } else if (hs_model.ext_dir == "Y") { tdOp += (hs_model.h_ext * time_dep_func(t) * Y(i)); time_dep_func = [&](double time) { return std::cos(hs_model->freq * time); }; } if (hs_model->h_ext != 0.0) { for (int i = 0; i < hs_model->num_spins; ++i) { if (hs_model->ext_dir == "X") { tdOp += ((hs_model->h_ext / hs_model->H_BAR) * time_dep_func(t) * X(i)); } else if (hs_model->ext_dir == "Y") { tdOp += ((hs_model->h_ext / hs_model->H_BAR) * time_dep_func(t) * Y(i)); } else { tdOp += (hs_model.h_ext * time_dep_func(t) * Z(i)); tdOp += ((hs_model->h_ext / hs_model->H_BAR) * time_dep_func(t) * Z(i)); } } } Loading @@ -90,12 +96,12 @@ ModelBuilder::createModel(ModelType type, const HeterogeneousMap ¶ms) { model.hamiltonian = H; // Non-zero initial spin state: if (std::find(hs_model.initial_spins.begin(), hs_model.initial_spins.end(), 1) != hs_model.initial_spins.end()) { if (std::find(hs_model->initial_spins.begin(), hs_model->initial_spins.end(), 1) != hs_model->initial_spins.end()) { auto initialSpinPrep = qcor::__internal__::create_composite("InitialSpin"); auto provider = qcor::__internal__::get_provider(); for (int i = 0; i < hs_model.initial_spins.size(); ++i) { if (hs_model.initial_spins[i] == 1) { for (int i = 0; i < hs_model->initial_spins.size(); ++i) { if (hs_model->initial_spins[i] == 1) { initialSpinPrep->addInstruction(provider->createInstruction("X", i)); } } Loading Loading @@ -147,14 +153,20 @@ void ModelBuilder::HeisenbergModel::fromDict(const HeterogeneousMap ¶ms) { } }; // Handle exact types (int, double) getKeyIfExists(Jx, "Jx"); getKeyIfExists(Jy, "Jy"); getKeyIfExists(Jz, "Jz"); getKeyIfExists(ext_dir, "ext_dir"); getKeyIfExists(h_ext, "h_ext"); getKeyIfExists(H_BAR, "H_BAR"); getKeyIfExists(num_spins, "num_spins"); getKeyIfExists(initial_spins, "initial_spins"); getKeyIfExists(time_func, "time_func"); getKeyIfExists(freq, "freq"); // Handle string-like if (params.stringExists("ext_dir")) { ext_dir = params.getString("ext_dir"); } } } // namespace qsim } // namespace qcor No newline at end of file
lib/qsim/base/qcor_qsim.hpp +3 −1 Original line number Diff line number Diff line Loading @@ -91,9 +91,11 @@ public: double Jy = 0.0; double Jz = 0.0; double h_ext = 0.0; // Support for H_BAR normalization double H_BAR = 1.0; // "X", "Y", or "Z" std::string ext_dir = "Z"; size_t num_spins = 2; int num_spins = 2; std::vector<int> initial_spins; // Time-dependent freq. // Default to using the cosine function. Loading
python/examples/qsim_heisenberg_model.py 0 → 100644 +29 −0 Original line number Diff line number Diff line import sys, os from pathlib import Path sys.path.insert(1, str(Path.home()) + "/.xacc") from qcor import * import numpy as np import matplotlib.pyplot as plt # Demonstrate Heisenberg model (ArQTiC format) input problemModel = qsim.ModelBuilder.createModel(ModelType.Heisenberg, {'Jz': 0.01183898, 'h_ext': 0.01183898, 'freq': 0.0048, 'ext_dir': 'X', 'num_spins': 3}) # Run TD workflow: workflow = qsim.getWorkflow( 'td-evolution', {'dt': 3.0, 'steps': 20}) result = workflow.execute(problemModel) # Plot the result: t = np.linspace(0, 60, 21) y = result["exp-vals"] axes = plt.axes() axes.plot(t, y) axes.set_xlim([0,60]) axes.set_ylim([0,1]) # Save the plot to a file: os.chdir(os.path.dirname(os.path.abspath(__file__))) plt.savefig("avg_magnetization_plot.pdf") No newline at end of file
python/py-qcor.cpp +12 −2 Original line number Diff line number Diff line Loading @@ -732,8 +732,18 @@ PYBIND11_MODULE(_pyqcor, m) { [](qcor::PauliOperator &obs) { return qcor::qsim::ModelBuilder::createModel(obs); }, ""); "") .def( "createModel", [](qcor::qsim::ModelBuilder::ModelType type, PyHeterogeneousMap ¶ms) { auto nativeHetMap = heterogeneousMapConvert(params); return qcor::qsim::ModelBuilder::createModel(type, nativeHetMap); }, "Create a model of a supported type."); py::enum_<qcor::qsim::ModelBuilder::ModelType>(m, "ModelType") .value("Heisenberg", qcor::qsim::ModelBuilder::ModelType::Heisenberg) .export_values(); // CostFunctionEvaluator bindings py::class_<qcor::qsim::CostFunctionEvaluator, std::shared_ptr<qcor::qsim::CostFunctionEvaluator>, Loading