Commit edf6a583 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

Adding calculate method to Algorithm, implemented for fidelity key on qpt, adding python example


Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent 996135a4
Pipeline #88765 failed with stage
in 3 minutes and 15 seconds
import xacc
import numpy as np
# Choose the QPU on which to
# characterize the process matrix for a Hadamard
qpu = xacc.getAccelerator('aer')
# Create the CompositeInstruction containing a
# single Hadamard instruction
provider = xacc.getIRProvider('quantum')
circuit = provider.createComposite('U')
hadamard = provider.createInstruction('H', [0])
circuit.addInstruction(hadamard)
# Create the Algorithm, give it the circuit
# to characterize and the backend to target
qpt = xacc.getAlgorithm('qpt', {'circuit':circuit, 'accelerator':qpu})
# Allocate a qubit, this will
# store our tomography results
buffer = xacc.qalloc(1)
# Execute
qpt.execute(buffer)
# Compute the fidelity with respect to
# the ideal hadamard process
F = qpt.calculate('fidelity', buffer, {'chi-theoretical-real':[0., 0., 0., 0., 0., 1., 0., 1., 0., 0., 0., 0., 0., 1., 0., 1.]})
print('\nFidelity: ', F)
# Can get the chi process matrix and print it
chi_real_part = np.array(buffer['chi-real'])
chi_imag_part = np.array(buffer['chi-imag'])
chi = np.reshape(chi_real_part + 1j*chi_imag_part, (4,4))
print('\nChi:\n', chi)
......@@ -12,16 +12,17 @@
*******************************************************************************/
#include "py_algorithm.hpp"
#include "Algorithm.hpp"
#include "py_heterogeneous_map.hpp"
void bind_algorithm(py::module &m) {
py::class_<xacc::Algorithm, std::shared_ptr<xacc::Algorithm>, PyAlgorithm> alg(
m, "Algorithm",
"The XACC Algorithm interface takes as input a dictionary of "
"AlgorithmParameters "
"and executes the desired Algorithm.");
py::class_<xacc::Algorithm, std::shared_ptr<xacc::Algorithm>, PyAlgorithm>
alg(m, "Algorithm",
"The XACC Algorithm interface takes as input a dictionary of "
"AlgorithmParameters "
"and executes the desired Algorithm.");
alg.def(py::init<>())
alg.def(py::init<>())
.def("name", &xacc::Algorithm::name, "Return the name of this Algorithm.")
.def("execute",
(void (xacc::Algorithm::*)(
......@@ -36,7 +37,27 @@ void bind_algorithm(py::module &m) {
xacc::Algorithm::execute,
"Execute the Algorithm, storing the results in provided "
"AcceleratorBuffer.")
.def("initialize",&xacc::Algorithm::initialize,
.def(
"calculate",
[](Algorithm &a, const std::string task,
const std::shared_ptr<AcceleratorBuffer> b,
PyHeterogeneousMap &params) {
HeterogeneousMap m;
for (auto &item : params) {
PyHeterogeneousMap2HeterogeneousMap vis(m, item.first);
mpark::visit(vis, item.second);
}
return a.calculate(task, b, m);
},
"")
.def(
"calculate",
[](Algorithm &a, const std::string task,
const std::shared_ptr<AcceleratorBuffer> b) {
return a.calculate(task, b);
},
"")
.def("initialize", &xacc::Algorithm::initialize,
"Initialize the algorithm with given AlgorithmParameters.")
.def("clone", &xacc::Algorithm::clone, "");
}
\ No newline at end of file
......@@ -358,7 +358,7 @@ void QPT::execute(const std::shared_ptr<AcceleratorBuffer> buffer) const {
}
Eigen::MatrixXcd chi = (1 / std::pow(2, nQ)) * (cob * choi * cob.adjoint());
// std::cout << "QPT Chi:\n" << chi << "\n\n";
// std::cout << "QPT Chi:\n" << chi << "\n\n";
std::vector<double> chi_real_vec, chi_imag_vec;
for (int i = 0; i < chi.rows(); i++) {
for (int j = 0; j < chi.cols(); j++) {
......@@ -378,5 +378,88 @@ void QPT::execute(const std::shared_ptr<AcceleratorBuffer> buffer) const {
buffer->addExtraInfo("chi-imag", chi_imag_vec);
}
template <typename Derived>
double fidelity(const Eigen::MatrixBase<Derived> &chi_1,
const Eigen::MatrixBase<Derived> &chi_2) {
Eigen::JacobiSVD<Eigen::MatrixXcd> svd(chi_1, Eigen::ComputeThinU |
Eigen::ComputeThinV);
Eigen::MatrixXcd sqrt_chi_1 = svd.matrixU() *
svd.singularValues().cwiseSqrt().asDiagonal() *
svd.matrixV().transpose();
Eigen::JacobiSVD<Eigen::MatrixXcd> svd2(chi_2, Eigen::ComputeThinU |
Eigen::ComputeThinV);
Eigen::MatrixXcd sqrt_chi_2 = svd2.matrixU() *
svd2.singularValues().cwiseSqrt().asDiagonal() *
svd2.matrixV().transpose();
Eigen::MatrixXcd tmp = sqrt_chi_1 * sqrt_chi_2;
Eigen::JacobiSVD<Eigen::MatrixXcd> svd3(tmp, Eigen::ComputeThinU |
Eigen::ComputeThinV);
auto svd_sum = svd3.singularValues().sum();
return svd_sum * svd_sum;
}
double QPT::calculate(const std::string &calculation_task,
const std::shared_ptr<AcceleratorBuffer> buffer,
const HeterogeneousMap &extra_data) {
if (calculation_task == "fidelity") {
if (!extra_data.keyExists<std::vector<double>>("chi-theoretical-real")) {
xacc::error("[QPT::calculate] Cannot calculate fidelity without "
"'chi-theoretical-real' vector<double>");
}
std::vector<double> chi_real =
(*buffer)["chi-real"].as<std::vector<double>>();
std::vector<double> chi_imag =
(*buffer)["chi-imag"].as<std::vector<double>>();
std::vector<double> chi_theory_real =
extra_data.get<std::vector<double>>("chi-theoretical-real");
std::vector<double> chi_theory_imag(chi_theory_real.size());
if (extra_data.keyExists<std::vector<double>>("chi-theoretical-imag")) {
std::vector<double> chi_theory_imag =
extra_data.get<std::vector<double>>("chi-theoretical-imag");
}
int n = (int)std::sqrt(chi_theory_real.size());
int nQ = (int)std::log2(std::sqrt(n));
Eigen::MatrixXd tmpchitheoryreal =
Eigen::Map<Eigen::MatrixXd>(chi_theory_real.data(), n, n);
Eigen::MatrixXd tmpchitheoryimag =
Eigen::Map<Eigen::MatrixXd>(chi_theory_imag.data(), n, n);
Eigen::MatrixXd tmpchireal =
Eigen::Map<Eigen::MatrixXd>(chi_real.data(), n, n);
Eigen::MatrixXd tmpchiimag =
Eigen::Map<Eigen::MatrixXd>(chi_imag.data(), n, n);
Eigen::MatrixXcd chitheory = Eigen::MatrixXcd::Zero(n, n);
Eigen::MatrixXcd chi = Eigen::MatrixXcd::Zero(n, n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
chitheory(i, j) = std::complex<double>(tmpchitheoryreal(i, j),
tmpchitheoryimag(i, j));
chi(i, j) = std::complex<double>(tmpchireal(i, j), tmpchiimag(i, j));
}
}
return fidelity((1. / std::pow(2, nQ)) * chi,
(1. / std::pow(2, nQ)) * chitheory);
} else {
xacc::error("[QPT::calculate] Can only calculate fidelity, invalid "
"calculation_task: " +
calculation_task);
}
return 0.0;
}
} // namespace algorithm
} // namespace xacc
\ No newline at end of file
......@@ -24,8 +24,12 @@ class QPT : public Algorithm {
public:
bool initialize(const HeterogeneousMap &parameters) override;
const std::vector<std::string> requiredParameters() const override;
void execute(const std::shared_ptr<AcceleratorBuffer> buffer) const override;
double calculate(const std::string &calculation_task,
const std::shared_ptr<AcceleratorBuffer> buffer,
const HeterogeneousMap &extra_data = {}) override;
const std::string name() const override { return "qpt"; }
const std::string description() const override { return ""; }
DEFINE_ALGORITHM_CLONE(QPT)
......
......@@ -34,17 +34,18 @@ namespace xacc {
class Algorithm : public xacc::Identifiable, public xacc::Cloneable<Algorithm> {
public:
// bool initialize(const HeterogeneousMap &&parameters) {
// return initialize(parameters);
// }
// bool initialize(const HeterogeneousMap &&parameters) {
// return initialize(parameters);
// }
virtual bool initialize(const HeterogeneousMap &parameters) = 0;
virtual const std::vector<std::string> requiredParameters() const = 0;
virtual void
execute(const std::shared_ptr<AcceleratorBuffer> buffer) const = 0;
virtual std::vector<double> execute(const std::shared_ptr<AcceleratorBuffer> buffer,
const std::vector<double> &parameters) {
virtual std::vector<double>
execute(const std::shared_ptr<AcceleratorBuffer> buffer,
const std::vector<double> &parameters) {
XACCLogger::instance()->error(
"Algorithm::execute(buffer, vector<double>) not implemented for " +
name());
......@@ -52,9 +53,15 @@ public:
return {};
}
#define DEFINE_ALGORITHM_CLONE(CLASS) \
std::shared_ptr<Algorithm> clone() override { \
return std::make_shared<CLASS>(); \
virtual double calculate(const std::string &calculation_task,
const std::shared_ptr<AcceleratorBuffer> buffer,
const HeterogeneousMap &extra_data = {}) {
return {};
}
#define DEFINE_ALGORITHM_CLONE(CLASS) \
std::shared_ptr<Algorithm> clone() override { \
return std::make_shared<CLASS>(); \
}
};
......
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