Commit 3459690b authored by Nguyen, Thien's avatar Nguyen, Thien
Browse files

Update example files for tutorial


Signed-off-by: Nguyen, Thien's avatarThien Nguyen <nguyentm@ornl.gov>
parent 4d71c67f
......@@ -8,10 +8,10 @@ int main() {
// Create the Hamiltonian
auto H = -2.1433 * X(0) * X(1) - 2.1433 * Y(0) * Y(1) + .21829 * Z(0) -
6.125 * Z(1) + 5.907;
std::cout << "H = " << H.toString() << "\n";
const double test_theta = 1.2345;
auto q = qalloc(2);
const double energy = ansatz::observe(H, q, test_theta);
std::cout << "E(" << test_theta << ") = " << energy << "\n";
q.print();
// q.print();
}
\ No newline at end of file
......@@ -12,7 +12,7 @@ def ansatz(q: qreg, x: List[float], exp_args: List[Operator]):
exp_i_theta(q, x[i], exp_args[i])
# Create OpenFermion operators for our quantum kernel...
exp_args_openfermion = [FOp('0^ 1') - FOp('1^ 0'), FOp('0^ 2') - FOp('2^ 0')]
exp_args_openfermion = [FOp('0^ 2') - FOp('2^ 0')]
# We need to translate OpenFermion ops into qcor Operators to use with kernels...
exp_args_qcor = [createOperator('fermion', fop) for fop in exp_args_openfermion]
......
......@@ -40,8 +40,5 @@ int main(int argc, char **argv) {
{"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
......@@ -4,7 +4,7 @@
// iterative QPE procedure.
// Compile and run with:
/// $ qcor -qpu qpp IterativeQpeVqe.cpp
/// $ qcor IterativeQpeVqe.cpp
/// $ ./a.out
/// Ansatz to bring the state into an eigenvector state of the Hamiltonian.
......@@ -37,8 +37,5 @@ int main(int argc, char **argv) {
std::cout << "Final phase = " << phaseValue << "\n";
// Expect: ~ -1.7 (due to limited bit precision)
std::cout << "Energy = " << energy << "\n";
print("N Instructions at Iter:");
for (auto [i,n] : enumerate(n_insts)) print("iter", i, ":" , n);
return 0;
}
\ No newline at end of file
......@@ -3,7 +3,7 @@
// Demonstrate qsim's QAOA workflow
// Compile and run with:
/// $ qcor -qpu qpp QaoaWorkflow.cpp
/// $ qcor -qpu qsim QaoaWorkflow.cpp
/// $ ./a.out
int main(int argc, char **argv) {
......
#include "qcor_qsim.hpp"
// Demonstrate qsim's QITE workflow
// with a simple 1-qubit Hamiltonian from
// https://www.nature.com/articles/s41567-019-0704-4 Compile and run with:
/// $ qcor -qpu qpp QiteWorkflow.cpp
/// $ ./a.out
int main(int argc, char **argv) {
auto ham = 0.7071067811865475 * X(0) + 0.7071067811865475 * Z(0);
// Number of QITE time steps and step size
const int nbSteps = 25;
const double stepSize = 0.1;
auto problemModel = QuaSiMo::ModelFactory::createModel(ham);
auto workflow =
QuaSiMo::getWorkflow("qite", {{"steps", nbSteps}, {"step-size", stepSize}});
auto result = workflow->execute(problemModel);
const auto energy = result.get<double>("energy");
const auto energyAtStep = result.get<std::vector<double>>("exp-vals");
std::cout << "QITE energy: [ ";
for (const auto &val : energyAtStep) {
std::cout << val << " ";
}
std::cout << "]\n";
std::cout << "Ground state energy: " << energy << "\n";
return 0;
}
\ No newline at end of file
#include "qcor_qsim.hpp"
// High-level usage of Model Builder for Heisenberg model.
// The Heisenberg Hamiltonian is parameterized using ArQTiC scheme.
// Compile and run with:
/// $ qcor -qpu qpp TdWorkflowHeisenbergModel.cpp
/// $ ./a.out
int main(int argc, char **argv) {
using ModelType = qcor::QuaSiMo::ModelFactory::ModelType;
// Example ArQTiC input:
// *Jz
// 0.01183898
// *h_ext
// 0.01183898
// *initial_spins
// 0 0 0
// *freq
// 0.0048
// *ext_dir
// X
// *num_spins
// 3
auto problemModel = QuaSiMo::ModelFactory::createModel(ModelType::Heisenberg,
{{"Jz", 0.01183898},
{"h_ext", 0.01183898},
{"freq", 0.0048},
{"ext_dir", "X"},
{"num_spins", 3}});
// Workflow parameters:
// *delta_t
// 3
// *steps
// 20
auto workflow = QuaSiMo::getWorkflow(
"td-evolution", {{"dt", 3.0}, {"steps", 20}});
// Result should contain the observable expectation value along Trotter steps.
auto result = workflow->execute(problemModel);
// Get the observable values (average magnetization)
const auto obsVals = result.get<std::vector<double>>("exp-vals");
// Print out for debugging:
for (const auto &val : obsVals) {
std::cout << "<Magnetization> = " << val << "\n";
}
return 0;
}
......@@ -35,8 +35,9 @@ int main(int argc, char **argv) {
const auto obsVals = result.get<std::vector<double>>("exp-vals");
// Print out for debugging:
std::cout << "<Magnetization>:\n";
for (const auto &val : obsVals) {
std::cout << "<Magnetization> = " << val << "\n";
std::cout << val << "\n";
}
return 0;
......
#include "qcor_qsim.hpp"
// Using noise-mitigation observable evaluation (Verified QPE)
// Compile and run with (e.g. using the 5-qubit Yorktown device)
/// $ qcor -qpu -qpu aer[noise-model:<noise JSON>] -shots 8192 -opt-pass
/// two-qubit-block-merging VerifiedQuantumPhaseEstimation.cpp
/// $ ./a.out
// For this simple circuit, the Trotter circuit can be significantly simplified
// by the `two-qubit-block-merging` optimizer (combine Trotter steps and
// decompose the total circuit into a more efficient KAK circuit).
// Note: for simplicity, we use the time-dependent Ising model with only 2
// qubits, hence with QPE, we need a total of 3 qubits. These 3 qubits can be
// directly mapped to the triangular topology of the Yorktown device.
// (Ref: Fig 3 of PhysRevB.101.184305)
int main(int argc, char **argv) {
// Define the time-dependent Hamiltonian and observable operator using the
// QCOR API Time-dependent Hamiltonian
QuaSiMo::TdObservable H = [](double t) {
// Parameters:
const double Jz = 2 * M_PI * 2.86265 * 1e-3;
const double epsilon = Jz;
const double omega = 4.8 * 2 * M_PI * 1e-3;
return -Jz * Z(0) * Z(1) - epsilon * std::cos(omega * t) * (X(0) + X(1));
};
// Observable = average magnetization
auto observable = (1.0 / 2.0) * (Z(0) + Z(1));
// Example: build model and TD workflow for Fig. 2 of
// https://journals.aps.org/prb/pdf/10.1103/PhysRevB.101.184305
auto problemModel = QuaSiMo::ModelFactory::createModel(observable, H);
// Trotter step = 3fs, number of steps = 100 -> end time = 300fs
// Request the Verified QPE observable evaluator:
auto vqpeEvaluator =
QuaSiMo::getObjEvaluator(observable, "qpe", {{"verified", true}});
auto workflow = QuaSiMo::getWorkflow(
"td-evolution",
{{"dt", 3.0}, {"steps", 100}, {"evaluator", vqpeEvaluator}});
// Result should contain the observable expectation value along Trotter steps.
auto result = workflow->execute(problemModel);
// Get the observable values (average magnetization)
const auto obsVals = result.get<std::vector<double>>("exp-vals");
// Print out for debugging:
for (const auto &val : obsVals) {
std::cout << "<Magnetization> = " << val << "\n";
}
return 0;
}
......@@ -31,6 +31,5 @@ int main(int argc, char **argv) {
const auto energy = result.get<double>("energy");
std::cout << "Ground-state energy = " << energy << "\n";
qcor_expect(std::abs(energy + 1.7487) < 0.1);
return 0;
}
\ No newline at end of file
#include "qcor_qsim.hpp"
int main(int argc, char** argv) {
set_verbose(true);
using namespace QuaSiMo;
// Create the qsearch IR Transformation
auto qsearch_optimizer = createTransformation("qsearch");
// Create the Hamiltonian: 3-qubit TFIM
auto observable = Z(0) * Z(1) + Z(1) * Z(2) + X(0) + X(1) + X(2);
observable *= -1;
// We'll run with 20 steps and .45 step size
const int nbSteps = 20;
const double stepSize = 0.45;
auto problemModel = ModelFactory::createModel(&observable);
// With circuit optimization (QSearch)
// auto workflow =
// getWorkflow("qite", {{"steps", nbSteps},
// {"step-size", stepSize},
// {"circuit-optimizer", qsearch_optimizer}});
// Without circuit optimization
auto workflow =
getWorkflow("qite", {{"steps", nbSteps}, {"step-size", stepSize}});
// Execute
auto result = workflow->execute(problemModel);
// Get the energy and final circuit
const auto energy = result.get<double>("energy");
auto finalCircuit = result.getPointerLike<CompositeInstruction>("circuit");
printf("\n%s\nEnergy=%f\n", finalCircuit->toString().c_str(), energy);
const auto energyAtStep = result.get<std::vector<double>>("exp-vals");
std::cout << "QITE energy: [ ";
for (const auto &val : energyAtStep) {
std::cout << val << " ";
}
std::cout << "]\n";
}
\ No newline at end of file
#include "qcor_qsim.hpp"
// qcor qite_deuteron.cpp -qpu qsim
__qpu__ void state_prep(qreg q) { X(q[0]); }
int main(int argc, char** argv) {
set_verbose(true);
int main(int argc, char **argv) {
using namespace QuaSiMo;
// Create the qsearch IR Transformation
auto qsearch_optimizer = createTransformation("qsearch");
// Create the Hamiltonian
auto observable = -2.1433 * X(0) * X(1) - 2.1433 * Y(0) * Y(1) +
.21829 * Z(0) - 6.125 * Z(1) + 5.907;
......@@ -21,15 +17,18 @@ int main(int argc, char** argv) {
// and QITE workflow
auto problemModel = ModelFactory::createModel(state_prep, &observable, 2, 0);
auto workflow =
getWorkflow("qite", {{"steps", nbSteps},
{"step-size", stepSize},
{"circuit-optimizer", qsearch_optimizer}});
getWorkflow("qite", {{"steps", nbSteps}, {"step-size", stepSize}});
// Execute
auto result = workflow->execute(problemModel);
// Get the energy and final circuit
// Get the final energy and iteration values
const auto energy = result.get<double>("energy");
auto finalCircuit = result.getPointerLike<CompositeInstruction>("circuit");
printf("\n%s\nEnergy=%f\n", finalCircuit->toString().c_str(), energy);
const auto energyAtStep = result.get<std::vector<double>>("exp-vals");
std::cout << "QITE energy: [ ";
for (const auto &val : energyAtStep) {
std::cout << val << " ";
}
std::cout << "]\n";
std::cout << "Ground state energy: " << energy << "\n";
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment