Loading examples/CMakeLists.txt +5 −0 Original line number Diff line number Diff line Loading @@ -21,3 +21,8 @@ add_test(NAME qrt_ftqc_steane_qec_std_lib COMMAND ${CMAKE_BINARY_DIR}/qcor -c -q add_test(NAME qsim_vqe COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/qsim/VqeWithAnsatzCircuit.cpp) add_test(NAME qsim_trotter COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/qsim/TrotterTdWorkflow.cpp) add_test(NAME qsim_iqpe_vqe COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/qsim/IterativeQpeVqe.cpp) add_test(NAME qsim_adapt_vqe COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/qsim/AdaptVqeWorkflow.cpp) add_test(NAME qsim_qaoa COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/qsim/QaoaWorkflow.cpp) add_test(NAME qsim_qite COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/qsim/QiteWorkflow.cpp) add_test(NAME qsim_heisenberg COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/qsim/TdWorkflowHeisenbergModel.cpp) add_test(NAME qsim_verified_qpe COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/qsim/VerifiedQuantumPhaseEstimation.cpp) examples/qsim/AdaptVqeWorkflow.cpp 0 → 100644 +48 −0 Original line number Diff line number Diff line #include "qcor_qsim.hpp" // Demonstrate qsim's Adapt-VQE workflow /// $ qcor -qpu qpp AdaptVqeWorkflow.cpp /// $ ./a.out int main(int argc, char **argv) { const auto str = std::string( "(-0.165606823582,-0) 1^ 2^ 1 2 + (0.120200490713,0) 1^ 0^ 0 1 + " "(-0.0454063328691,-0) 0^ 3^ 1 2 + (0.168335986252,0) 2^ 0^ 0 2 + " "(0.0454063328691,0) 1^ 2^ 3 0 + (0.168335986252,0) 0^ 2^ 2 0 + " "(0.165606823582,0) 0^ 3^ 3 0 + (-0.0454063328691,-0) 3^ 0^ 2 1 + " "(-0.0454063328691,-0) 1^ 3^ 0 2 + (-0.0454063328691,-0) 3^ 1^ 2 0 + " "(0.165606823582,0) 1^ 2^ 2 1 + (-0.165606823582,-0) 0^ 3^ 0 3 + " "(-0.479677813134,-0) 3^ 3 + (-0.0454063328691,-0) 1^ 2^ 0 3 + " "(-0.174072892497,-0) 1^ 3^ 1 3 + (-0.0454063328691,-0) 0^ 2^ 1 3 + " "(0.120200490713,0) 0^ 1^ 1 0 + (0.0454063328691,0) 0^ 2^ 3 1 + " "(0.174072892497,0) 1^ 3^ 3 1 + (0.165606823582,0) 2^ 1^ 1 2 + " "(-0.0454063328691,-0) 2^ 1^ 3 0 + (-0.120200490713,-0) 2^ 3^ 2 3 + " "(0.120200490713,0) 2^ 3^ 3 2 + (-0.168335986252,-0) 0^ 2^ 0 2 + " "(0.120200490713,0) 3^ 2^ 2 3 + (-0.120200490713,-0) 3^ 2^ 3 2 + " "(0.0454063328691,0) 1^ 3^ 2 0 + (-1.2488468038,-0) 0^ 0 + " "(0.0454063328691,0) 3^ 1^ 0 2 + (-0.168335986252,-0) 2^ 0^ 2 0 + " "(0.165606823582,0) 3^ 0^ 0 3 + (-0.0454063328691,-0) 2^ 0^ 3 1 + " "(0.0454063328691,0) 2^ 0^ 1 3 + (-1.2488468038,-0) 2^ 2 + " "(0.0454063328691,0) 2^ 1^ 0 3 + (0.174072892497,0) 3^ 1^ 1 3 + " "(-0.479677813134,-0) 1^ 1 + (-0.174072892497,-0) 3^ 1^ 3 1 + " "(0.0454063328691,0) 3^ 0^ 1 2 + (-0.165606823582,-0) 3^ 0^ 3 0 + " "(0.0454063328691,0) 0^ 3^ 2 1 + (-0.165606823582,-0) 2^ 1^ 2 1 + " "(-0.120200490713,-0) 0^ 1^ 0 1 + (-0.120200490713,-0) 1^ 0^ 1 0 + " "(0.7080240981,0)"); FermionOperator H_vqe; H_vqe.fromString(str); auto problemModel = qsim::ModelBuilder::createModel(&H_vqe); auto optimizer = createOptimizer("nlopt", {{"nlopt-optimizer", "l-bfgs"}}); const int nElectrons = 2; const auto pool_vqe = "qubit-pool"; auto workflow = qsim::getWorkflow("adapt", {{"optimizer", optimizer}, {"pool", pool_vqe}, {"n-electrons", nElectrons}}); auto result = workflow->execute(problemModel); std::cout << "Final energy: " << result.get<double>("energy") << "\n"; auto final_ansatz = result.getPointerLike<xacc::CompositeInstruction>("circuit"); std::cout << "HOWDY: \n" << final_ansatz->toString() << "\n"; return 0; } No newline at end of file examples/qsim/demo/HeisenbergModel/QuantumQuenchSimulation.cpp 0 → 100644 +76 −0 Original line number Diff line number Diff line #include "qcor_qsim.hpp" // Simulate dynamics of a quantum quench of // a 1D antiferromagnetic Heisenberg model. // Compile and run with: /// $ qcor -qpu qsim QuantumQuenchSimulation.cpp /// $ ./a.out int main(int argc, char **argv) { // Handle input parameters: // --n-spins : number of spins/qubits (default = 7) // --g: g parameter - ZZ coupling strength (default = 0.0) // --dt: Trotter dt (default = 0.05) // --steps: number of steps (defalt = 100) // Process the input arguments std::vector<std::string> arguments(argv + 1, argv + argc); int n_spins = 7; double g = 0.0; double dt = 0.05; int n_steps = 100; for (int i = 0; i < arguments.size(); i++) { if (arguments[i] == "--n-spins") { n_spins = std::stoi(arguments[i + 1]); } if (arguments[i] == "--g") { g = std::stod(arguments[i + 1]); } if (arguments[i] == "--dt") { dt = std::stod(arguments[i + 1]); } if (arguments[i] == "--steps") { n_steps = std::stoi(arguments[i + 1]); } } std::cout << "Running QSim for a quenching model with " << n_spins << " spins and g = " << g << "\n"; std::cout << "dt " << dt << "; number of steps = " << n_steps << "\n"; using ModelType = qcor::qsim::ModelBuilder::ModelType; // Initial spin state: Neel state std::vector<int> initial_spins; for (int i = 0; i < n_spins; ++i) { // Alternating up/down spins initial_spins.emplace_back(i % 2); } auto problemModel = qsim::ModelBuilder::createModel( ModelType::Heisenberg, {{"Jx", 1.0}, {"Jy", 1.0}, // Jz == g parameter {"Jz", g}, // No external field {"h_ext", 0.0}, {"ext_dir", "X"}, {"num_spins", n_spins}, {"initial_spins", initial_spins}, {"observable", "staggered_magnetization"}}); // Workflow parameters: auto workflow = qsim::getWorkflow("td-evolution", {{"dt", dt}, {"steps", n_steps}}); // Result should contain the observable expectation value along Trotter steps. auto result = workflow->execute(problemModel); // Get the observable values (staggered magnetization) const auto obsVals = result.get<std::vector<double>>("exp-vals"); // Print out for debugging: std::cout << "<Staggered Magnetization> = \n"; for (const auto &val : obsVals) { std::cout << val << "\n"; } return 0; } lib/qsim/base/qcor_qsim.cpp +43 −5 Original line number Diff line number Diff line Loading @@ -50,12 +50,50 @@ ModelBuilder::createModel(ModelType type, const HeterogeneousMap ¶ms) { } QuantumSimulationModel model; // Observable = average magnetization // Handle custom observable: qcor::Observable *model_observable = nullptr; // Get QCOR Pauli Op first (if any) if (params.keyExists<qcor::PauliOperator>("observable")) { static auto cached_pauli = params.get<qcor::PauliOperator>("observable"); model_observable = &cached_pauli; } // Generic qcor::Observable else if (params.pointerLikeExists<qcor::Observable>("observable")) { model_observable = params.getPointerLike<qcor::Observable>("observable"); } else { const std::vector<std::string> SUPPORTED_OBS{"average_magnetization", "staggered_magnetization"}; std::string observable_type = "average_magnetization"; if (params.stringExists("observable")) { observable_type = params.getString("observable"); } if (!xacc::container::contains(SUPPORTED_OBS, observable_type)) { qcor::error("Unknown observable type: " + observable_type); } auto observable = new qcor::PauliOperator; if (observable_type == "average_magnetization") { for (int i = 0; i < hs_model->num_spins; ++i) { (*observable) += ((1.0 / hs_model->num_spins) * Z(i)); } model.observable = observable; } else if (observable_type == "staggered_magnetization") { double coeff = 1.0; for (int i = 0; i < hs_model->num_spins; ++i) { (*observable) += ((coeff / hs_model->num_spins) * Z(i)); // Alternate the sign coeff = -coeff; } } model_observable = observable; } assert(model_observable); model.observable = model_observable; qsim::TdObservable H = [&](double t) { qcor::PauliOperator tdOp; for (int i = 0; i < hs_model->num_spins - 1; ++i) { Loading lib/qsim/impls/qsim_activator.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ #include "workflow/qite.hpp" #include "workflow/time_dependent.hpp" #include "workflow/vqe.hpp" #include "workflow/adapt.hpp" namespace qcor { namespace qsim { Loading Loading @@ -48,6 +49,8 @@ public: std::make_shared<qsim::QiteWorkflow>()); context.RegisterService<qsim::QuantumSimulationWorkflow>( std::make_shared<qsim::IterativeQpeWorkflow>()); context.RegisterService<qsim::QuantumSimulationWorkflow>( std::make_shared<qsim::AdaptVqeWorkflow>()); // Cost evaluators context.RegisterService<qsim::CostFunctionEvaluator>( std::make_shared<qsim::PartialTomoObjFuncEval>()); Loading Loading
examples/CMakeLists.txt +5 −0 Original line number Diff line number Diff line Loading @@ -21,3 +21,8 @@ add_test(NAME qrt_ftqc_steane_qec_std_lib COMMAND ${CMAKE_BINARY_DIR}/qcor -c -q add_test(NAME qsim_vqe COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/qsim/VqeWithAnsatzCircuit.cpp) add_test(NAME qsim_trotter COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/qsim/TrotterTdWorkflow.cpp) add_test(NAME qsim_iqpe_vqe COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/qsim/IterativeQpeVqe.cpp) add_test(NAME qsim_adapt_vqe COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/qsim/AdaptVqeWorkflow.cpp) add_test(NAME qsim_qaoa COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/qsim/QaoaWorkflow.cpp) add_test(NAME qsim_qite COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/qsim/QiteWorkflow.cpp) add_test(NAME qsim_heisenberg COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/qsim/TdWorkflowHeisenbergModel.cpp) add_test(NAME qsim_verified_qpe COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/qsim/VerifiedQuantumPhaseEstimation.cpp)
examples/qsim/AdaptVqeWorkflow.cpp 0 → 100644 +48 −0 Original line number Diff line number Diff line #include "qcor_qsim.hpp" // Demonstrate qsim's Adapt-VQE workflow /// $ qcor -qpu qpp AdaptVqeWorkflow.cpp /// $ ./a.out int main(int argc, char **argv) { const auto str = std::string( "(-0.165606823582,-0) 1^ 2^ 1 2 + (0.120200490713,0) 1^ 0^ 0 1 + " "(-0.0454063328691,-0) 0^ 3^ 1 2 + (0.168335986252,0) 2^ 0^ 0 2 + " "(0.0454063328691,0) 1^ 2^ 3 0 + (0.168335986252,0) 0^ 2^ 2 0 + " "(0.165606823582,0) 0^ 3^ 3 0 + (-0.0454063328691,-0) 3^ 0^ 2 1 + " "(-0.0454063328691,-0) 1^ 3^ 0 2 + (-0.0454063328691,-0) 3^ 1^ 2 0 + " "(0.165606823582,0) 1^ 2^ 2 1 + (-0.165606823582,-0) 0^ 3^ 0 3 + " "(-0.479677813134,-0) 3^ 3 + (-0.0454063328691,-0) 1^ 2^ 0 3 + " "(-0.174072892497,-0) 1^ 3^ 1 3 + (-0.0454063328691,-0) 0^ 2^ 1 3 + " "(0.120200490713,0) 0^ 1^ 1 0 + (0.0454063328691,0) 0^ 2^ 3 1 + " "(0.174072892497,0) 1^ 3^ 3 1 + (0.165606823582,0) 2^ 1^ 1 2 + " "(-0.0454063328691,-0) 2^ 1^ 3 0 + (-0.120200490713,-0) 2^ 3^ 2 3 + " "(0.120200490713,0) 2^ 3^ 3 2 + (-0.168335986252,-0) 0^ 2^ 0 2 + " "(0.120200490713,0) 3^ 2^ 2 3 + (-0.120200490713,-0) 3^ 2^ 3 2 + " "(0.0454063328691,0) 1^ 3^ 2 0 + (-1.2488468038,-0) 0^ 0 + " "(0.0454063328691,0) 3^ 1^ 0 2 + (-0.168335986252,-0) 2^ 0^ 2 0 + " "(0.165606823582,0) 3^ 0^ 0 3 + (-0.0454063328691,-0) 2^ 0^ 3 1 + " "(0.0454063328691,0) 2^ 0^ 1 3 + (-1.2488468038,-0) 2^ 2 + " "(0.0454063328691,0) 2^ 1^ 0 3 + (0.174072892497,0) 3^ 1^ 1 3 + " "(-0.479677813134,-0) 1^ 1 + (-0.174072892497,-0) 3^ 1^ 3 1 + " "(0.0454063328691,0) 3^ 0^ 1 2 + (-0.165606823582,-0) 3^ 0^ 3 0 + " "(0.0454063328691,0) 0^ 3^ 2 1 + (-0.165606823582,-0) 2^ 1^ 2 1 + " "(-0.120200490713,-0) 0^ 1^ 0 1 + (-0.120200490713,-0) 1^ 0^ 1 0 + " "(0.7080240981,0)"); FermionOperator H_vqe; H_vqe.fromString(str); auto problemModel = qsim::ModelBuilder::createModel(&H_vqe); auto optimizer = createOptimizer("nlopt", {{"nlopt-optimizer", "l-bfgs"}}); const int nElectrons = 2; const auto pool_vqe = "qubit-pool"; auto workflow = qsim::getWorkflow("adapt", {{"optimizer", optimizer}, {"pool", pool_vqe}, {"n-electrons", nElectrons}}); auto result = workflow->execute(problemModel); std::cout << "Final energy: " << result.get<double>("energy") << "\n"; auto final_ansatz = result.getPointerLike<xacc::CompositeInstruction>("circuit"); std::cout << "HOWDY: \n" << final_ansatz->toString() << "\n"; return 0; } No newline at end of file
examples/qsim/demo/HeisenbergModel/QuantumQuenchSimulation.cpp 0 → 100644 +76 −0 Original line number Diff line number Diff line #include "qcor_qsim.hpp" // Simulate dynamics of a quantum quench of // a 1D antiferromagnetic Heisenberg model. // Compile and run with: /// $ qcor -qpu qsim QuantumQuenchSimulation.cpp /// $ ./a.out int main(int argc, char **argv) { // Handle input parameters: // --n-spins : number of spins/qubits (default = 7) // --g: g parameter - ZZ coupling strength (default = 0.0) // --dt: Trotter dt (default = 0.05) // --steps: number of steps (defalt = 100) // Process the input arguments std::vector<std::string> arguments(argv + 1, argv + argc); int n_spins = 7; double g = 0.0; double dt = 0.05; int n_steps = 100; for (int i = 0; i < arguments.size(); i++) { if (arguments[i] == "--n-spins") { n_spins = std::stoi(arguments[i + 1]); } if (arguments[i] == "--g") { g = std::stod(arguments[i + 1]); } if (arguments[i] == "--dt") { dt = std::stod(arguments[i + 1]); } if (arguments[i] == "--steps") { n_steps = std::stoi(arguments[i + 1]); } } std::cout << "Running QSim for a quenching model with " << n_spins << " spins and g = " << g << "\n"; std::cout << "dt " << dt << "; number of steps = " << n_steps << "\n"; using ModelType = qcor::qsim::ModelBuilder::ModelType; // Initial spin state: Neel state std::vector<int> initial_spins; for (int i = 0; i < n_spins; ++i) { // Alternating up/down spins initial_spins.emplace_back(i % 2); } auto problemModel = qsim::ModelBuilder::createModel( ModelType::Heisenberg, {{"Jx", 1.0}, {"Jy", 1.0}, // Jz == g parameter {"Jz", g}, // No external field {"h_ext", 0.0}, {"ext_dir", "X"}, {"num_spins", n_spins}, {"initial_spins", initial_spins}, {"observable", "staggered_magnetization"}}); // Workflow parameters: auto workflow = qsim::getWorkflow("td-evolution", {{"dt", dt}, {"steps", n_steps}}); // Result should contain the observable expectation value along Trotter steps. auto result = workflow->execute(problemModel); // Get the observable values (staggered magnetization) const auto obsVals = result.get<std::vector<double>>("exp-vals"); // Print out for debugging: std::cout << "<Staggered Magnetization> = \n"; for (const auto &val : obsVals) { std::cout << val << "\n"; } return 0; }
lib/qsim/base/qcor_qsim.cpp +43 −5 Original line number Diff line number Diff line Loading @@ -50,12 +50,50 @@ ModelBuilder::createModel(ModelType type, const HeterogeneousMap ¶ms) { } QuantumSimulationModel model; // Observable = average magnetization // Handle custom observable: qcor::Observable *model_observable = nullptr; // Get QCOR Pauli Op first (if any) if (params.keyExists<qcor::PauliOperator>("observable")) { static auto cached_pauli = params.get<qcor::PauliOperator>("observable"); model_observable = &cached_pauli; } // Generic qcor::Observable else if (params.pointerLikeExists<qcor::Observable>("observable")) { model_observable = params.getPointerLike<qcor::Observable>("observable"); } else { const std::vector<std::string> SUPPORTED_OBS{"average_magnetization", "staggered_magnetization"}; std::string observable_type = "average_magnetization"; if (params.stringExists("observable")) { observable_type = params.getString("observable"); } if (!xacc::container::contains(SUPPORTED_OBS, observable_type)) { qcor::error("Unknown observable type: " + observable_type); } auto observable = new qcor::PauliOperator; if (observable_type == "average_magnetization") { for (int i = 0; i < hs_model->num_spins; ++i) { (*observable) += ((1.0 / hs_model->num_spins) * Z(i)); } model.observable = observable; } else if (observable_type == "staggered_magnetization") { double coeff = 1.0; for (int i = 0; i < hs_model->num_spins; ++i) { (*observable) += ((coeff / hs_model->num_spins) * Z(i)); // Alternate the sign coeff = -coeff; } } model_observable = observable; } assert(model_observable); model.observable = model_observable; qsim::TdObservable H = [&](double t) { qcor::PauliOperator tdOp; for (int i = 0; i < hs_model->num_spins - 1; ++i) { Loading
lib/qsim/impls/qsim_activator.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ #include "workflow/qite.hpp" #include "workflow/time_dependent.hpp" #include "workflow/vqe.hpp" #include "workflow/adapt.hpp" namespace qcor { namespace qsim { Loading Loading @@ -48,6 +49,8 @@ public: std::make_shared<qsim::QiteWorkflow>()); context.RegisterService<qsim::QuantumSimulationWorkflow>( std::make_shared<qsim::IterativeQpeWorkflow>()); context.RegisterService<qsim::QuantumSimulationWorkflow>( std::make_shared<qsim::AdaptVqeWorkflow>()); // Cost evaluators context.RegisterService<qsim::CostFunctionEvaluator>( std::make_shared<qsim::PartialTomoObjFuncEval>()); Loading