Commit 5c708e42 authored by Nguyen, Thien's avatar Nguyen, Thien
Browse files

Work on QITE algorithm



Added basic algorithm flow/structure.
Signed-off-by: Nguyen, Thien's avatarThien Nguyen <nguyentm@ornl.gov>
parent 402c8b11
......@@ -21,9 +21,10 @@ add_library(${LIBRARY_NAME} SHARED ${SRC})
target_include_directories(
${LIBRARY_NAME}
PUBLIC .)
PUBLIC .
${CMAKE_SOURCE_DIR}/tpls/eigen)
target_link_libraries(${LIBRARY_NAME} PUBLIC xacc CppMicroServices)
target_link_libraries(${LIBRARY_NAME} PUBLIC xacc CppMicroServices xacc-quantum-gate)
set(_bundle_name xacc_algorithm_qite)
set_target_properties(${LIBRARY_NAME}
......
......@@ -14,9 +14,11 @@
#include "Observable.hpp"
#include "xacc.hpp"
#include "xacc_service.hpp"
#include "PauliOperator.hpp"
#include "Circuit.hpp"
#include <memory>
#include <iomanip>
#include <Eigen/Dense>
using namespace xacc;
......@@ -34,9 +36,86 @@ const std::vector<std::string> QITE::requiredParameters() const
return {};
}
std::shared_ptr<CompositeInstruction> QITE::constructPropagateCircuit() const
{
auto gateRegistry = xacc::getService<xacc::IRProvider>("quantum");
auto propagateKernel = gateRegistry->createComposite("statePropCircuit");
// Adds ansatz if provided
if (m_ansatz)
{
propagateKernel->addInstructions(m_ansatz->getInstructions());
}
const auto pauliTermToString = [](const std::shared_ptr<xacc::Observable>& in_term){
std::string pauliTermStr = in_term->toString();
std::stringstream s;
s.precision(12);
s << std::fixed << in_term->coefficient();
// Find the parenthesis
const auto startPosition = pauliTermStr.find("(");
const auto endPosition = pauliTermStr.find(")");
if (startPosition != std::string::npos && endPosition != std::string::npos)
{
const auto length = endPosition - startPosition + 1;
pauliTermStr.replace(startPosition, length, s.str());
}
return pauliTermStr;
};
// Progagates by Trotter steps
// Using those A operators that have been
// optimized up to this point.
for (const auto& aObs : m_approxOps)
{
// Circuit is: exp(-idt*A),
// i.e. regular evolution which approximates the imaginary time evolution.
for (const auto& term : aObs->getNonIdentitySubTerms())
{
const auto pauliStr = pauliTermToString(term);
auto expCirc = std::dynamic_pointer_cast<xacc::quantum::Circuit>(xacc::getService<Instruction>("exp_i_theta"));
expCirc->addVariable("theta");
expCirc->expand({ std::make_pair("pauli", term) });
auto evaled = expCirc->operator()({ m_dBeta });
propagateKernel->addInstructions(evaled->getInstructions());
}
}
return propagateKernel;
}
void QITE::execute(const std::shared_ptr<AcceleratorBuffer> buffer) const
{
// TODO
// Calculate approximate A operator observable at each time step.
const auto calcAOps = [&](std::shared_ptr<CompositeInstruction>) -> std::shared_ptr<Observable> {
// Step 1: Observe the kernels using the various Pauli
// operators to calculate S and b.
// TODO: this requires some Pauli algebra computation.
// Step 2: Calculate S matrix and b vector
// i.e. set up the linear equation Sa = b
// These are expectations on the current state.
// i.e. set-up the observables to calculate those entries.
// TODO: construct circuits and evaluate to get expectation values
// and populate S matrix and b vector.
Eigen::MatrixXf S_Mat;
Eigen::VectorXf b_Vec;
// const auto a_Vec = S_Mat.bdcSvd(ComputeThinU | ComputeThinV).solve(b_Vec);
// TODO: construct A observable from the coefficients in a_Vec
return nullptr;
};
// Time stepping:
for (int i = 0; i < m_nbSteps; ++i)
{
// Propagates the state via Trotter steps:
auto kernel = constructPropagateCircuit();
// Optimizes/calculates next A ops
auto nextAOps = calcAOps(kernel);
m_approxOps.emplace_back(nextAOps);
}
}
std::vector<double> QITE::execute(const std::shared_ptr<AcceleratorBuffer> buffer, const std::vector<double>& x)
......
......@@ -27,6 +27,24 @@ public:
const std::string name() const override { return "qite"; }
const std::string description() const override { return ""; }
DEFINE_ALGORITHM_CLONE(QITE)
private:
// Construct the Trotter propagate circuit up to current time step.
std::shared_ptr<CompositeInstruction> constructPropagateCircuit() const;
private:
// Number of Trotter steps
int m_nbSteps;
// dBeta, i.e. step size
double m_dBeta;
// Hamiltonian Observable, i.e. H = Sum(h_i)
Observable* m_observable;
// Ansatz circuit (apply before Trotter steps)
CompositeInstruction* m_ansatz;
// List of A operators for each time step
// which approximates the imaginary-time step
// of the Hamiltonian observable
// i.e. exp(-iAt) -> exp(-Ht)
mutable std::vector<std::shared_ptr<Observable>> m_approxOps;
};
} // namespace algorithm
} // namespace xacc
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