Loading lib/qsim/base/qcor_qsim.cpp +79 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,66 @@ ModelBuilder::createModel(Observable *obs, const HeterogeneousMap ¶ms) { return model; } QuantumSimulationModel ModelBuilder::createModel(ModelType type, const HeterogeneousMap ¶ms) { if (type == ModelType::Heisenberg) { HeisenbergModel hs_model; hs_model.fromDict(params); if (!hs_model.validateModel()) { qcor::error( "Failed to validate the input parameters for the Heisenberg model."); } 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)); } 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))); } if (hs_model.Jy != 0.0) { tdOp += (hs_model.Jy * (Y(i) * Y(i + 1))); } if (hs_model.Jz != 0.0) { tdOp += (hs_model.Jz * (Z(i) * Z(i + 1))); } } std::function<double(double)> time_dep_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)); } else { tdOp += (hs_model.h_ext * time_dep_func(t) * Z(i)); } } } return tdOp; }; model.hamiltonian = H; return model; } else { qcor::error("Unknown model type."); __builtin_unreachable(); } } QuantumSimulationModel ModelBuilder::createModel(const std::string &format, const std::string &data, const HeterogeneousMap ¶ms) { Loading Loading @@ -64,5 +124,24 @@ getObjEvaluator(Observable *observable, const std::string &name, // ERROR: unknown CostFunctionEvaluator or invalid initialization options. return nullptr; } void ModelBuilder::HeisenbergModel::fromDict(const HeterogeneousMap ¶ms) { const auto getKeyIfExists = [¶ms](auto &modelVar, const std::string &keyName) { using ValType = typename std::remove_reference_t<decltype(modelVar)>; if (params.keyExists<ValType>(keyName)) { modelVar = params.get<ValType>(keyName); } }; getKeyIfExists(Jx, "Jx"); getKeyIfExists(Jy, "Jy"); getKeyIfExists(Jz, "Jz"); getKeyIfExists(ext_dir, "ext_dir"); getKeyIfExists(num_spins, "num_spins"); getKeyIfExists(initial_spins, "initial_spins"); getKeyIfExists(time_func, "time_func"); getKeyIfExists(freq, "freq"); } } // namespace qsim } // namespace qcor No newline at end of file lib/qsim/base/qcor_qsim.hpp +31 −1 Original line number Diff line number Diff line Loading @@ -85,6 +85,33 @@ struct QuantumSimulationModel { // Create a model which capture the problem description. class ModelBuilder { public: // Generic Heisenberg model struct HeisenbergModel { double Jx = 0.0; double Jy = 0.0; double Jz = 0.0; double h_ext = 0.0; // "X", "Y", or "Z" std::string ext_dir = "Z"; size_t num_spins = 2; std::vector<int> initial_spins; // Time-dependent freq. // Default to using the cosine function. double freq = 0.0; // User-provided custom time-dependent function: std::function<double(double)> time_func; // Allows a simple Pythonic kwarg-style initialization. // i.e. all params have preset defaults, only update those that are // specified. void fromDict(const HeterogeneousMap ¶ms); bool validateModel() const { const bool ext_dir_valid = (ext_dir == "X" || ext_dir == "Y" || ext_dir == "Z"); const bool initial_spins_valid = (initial_spins.empty() || (initial_spins.size() == num_spins)); return ext_dir_valid && initial_spins_valid; } }; // ======== Direct model builder ============== // Strongly-typed parameters/argument. // Build a simple Hamiltonian-based model: static Hamiltonian which is also Loading Loading @@ -121,7 +148,10 @@ public: static QuantumSimulationModel createModel(const std::string &format, const std::string &data, const HeterogeneousMap ¶ms = {}); // Predefined model type that we support intrinsically. enum class ModelType { Heisenberg }; static QuantumSimulationModel createModel(ModelType type, const HeterogeneousMap ¶ms); // ========== QuantumSimulationModel with a fixed (pre-defined) ansatz ======== // The ansatz is provided as a QCOR kernel. template <typename... Args> Loading Loading
lib/qsim/base/qcor_qsim.cpp +79 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,66 @@ ModelBuilder::createModel(Observable *obs, const HeterogeneousMap ¶ms) { return model; } QuantumSimulationModel ModelBuilder::createModel(ModelType type, const HeterogeneousMap ¶ms) { if (type == ModelType::Heisenberg) { HeisenbergModel hs_model; hs_model.fromDict(params); if (!hs_model.validateModel()) { qcor::error( "Failed to validate the input parameters for the Heisenberg model."); } 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)); } 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))); } if (hs_model.Jy != 0.0) { tdOp += (hs_model.Jy * (Y(i) * Y(i + 1))); } if (hs_model.Jz != 0.0) { tdOp += (hs_model.Jz * (Z(i) * Z(i + 1))); } } std::function<double(double)> time_dep_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)); } else { tdOp += (hs_model.h_ext * time_dep_func(t) * Z(i)); } } } return tdOp; }; model.hamiltonian = H; return model; } else { qcor::error("Unknown model type."); __builtin_unreachable(); } } QuantumSimulationModel ModelBuilder::createModel(const std::string &format, const std::string &data, const HeterogeneousMap ¶ms) { Loading Loading @@ -64,5 +124,24 @@ getObjEvaluator(Observable *observable, const std::string &name, // ERROR: unknown CostFunctionEvaluator or invalid initialization options. return nullptr; } void ModelBuilder::HeisenbergModel::fromDict(const HeterogeneousMap ¶ms) { const auto getKeyIfExists = [¶ms](auto &modelVar, const std::string &keyName) { using ValType = typename std::remove_reference_t<decltype(modelVar)>; if (params.keyExists<ValType>(keyName)) { modelVar = params.get<ValType>(keyName); } }; getKeyIfExists(Jx, "Jx"); getKeyIfExists(Jy, "Jy"); getKeyIfExists(Jz, "Jz"); getKeyIfExists(ext_dir, "ext_dir"); getKeyIfExists(num_spins, "num_spins"); getKeyIfExists(initial_spins, "initial_spins"); getKeyIfExists(time_func, "time_func"); getKeyIfExists(freq, "freq"); } } // namespace qsim } // namespace qcor No newline at end of file
lib/qsim/base/qcor_qsim.hpp +31 −1 Original line number Diff line number Diff line Loading @@ -85,6 +85,33 @@ struct QuantumSimulationModel { // Create a model which capture the problem description. class ModelBuilder { public: // Generic Heisenberg model struct HeisenbergModel { double Jx = 0.0; double Jy = 0.0; double Jz = 0.0; double h_ext = 0.0; // "X", "Y", or "Z" std::string ext_dir = "Z"; size_t num_spins = 2; std::vector<int> initial_spins; // Time-dependent freq. // Default to using the cosine function. double freq = 0.0; // User-provided custom time-dependent function: std::function<double(double)> time_func; // Allows a simple Pythonic kwarg-style initialization. // i.e. all params have preset defaults, only update those that are // specified. void fromDict(const HeterogeneousMap ¶ms); bool validateModel() const { const bool ext_dir_valid = (ext_dir == "X" || ext_dir == "Y" || ext_dir == "Z"); const bool initial_spins_valid = (initial_spins.empty() || (initial_spins.size() == num_spins)); return ext_dir_valid && initial_spins_valid; } }; // ======== Direct model builder ============== // Strongly-typed parameters/argument. // Build a simple Hamiltonian-based model: static Hamiltonian which is also Loading Loading @@ -121,7 +148,10 @@ public: static QuantumSimulationModel createModel(const std::string &format, const std::string &data, const HeterogeneousMap ¶ms = {}); // Predefined model type that we support intrinsically. enum class ModelType { Heisenberg }; static QuantumSimulationModel createModel(ModelType type, const HeterogeneousMap ¶ms); // ========== QuantumSimulationModel with a fixed (pre-defined) ansatz ======== // The ansatz is provided as a QCOR kernel. template <typename... Args> Loading