Loading lib/qsim/impls/qsim_impl.cpp +19 −7 Original line number Diff line number Diff line Loading @@ -13,7 +13,6 @@ Ansatz TrotterEvolution::create_ansatz(Observable *obs, if (params.keyExists<double>("dt")) { dt = params.get<double>("dt"); } // Just use exp_i_theta for now // TODO: formalize a standard library kernel for this. auto expCirc = std::dynamic_pointer_cast<xacc::quantum::Circuit>( Loading Loading @@ -130,7 +129,6 @@ bool IterativeQpeWorkflow::initialize(const HeterogeneousMap ¶ms) { if (params.keyExists<int>("iterations")) { num_iters = params.get<int>("iterations"); } return (num_steps >= 1) && (num_iters >= 1); } Loading Loading @@ -164,14 +162,27 @@ IterativeQpeWorkflow::constructQpeCircuit(const QuantumSimulationModel &model, // Apply C-U^n int power = 1 << (k - 1); // std::cout << "Power = " << power << "\n"; for (int i = 0; i < power; ++i) { for (int j = 0; j < num_steps; ++j) { for (int instId = 0; instId < ctrlKernel->nInstructions(); ++instId) { // We need to clone the instruction since it'll be repeated. kernel->addInstruction(ctrlKernel->getInstruction(instId)->clone()); } } } // Rz on ancilla qubit // Global phase due to identity pauli if (model.observable->getIdentitySubTerm()) { const double idCoeff = model.observable->getIdentitySubTerm()->coefficient().real(); const double globalPhase = 2 * M_PI * idCoeff * power; // std::cout << "Global phase = " << globalPhase << "\n"; kernel->addInstruction( provider->createInstruction("Rz", {ancBit}, {globalPhase})); } kernel->addInstruction(provider->createInstruction("Rz", {ancBit}, {omega})); // Hadamard on ancilla qubit Loading Loading @@ -232,12 +243,13 @@ IterativeQpeWorkflow::execute(const QuantumSimulationModel &model) { } }(); std::cout << "Iter " << iterIdx << ": Result = " << bitResult << "\n"; if (bitResult) { omega_coef = omega_coef + 0.5; } // std::cout << "Iter " << iterIdx << ": Result = " << bitResult << "; omega_coef = " << omega_coef << "\n"; } std::cout << "Final phase = " << omega_coef << "\n"; // std::cout << "Final phase = " << omega_coef << "\n"; return { {"phase", omega_coef}}; } Loading lib/qsim/impls/tests/IterativeQpeWorkflow.cpp +12 −11 Original line number Diff line number Diff line Loading @@ -6,25 +6,26 @@ // Compile and run with: /// $ qcor -qpu qpp IterativeQpeWorkflow.cpp /// $ ./a.out // Ansatz to bring the state into an eigenvector state of the Hamiltonian. __qpu__ void eigen_state_prep(qreg q) { auto theta = 0.297113; X(q[0]); auto exponent_op = X(0) * Y(1) - Y(0) * X(1); exp_i_theta(q, theta, exponent_op); using qcor::openqasm; u3(pi / 4, 0, 0) q[0]; } int main(int argc, char **argv) { // Create Hamiltonian auto H = 5.907 - 2.1433 * X(0) * X(1) - 2.143 * Y(0) * Y(1) + 0.21829 * Z(0) - 6.125 * Z(1); // Create Hamiltonian: // Important: this must be a weighted pauli operator list. // TODO: add function to convert arbitrary Hamiltonian to the weighted form. auto H = 0.5 + 0.25 * X(0) + 0.25 * Z(0); auto problemModel = qsim::ModelBuilder::createModel(eigen_state_prep, H, 2, 0); qsim::ModelBuilder::createModel(eigen_state_prep, H, 1, 0); // Instantiate an IQPE workflow. auto workflow = qsim::getWorkflow("iqpe", {{"iterations", 8}}); auto workflow = qsim::getWorkflow("iqpe", {{"time-steps", 4}, {"iterations", 4}}); // Result should contain the observable expectation value along Trotter steps. auto result = workflow->execute(problemModel); const double phaseValue = result.get<double>("phase"); std::cout << "Final phase = " << phaseValue << "\n"; return 0; } No newline at end of file Loading
lib/qsim/impls/qsim_impl.cpp +19 −7 Original line number Diff line number Diff line Loading @@ -13,7 +13,6 @@ Ansatz TrotterEvolution::create_ansatz(Observable *obs, if (params.keyExists<double>("dt")) { dt = params.get<double>("dt"); } // Just use exp_i_theta for now // TODO: formalize a standard library kernel for this. auto expCirc = std::dynamic_pointer_cast<xacc::quantum::Circuit>( Loading Loading @@ -130,7 +129,6 @@ bool IterativeQpeWorkflow::initialize(const HeterogeneousMap ¶ms) { if (params.keyExists<int>("iterations")) { num_iters = params.get<int>("iterations"); } return (num_steps >= 1) && (num_iters >= 1); } Loading Loading @@ -164,14 +162,27 @@ IterativeQpeWorkflow::constructQpeCircuit(const QuantumSimulationModel &model, // Apply C-U^n int power = 1 << (k - 1); // std::cout << "Power = " << power << "\n"; for (int i = 0; i < power; ++i) { for (int j = 0; j < num_steps; ++j) { for (int instId = 0; instId < ctrlKernel->nInstructions(); ++instId) { // We need to clone the instruction since it'll be repeated. kernel->addInstruction(ctrlKernel->getInstruction(instId)->clone()); } } } // Rz on ancilla qubit // Global phase due to identity pauli if (model.observable->getIdentitySubTerm()) { const double idCoeff = model.observable->getIdentitySubTerm()->coefficient().real(); const double globalPhase = 2 * M_PI * idCoeff * power; // std::cout << "Global phase = " << globalPhase << "\n"; kernel->addInstruction( provider->createInstruction("Rz", {ancBit}, {globalPhase})); } kernel->addInstruction(provider->createInstruction("Rz", {ancBit}, {omega})); // Hadamard on ancilla qubit Loading Loading @@ -232,12 +243,13 @@ IterativeQpeWorkflow::execute(const QuantumSimulationModel &model) { } }(); std::cout << "Iter " << iterIdx << ": Result = " << bitResult << "\n"; if (bitResult) { omega_coef = omega_coef + 0.5; } // std::cout << "Iter " << iterIdx << ": Result = " << bitResult << "; omega_coef = " << omega_coef << "\n"; } std::cout << "Final phase = " << omega_coef << "\n"; // std::cout << "Final phase = " << omega_coef << "\n"; return { {"phase", omega_coef}}; } Loading
lib/qsim/impls/tests/IterativeQpeWorkflow.cpp +12 −11 Original line number Diff line number Diff line Loading @@ -6,25 +6,26 @@ // Compile and run with: /// $ qcor -qpu qpp IterativeQpeWorkflow.cpp /// $ ./a.out // Ansatz to bring the state into an eigenvector state of the Hamiltonian. __qpu__ void eigen_state_prep(qreg q) { auto theta = 0.297113; X(q[0]); auto exponent_op = X(0) * Y(1) - Y(0) * X(1); exp_i_theta(q, theta, exponent_op); using qcor::openqasm; u3(pi / 4, 0, 0) q[0]; } int main(int argc, char **argv) { // Create Hamiltonian auto H = 5.907 - 2.1433 * X(0) * X(1) - 2.143 * Y(0) * Y(1) + 0.21829 * Z(0) - 6.125 * Z(1); // Create Hamiltonian: // Important: this must be a weighted pauli operator list. // TODO: add function to convert arbitrary Hamiltonian to the weighted form. auto H = 0.5 + 0.25 * X(0) + 0.25 * Z(0); auto problemModel = qsim::ModelBuilder::createModel(eigen_state_prep, H, 2, 0); qsim::ModelBuilder::createModel(eigen_state_prep, H, 1, 0); // Instantiate an IQPE workflow. auto workflow = qsim::getWorkflow("iqpe", {{"iterations", 8}}); auto workflow = qsim::getWorkflow("iqpe", {{"time-steps", 4}, {"iterations", 4}}); // Result should contain the observable expectation value along Trotter steps. auto result = workflow->execute(problemModel); const double phaseValue = result.get<double>("phase"); std::cout << "Final phase = " << phaseValue << "\n"; return 0; } No newline at end of file