Maestro 0.3.11
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
QCSimTensorUtils.h
Go to the documentation of this file.
1#pragma once
2#include "MPSSimulator.h"
3#include <functional>
4#include <type_traits>
5
7{
8// Keep compatibility with the pinned QCSim dependency while allowing local
9// and newer QCSim builds to use the summary and batch APIs.
10template <typename T, typename = void> struct HasBondSummary : std::false_type
11{
12};
13
14template <typename T>
15struct HasBondSummary<T, std::void_t<decltype(std::declval<T &>().SetBondDimensionSummaryCallback(std::declval<std::function<void(Eigen::Index)>>()))>>
16 : std::true_type
17{
18};
19
20template <typename T, typename Callback> void InstallBondSummary(T &backend, Callback callback)
21{
22 if constexpr (HasBondSummary<T>::value)
23 {
24 backend.SetBondDimensionSummaryCallback(std::move(callback));
25 }
26 else
27 {
28 backend.SetBondDimensionCallback([callback = std::move(callback)](const auto &dims) {
29 Eigen::Index maximum = 1;
30 for (auto dim : dims)
31 maximum = std::max(maximum, dim);
32 callback(maximum);
33 });
34 }
35}
36
37template <typename T, typename = void> struct HasTensorExpectationBatch : std::false_type
38{
39};
40
41template <typename T>
42struct HasTensorExpectationBatch<T, std::void_t<decltype(std::declval<T &>().ExpectationValues(std::declval<const std::vector<std::string> &>()))>>
43 : std::true_type
44{
45};
46
47template <typename T, typename = void> struct HasNormalizedTensorExpectationBatch : std::false_type
48{
49};
50
51template <typename T>
53 T, std::void_t<decltype(std::declval<const T &>().ExpectationValues(std::declval<const std::vector<std::string> &>(), true))>> : std::true_type
54{
55};
56
57template <typename T> std::vector<std::complex<double>> ComplexTensorExpectationBatch(const T &backend, const std::vector<std::string> &paulis, bool normalized)
58{
60 {
61 return backend.ExpectationValues(paulis, normalized);
62 }
63 else
64 {
65 std::vector<std::complex<double>> values;
66 values.reserve(paulis.size());
67 for (const auto &pauli : paulis)
68 values.push_back(normalized ? backend.ExpectationValue(pauli) : backend.UnnormalizedExpectationValue(pauli));
69 return values;
70 }
71}
72
73template <typename T> std::vector<std::complex<double>> TensorExpectationBatch(T &backend, const std::vector<std::string> &paulis)
74{
76 {
77 return backend.ExpectationValues(paulis);
78 }
79 else
80 {
81 std::vector<std::complex<double>> values;
82 values.reserve(paulis.size());
83 for (const auto &pauli : paulis)
84 {
85 if constexpr (std::is_same_v<T, QC::TensorNetworks::MPSSimulator>)
86 {
87 static const QC::Gates::PauliXGate<> x;
88 static const QC::Gates::PauliYGate<> y;
89 static const QC::Gates::PauliZGate<> z;
90 std::vector<QC::Gates::AppliedGate<>> gates;
91 for (size_t q = 0; q < pauli.size(); ++q)
92 {
93 if (pauli[q] == 'X')
94 gates.emplace_back(x.getRawOperatorMatrix(), q);
95 if (pauli[q] == 'Y')
96 gates.emplace_back(y.getRawOperatorMatrix(), q);
97 if (pauli[q] == 'Z')
98 gates.emplace_back(z.getRawOperatorMatrix(), q);
99 }
100 values.push_back(backend.ExpectationValue(gates));
101 }
102 else
103 {
104 values.push_back(backend.ExpectationValue(pauli));
105 }
106 }
107 return values;
108 }
109}
110
111} // namespace Simulators::Private
std::vector< std::complex< double > > ComplexTensorExpectationBatch(const T &backend, const std::vector< std::string > &paulis, bool normalized)
std::vector< std::complex< double > > TensorExpectationBatch(T &backend, const std::vector< std::string > &paulis)
void InstallBondSummary(T &backend, Callback callback)