Commit 872b8afc authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

adding observable and paulioperator


Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent ad2724ec
Pipeline #44140 passed with stages
in 9 minutes and 23 seconds
...@@ -70,9 +70,19 @@ endif() ...@@ -70,9 +70,19 @@ endif()
message(STATUS "${BoldGreen}Installing XACC to ${CMAKE_INSTALL_PREFIX}. Override with -DCMAKE_INSTALL_PREFIX=...${ColorReset}") message(STATUS "${BoldGreen}Installing XACC to ${CMAKE_INSTALL_PREFIX}. Override with -DCMAKE_INSTALL_PREFIX=...${ColorReset}")
#if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "7.0.0") if (XACC_BUILD_TESTS)
# set (CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "-Wimplicit-fallthrough=0") enable_testing()
#endif() macro(add_xacc_test _TEST_NAME)
add_executable(${_TEST_NAME}Tester ${_TEST_NAME}Tester.cpp)
target_include_directories(${_TEST_NAME}Tester PRIVATE ${GTEST_INCLUDE_DIRS})
add_test(NAME xacc_${_TEST_NAME}Tester COMMAND ${_TEST_NAME}Tester)
target_link_libraries(${_TEST_NAME}Tester ${GTEST_LIBRARIES} xacc)
endmacro()
macro(set_cache_variable VAR_NAME VAR_DESCRIPTION)
set(${VAR_NAME} ${${VAR_NAME}} CACHE INTERNAL ${VAR_DESCRIPTION})
message(STATUS "Set ${VAR_NAME} to ${${VAR_NAME}}.")
endmacro()
endif()
include_directories(${CMAKE_BINARY_DIR}/tpls/cppmicroservices/include) include_directories(${CMAKE_BINARY_DIR}/tpls/cppmicroservices/include)
add_subdirectory(tpls) add_subdirectory(tpls)
...@@ -90,9 +100,10 @@ endif() ...@@ -90,9 +100,10 @@ endif()
# and CMake loads include paths, libs, etc # and CMake loads include paths, libs, etc
configure_file("${CMAKE_SOURCE_DIR}/cmake/xacc-config.cmake.in" "${CMAKE_BINARY_DIR}/xacc-config.cmake" @ONLY) configure_file("${CMAKE_SOURCE_DIR}/cmake/xacc-config.cmake.in" "${CMAKE_BINARY_DIR}/xacc-config.cmake" @ONLY)
install(FILES "${CMAKE_BINARY_DIR}/xacc-config.cmake" DESTINATION .) install(FILES "${CMAKE_BINARY_DIR}/xacc-config.cmake" DESTINATION .)
install(FILES "${CMAKE_SOURCE_DIR}/cmake/Modules/tests.cmake" DESTINATION share/xacc/)
install(FILES "${CMAKE_SOURCE_DIR}/cmake/Modules/format.cmake" DESTINATION share/xacc/) install(FILES "${CMAKE_SOURCE_DIR}/cmake/Modules/format.cmake" DESTINATION share/xacc/)
install(FILES "${CMAKE_SOURCE_DIR}/tpls/mpark-variant/variant.hpp" DESTINATION include/xacc/) install(FILES "${CMAKE_SOURCE_DIR}/tpls/mpark-variant/variant.hpp" DESTINATION include/xacc/)
install(FILES "${CMAKE_SOURCE_DIR}/tpls/taocpp/operators.hpp" DESTINATION include/xacc/)
install( DIRECTORY "${CMAKE_SOURCE_DIR}/tpls/spdlog" DESTINATION include ) install( DIRECTORY "${CMAKE_SOURCE_DIR}/tpls/spdlog" DESTINATION include )
install( DIRECTORY "${CMAKE_SOURCE_DIR}/tpls/exprtk" DESTINATION include ) install( DIRECTORY "${CMAKE_SOURCE_DIR}/tpls/exprtk" DESTINATION include )
install( DIRECTORY "${CMAKE_SOURCE_DIR}/tpls/eigen" DESTINATION include ) install( DIRECTORY "${CMAKE_SOURCE_DIR}/tpls/eigen" DESTINATION include )
......
...@@ -6,24 +6,28 @@ ...@@ -6,24 +6,28 @@
# XACC_INCLUDE_DIRS - include directories for XACC # XACC_INCLUDE_DIRS - include directories for XACC
# XACC_LIBRARIES - libraries to link against # XACC_LIBRARIES - libraries to link against
# XACC_LIBRARY_DIR - the XACC library directory # XACC_LIBRARY_DIR - the XACC library directory
include(CTest) include(CTest)
if (NOT XACC_ROOT) if (NOT XACC_ROOT)
get_filename_component(XACC_ROOT "${CMAKE_CURRENT_LIST_FILE}" PATH) get_filename_component(XACC_ROOT "${CMAKE_CURRENT_LIST_FILE}" PATH)
endif() endif()
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${XACC_ROOT}/share/xacc) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${XACC_ROOT}/share/xacc)
if (NOT TARGET format) if (NOT TARGET format)
include(format) include(format)
endif() endif()
set (XACC_LIBRARY_DIR "${XACC_ROOT}/lib") set (XACC_LIBRARY_DIR "${XACC_ROOT}/lib")
link_directories("${XACC_ROOT}/lib") link_directories("${XACC_ROOT}/lib")
set(XACC_INCLUDE_ROOT "${XACC_ROOT}/include") set(XACC_INCLUDE_ROOT "${XACC_ROOT}/include")
set(XACC_HAS_ANTLR @XACC_HAS_ANTLR@)
set (XACC_INCLUDE_DIRS "${XACC_INCLUDE_ROOT}/antlr4-runtime;${XACC_INCLUDE_ROOT}/cppmicroservices4;${XACC_INCLUDE_ROOT}/xacc;${XACC_INCLUDE_ROOT}/quantum/gate;${XACC_INCLUDE_ROOT}/quantum/utils;${XACC_INCLUDE_ROOT}/quantum/aqc;${XACC_INCLUDE_ROOT}/spdlog;${XACC_INCLUDE_ROOT}/exprtk;${XACC_INCLUDE_ROOT}/eigen;${XACC_INCLUDE_ROOT}/rapidjson/include;${XACC_INCLUDE_ROOT};${XACC_INCLUDE_ROOT}/gtest") set (XACC_INCLUDE_DIRS "${XACC_INCLUDE_ROOT}/antlr4-runtime;${XACC_INCLUDE_ROOT}/cppmicroservices4;${XACC_INCLUDE_ROOT}/xacc;${XACC_INCLUDE_ROOT}/quantum/gate;${XACC_INCLUDE_ROOT}/quantum/utils;${XACC_INCLUDE_ROOT}/quantum/aqc;${XACC_INCLUDE_ROOT}/spdlog;${XACC_INCLUDE_ROOT}/exprtk;${XACC_INCLUDE_ROOT}/eigen;${XACC_INCLUDE_ROOT}/rapidjson/include;${XACC_INCLUDE_ROOT};${XACC_INCLUDE_ROOT}/gtest")
set (XACC_LIBRARIES "xacc;xacc-quantum-gate;xacc-quantum-aqc;antlr4-runtime;CppMicroServices") set (XACC_LIBRARIES "xacc;xacc-quantum-gate;xacc-quantum-aqc;antlr4-runtime;CppMicroServices")
set (XACC_TEST_LIBRARIES "${XACC_LIBRARIES};gtest;gtest_main") set (XACC_TEST_LIBRARIES "${XACC_LIBRARIES};gtest;gtest_main")
set(BOOST_ROOT ${XACC_ROOT})
macro(add_xacc_test _TEST_NAME) macro(add_xacc_test _TEST_NAME)
add_executable(${_TEST_NAME}Tester ${_TEST_NAME}Tester.cpp) add_executable(${_TEST_NAME}Tester ${_TEST_NAME}Tester.cpp)
add_test(NAME xacc_${_TEST_NAME}Tester COMMAND ${_TEST_NAME}Tester) add_test(NAME xacc_${_TEST_NAME}Tester COMMAND ${_TEST_NAME}Tester)
......
...@@ -12,6 +12,7 @@ include_directories(${CMAKE_SOURCE_DIR}/tpls/rapidjson/include) ...@@ -12,6 +12,7 @@ include_directories(${CMAKE_SOURCE_DIR}/tpls/rapidjson/include)
include_directories(${CMAKE_SOURCE_DIR}/tpls/exprtk) include_directories(${CMAKE_SOURCE_DIR}/tpls/exprtk)
include_directories(${CMAKE_SOURCE_DIR}/tpls/spdlog) include_directories(${CMAKE_SOURCE_DIR}/tpls/spdlog)
include_directories(${CMAKE_SOURCE_DIR}/tpls/eigen) include_directories(${CMAKE_SOURCE_DIR}/tpls/eigen)
include_directories(${CMAKE_SOURCE_DIR}/tpls/taocpp)
include_directories(${CMAKE_SOURCE_DIR}/quantum/utils) include_directories(${CMAKE_SOURCE_DIR}/quantum/utils)
include_directories(${CMAKE_SOURCE_DIR}/quantum/aqc/ir) include_directories(${CMAKE_SOURCE_DIR}/quantum/aqc/ir)
...@@ -35,7 +36,7 @@ add_library(_pyxacc SHARED xacc-py.cpp) ...@@ -35,7 +36,7 @@ add_library(_pyxacc SHARED xacc-py.cpp)
set_target_properties(_pyxacc PROPERTIES PREFIX "") set_target_properties(_pyxacc PROPERTIES PREFIX "")
target_link_libraries(_pyxacc PUBLIC CppMicroServices xacc Boost::graph) target_link_libraries(_pyxacc PUBLIC CppMicroServices xacc xacc-quantum-gate Boost::graph)
if(APPLE) if(APPLE)
set_target_properties(_pyxacc PROPERTIES INSTALL_RPATH "@loader_path/lib") set_target_properties(_pyxacc PROPERTIES INSTALL_RPATH "@loader_path/lib")
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "InstructionParameter.hpp" #include "InstructionParameter.hpp"
#include "DWGraph.hpp" #include "DWGraph.hpp"
#include "EmbeddingAlgorithm.hpp" #include "EmbeddingAlgorithm.hpp"
#include "PauliOperator.hpp"
#include <pybind11/complex.h> #include <pybind11/complex.h>
#include <pybind11/numpy.h> #include <pybind11/numpy.h>
...@@ -30,6 +31,7 @@ ...@@ -30,6 +31,7 @@
namespace py = pybind11; namespace py = pybind11;
using namespace xacc; using namespace xacc;
using namespace xacc::quantum;
// `boost::variant` as an example -- can be any `std::variant`-like container // `boost::variant` as an example -- can be any `std::variant`-like container
namespace pybind11 { namespace pybind11 {
...@@ -408,6 +410,45 @@ PYBIND11_MODULE(_pyxacc, m) { ...@@ -408,6 +410,45 @@ PYBIND11_MODULE(_pyxacc, m) {
"Translate the given IR Function instance to source code in this " "Translate the given IR Function instance to source code in this "
"Compiler's language."); "Compiler's language.");
py::class_<Term>(m, "Term").def("coeff", &Term::coeff).def("ops",&Term::ops);
py::class_<PauliOperator>(m, "PauliOperator")
.def(py::init<>())
.def(py::init<std::complex<double>>())
.def(py::init<double>())
.def(py::init<std::string>())
.def(py::init<std::map<int, std::string>>())
.def(py::init<std::map<int, std::string>, double>())
.def(py::init<std::map<int, std::string>, std::complex<double>>())
.def(py::init<std::map<int, std::string>, std::string>())
.def(py::init<std::map<int, std::string>, std::complex<double>,
std::string>())
.def(py::self + py::self)
.def(py::self += py::self)
.def(py::self *= py::self)
.def(py::self *= double())
.def(py::self * py::self)
.def(py::self *= std::complex<double>())
.def(py::self -= py::self)
.def(py::self - py::self)
.def("__eq__", &PauliOperator::operator==)
.def("__repr__", &PauliOperator::toString)
.def("eval", &PauliOperator::eval)
.def("toBinaryVectors", &PauliOperator::toBinaryVectors)
.def("toXACCIR", &PauliOperator::toXACCIR)
.def("fromXACCIR", &PauliOperator::fromXACCIR)
.def("fromString", &PauliOperator::fromString)
.def("nTerms", &PauliOperator::nTerms)
.def("isClose", &PauliOperator::isClose)
.def("commutes", &PauliOperator::commutes)
.def("__len__", &PauliOperator::nTerms)
.def("nQubits", &PauliOperator::nQubits)
.def("computeActionOnKet", &PauliOperator::computeActionOnKet)
.def("computeActionOnBra", &PauliOperator::computeActionOnBra)
.def("__iter__",
[](PauliOperator &op) {
return py::make_iterator(op.begin(), op.end());
},
py::keep_alive<0, 1>());
// Expose the Program object // Expose the Program object
py::class_<xacc::Program>( py::class_<xacc::Program>(
m, "Program", m, "Program",
...@@ -527,7 +568,7 @@ PYBIND11_MODULE(_pyxacc, m) { ...@@ -527,7 +568,7 @@ PYBIND11_MODULE(_pyxacc, m) {
m.def("getCache", &xacc::getCache, ""); m.def("getCache", &xacc::getCache, "");
m.def( m.def(
"appendCache", "appendCache",
(void (*)(const std::string, const std::string, InstructionParameter &)) & (void (*)(const std::string, const std::string, InstructionParameter &,const std::string)) &
xacc::appendCache, xacc::appendCache,
""); "");
m.def("Finalize", &xacc::Finalize, "Finalize the framework"); m.def("Finalize", &xacc::Finalize, "Finalize the framework");
......
...@@ -42,8 +42,10 @@ target_include_directories(${LIBRARY_NAME} ...@@ -42,8 +42,10 @@ target_include_directories(${LIBRARY_NAME}
${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}
${CMAKE_SOURCE_DIR}/quantum/utils ${CMAKE_SOURCE_DIR}/quantum/utils
${CMAKE_SOURCE_DIR}/tpls/exprtk ${CMAKE_SOURCE_DIR}/tpls/exprtk
${CMAKE_SOURCE_DIR}/tpls/rapidjson/include) ${CMAKE_SOURCE_DIR}/tpls/rapidjson/include
${CMAKE_SOURCE_DIR}/tpls/taocpp
${CMAKE_SOURCE_DIR}/tpls/eigen)
set(_bundle_name xacc_quantum_gate) set(_bundle_name xacc_quantum_gate)
set_target_properties(${LIBRARY_NAME} set_target_properties(${LIBRARY_NAME}
PROPERTIES # This is required for every bundle PROPERTIES # This is required for every bundle
......
...@@ -53,10 +53,14 @@ auto splitParameter = [](InstructionParameter instParam) { ...@@ -53,10 +53,14 @@ auto splitParameter = [](InstructionParameter instParam) {
std::vector<std::string> split; std::vector<std::string> split;
InstructionParameter rawParam; InstructionParameter rawParam;
auto paramStr = mpark::get<std::string>(instParam); auto paramStr = mpark::get<std::string>(instParam);
std::replace(mpark::get<std::string>(instParam).begin(), mpark::get<std::string>(instParam).end(), '-', ' '); std::replace(mpark::get<std::string>(instParam).begin(),
std::replace(mpark::get<std::string>(instParam).begin(), mpark::get<std::string>(instParam).end(), '+', ' '); mpark::get<std::string>(instParam).end(), '-', ' ');
std::replace(mpark::get<std::string>(instParam).begin(), mpark::get<std::string>(instParam).end(), '*', ' '); std::replace(mpark::get<std::string>(instParam).begin(),
std::replace(mpark::get<std::string>(instParam).begin(), mpark::get<std::string>(instParam).end(), '/', ' '); mpark::get<std::string>(instParam).end(), '+', ' ');
std::replace(mpark::get<std::string>(instParam).begin(),
mpark::get<std::string>(instParam).end(), '*', ' ');
std::replace(mpark::get<std::string>(instParam).begin(),
mpark::get<std::string>(instParam).end(), '/', ' ');
auto instParamStr = instParam.as<std::string>(); auto instParamStr = instParam.as<std::string>();
split = xacc::split(instParamStr, ' '); split = xacc::split(instParamStr, ' ');
...@@ -68,6 +72,37 @@ auto splitParameter = [](InstructionParameter instParam) { ...@@ -68,6 +72,37 @@ auto splitParameter = [](InstructionParameter instParam) {
return rawParam; return rawParam;
}; };
const int GateFunction::nLogicalBits() {
std::set<int> local_bits;
xacc::InstructionIterator it(shared_from_this());
while (it.hasNext()) {
auto nextInst = it.next();
if (nextInst->isEnabled()) {
for (auto &i : nextInst->bits()) {
local_bits.insert(i);
}
}
}
return local_bits.size();
}
const int GateFunction::nPhysicalBits() {
int maxBitIdx = 0;
xacc::InstructionIterator it(shared_from_this());
while (it.hasNext()) {
auto nextInst = it.next();
if (nextInst->isEnabled()) {
for (auto &i : nextInst->bits()) {
if (maxBitIdx < i) {
maxBitIdx = i;
}
}
}
}
maxBitIdx++;
return maxBitIdx;
}
void GateFunction::removeInstruction(const int idx) { void GateFunction::removeInstruction(const int idx) {
auto instruction = getInstruction(idx); auto instruction = getInstruction(idx);
// Check to see if instruction being removed is parameterized // Check to see if instruction being removed is parameterized
...@@ -211,7 +246,7 @@ void GateFunction::replaceInstruction(const int idx, InstPtr replacingInst) { ...@@ -211,7 +246,7 @@ void GateFunction::replaceInstruction(const int idx, InstPtr replacingInst) {
void GateFunction::insertInstruction(const int idx, InstPtr newInst) { void GateFunction::insertInstruction(const int idx, InstPtr newInst) {
// Check if new GateInstruction is parameterized with 1 parameter // Check if new GateInstruction is parameterized with 1 parameter
if (newInst->isParameterized() && newInst->nParameters() <= 1) { if (newInst->isParameterized() && !newInst->isComposite()) {
xacc::InstructionParameter param = newInst->getParameter(0); xacc::InstructionParameter param = newInst->getParameter(0);
// Check if new parameter is a string // Check if new parameter is a string
if (param.isVariable()) { if (param.isVariable()) {
...@@ -286,8 +321,8 @@ const std::string GateFunction::toString(const std::string &bufferVarName) { ...@@ -286,8 +321,8 @@ const std::string GateFunction::toString(const std::string &bufferVarName) {
return retStr; return retStr;
} }
std::shared_ptr<Function> GateFunction:: std::shared_ptr<Function>
operator()(const std::vector<double> &params) { GateFunction::operator()(const std::vector<double> &params) {
if (params.size() != nParameters()) { if (params.size() != nParameters()) {
xacc::error("Invalid GateFunction evaluation: number " xacc::error("Invalid GateFunction evaluation: number "
"of parameters don't match. " + "of parameters don't match. " +
...@@ -322,8 +357,7 @@ operator()(const std::vector<double> &params) { ...@@ -322,8 +357,7 @@ operator()(const std::vector<double> &params) {
for (auto inst : getInstructions()) { for (auto inst : getInstructions()) {
if (inst->isComposite()) { if (inst->isComposite()) {
// If a Function, call this method recursively // If a Function, call this method recursively
auto evaled = auto evaled = std::dynamic_pointer_cast<Function>(inst)->operator()(p);
std::dynamic_pointer_cast<Function>(inst)->operator()(p);
evaluatedFunction->addInstruction(evaled); evaluatedFunction->addInstruction(evaled);
} else { } else {
// If a concrete GateInstruction, then check that it // If a concrete GateInstruction, then check that it
......
...@@ -91,8 +91,9 @@ public: ...@@ -91,8 +91,9 @@ public:
const int nInstructions() override; const int nInstructions() override;
const int nRequiredBits() const override { const int nRequiredBits() const override {
XACCLogger::instance()->error("GateFunction nRequiredBits() not implemented."); XACCLogger::instance()->error(
return 0; "GateFunction nRequiredBits() not implemented.");
return 0;
} }
InstPtr getInstruction(const int idx) override; InstPtr getInstruction(const int idx) override;
...@@ -121,7 +122,7 @@ public: ...@@ -121,7 +122,7 @@ public:
for (int i = 0; i < instructions.size(); i++) { for (int i = 0; i < instructions.size(); i++) {
auto inst = *std::next(instructions.begin(), i); auto inst = *std::next(instructions.begin(), i);
if (inst->isAnalog()) { if (inst->isAnalog()) {
return true; return true;
} }
} }
return false; return false;
...@@ -193,7 +194,7 @@ public: ...@@ -193,7 +194,7 @@ public:
* *
* @return qasm The instruction as qasm * @return qasm The instruction as qasm
*/ */
const std::string toString() override {return toString("q");} const std::string toString() override { return toString("q"); }
InstructionParameter getParameter(const int idx) const override; InstructionParameter getParameter(const int idx) const override;
...@@ -207,32 +208,26 @@ public: ...@@ -207,32 +208,26 @@ public:
const int nParameters() override; const int nParameters() override;
std::shared_ptr<Function> operator()(const std::vector<double> &params) override; std::shared_ptr<Function>
operator()(const std::vector<double> &params) override;
Graph<CircuitNode, Directed> toGraph() override; Graph<CircuitNode, Directed> toGraph() override;
// void fromGraph(Graph<CircuitNode>& graph) override; // void fromGraph(Graph<CircuitNode>& graph) override;
// void fromGraph(std::istream& input) override; // void fromGraph(std::istream& input) override;
/** /**
* Return the number of logical qubits. * Return the number of logical qubits.
* *
* @return nLogical The number of logical qubits. * @return nLogical The number of logical qubits.
*/ */
const int nLogicalBits() override { const int nLogicalBits() override;
XACCLogger::instance()->error("GateFunction nLogicalBits() not implemented.");
return 0;
}
/** /**
* Return the number of physical qubits. * Return the number of physical qubits.
* *
* @return nPhysical The number of physical qubits. * @return nPhysical The number of physical qubits.
*/ */
const int nPhysicalBits() override { const int nPhysicalBits() override;
XACCLogger::instance()->error("GateFunction nPhysicalBits() not implemented.");
return 0;
}
/** /**
* Return true if this Instruction has * Return true if this Instruction has
...@@ -240,7 +235,7 @@ public: ...@@ -240,7 +235,7 @@ public:
* *
* @return hasOptions * @return hasOptions
*/ */
bool hasOptions() override {return false;} bool hasOptions() override { return !options.empty(); }
/** /**
* Set the value of an option with the given name. * Set the value of an option with the given name.
...@@ -249,7 +244,10 @@ public: ...@@ -249,7 +244,10 @@ public:
* @param option The value of the option * @param option The value of the option
*/ */
void setOption(const std::string optName, void setOption(const std::string optName,
InstructionParameter option) override {} InstructionParameter option) override {
options.insert({optName, option});
}
/** /**
* Get the value of an option with the given name. * Get the value of an option with the given name.
* *
...@@ -257,8 +255,7 @@ public: ...@@ -257,8 +255,7 @@ public:
* @return option The value of the option. * @return option The value of the option.
*/ */
InstructionParameter getOption(const std::string optName) override { InstructionParameter getOption(const std::string optName) override {
XACCLogger::instance()->error("GateFunction does not have options."); return options[optName];
return InstructionParameter(0);
} }
/** /**
...@@ -267,8 +264,7 @@ public: ...@@ -267,8 +264,7 @@ public:
* @return optMap The options map. * @return optMap The options map.
*/ */
std::map<std::string, InstructionParameter> getOptions() override { std::map<std::string, InstructionParameter> getOptions() override {
XACCLogger::instance()->error("GateFunction does not have options."); return options;
return std::map<std::string, InstructionParameter>{};
} }
DEFINE_VISITABLE() DEFINE_VISITABLE()
...@@ -284,6 +280,9 @@ protected: ...@@ -284,6 +280,9 @@ protected:
std::vector<InstructionParameter> parameters; std::vector<InstructionParameter> parameters;
std::string tag = ""; std::string tag = "";
std::map<std::string, InstructionParameter> options;
}; };
} // namespace quantum } // namespace quantum
......
This diff is collapsed.
/*******************************************************************************
* Copyright (c) 2019 UT-Battelle, LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompanies this
* distribution. The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution
*License is available at https://eclipse.org/org/documents/edl-v10.php
*
* Contributors:
* Alexander J. McCaskey - initial API and implementation
*******************************************************************************/
#ifndef QUANTUM_UTILS_PAULIOPERATOR_HPP_
#define QUANTUM_UTILS_PAULIOPERATOR_HPP_
#include <unordered_map>
#include <map>
#include <stdio.h>
#include <stdlib.h>
#include "Observable.hpp"
#include "IR.hpp"
// Putting this here due to clang error
// not able to find operator!= from operators.hpp
namespace xacc {
namespace quantum {
class PauliOperator;
}
} // namespace xacc
bool operator==(const xacc::quantum::PauliOperator &lhs,
const xacc::quantum::PauliOperator &rhs);
#include "operators.hpp"
namespace xacc {
namespace quantum {
// A Term can be a coefficient, a variable coefficient, and the terms themselves
using TermTuple =
std::tuple<std::complex<double>, std::string, std::map<int, std::string>>;
using c = std::complex<double>;
using ActionResult = std::pair<std::string, c>;
enum ActionType { Bra, Ket };
class Triplet : std::tuple<std::uint64_t, std::uint64_t, std::complex<double>> {
public:
Triplet(std::uint64_t r, std::uint64_t c, std::complex<double> coeff) {
std::get<0>(*this) = r;
std::get<1>(*this) = c;
std::get<2>(*this) = coeff;
}
const std::uint64_t row() { return std::get<0>(*this); }
const std::uint64_t col() { return std::get<1>(*this); }
const std::complex<double> coeff() { return std::get<2>(*this); }
};
class Term : public TermTuple,
public tao::operators::commutative_multipliable<Term>,
public tao::operators::equality_comparable<Term> {
protected:
// static std::map<std::string, std::pair<c, std::string>>
void create_map() {
// static std::map<std::string, std::pair<c, std::string>> m;
pauliProducts.insert({"II", {c(1.0, 0.0), "I"}});
pauliProducts.insert({"IX", {c(1.0, 0.0), "X"}});
pauliProducts.insert({"XI", {c(1.0, 0.0), "X"}});
pauliProducts.insert({"IY", {c(1.0, 0.0), "Y"}});
pauliProducts.insert({"YI", {c(1.0, 0.0), "Y"}});
pauliProducts.insert({"ZI", {c(1.0, 0.0), "Z"}});
pauliProducts.insert({"IZ", {c(1.0, 0.0), "Z"}});
pauliProducts.insert({"XX", {c(1.0, 0.0), "I"}});
pauliProducts.insert({"YY", {c(1.0, 0.0), "I"}});
pauliProducts.insert({"ZZ", {c(1.0, 0.0), "I"}});
pauliProducts.insert({"XY", {c(0.0, 1.0), "Z"}});
pauliProducts.insert({"XZ", {c(0.0, -1.0), "Y"}});
pauliProducts.insert({"YX", {c(0.0, -1.0), "Z"}});
pauliProducts.insert({"YZ", {c(0.0, 1.0), "X"}});
pauliProducts.insert({"ZX", {c(0.0, 1.0), "Y"}});
pauliProducts.insert({"ZY", {c(0.0, -1.0), "X"}});
// return m;
}
std::map<std::string, std::pair<c, std::string>> pauliProducts;
public:
Term() {
std::get<0>(*this) = std::complex<double>(0, 0);
std::get<1>(*this) = "";
std::get<2>(*this) = {};
create_map();
}
Term(const Term &t) {