tket
Loading...
Searching...
No Matches
MatrixAnalysis.hpp
Go to the documentation of this file.
1// Copyright Quantinuum
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma once
16
17#include <array>
18#include <tklog/TketLog.hpp>
19#include <vector>
20
21#include "EigenConfig.hpp"
22#include "UnitID.hpp"
25
26namespace tket {
27
28typedef Eigen::Matrix<bool, Eigen::Dynamic, Eigen::Dynamic> MatrixXb;
29typedef Eigen::Matrix<bool, Eigen::Dynamic, 1> VectorXb;
30typedef Eigen::Matrix<bool, 2, 1> Vector2b;
31// Eigen::Matrix8cd doesn't exist.
32typedef Eigen::Matrix<std::complex<double>, 8, 8> Matrix8cd;
33
44bool is_unitary(const Eigen::MatrixXcd &U, double tol = EPS);
45bool is_projector(const Eigen::MatrixXcd &P, double tol = EPS);
46
61Eigen::PermutationMatrix<Eigen::Dynamic> lift_perm(
62 const std::map<unsigned, unsigned> &p);
63
64// Convert between ILO-BE and DLO-BE conventions
65Eigen::Matrix4cd reverse_indexing(const Eigen::Matrix4cd &m);
67Eigen::MatrixXcd reverse_indexing(const Eigen::MatrixXcd &m);
68Eigen::VectorXcd reverse_indexing(const Eigen::VectorXcd &v);
69
70Eigen::MatrixXcd apply_qubit_permutation(
71 const Eigen::MatrixXcd &m, const qubit_map_t &perm);
72Eigen::VectorXcd apply_qubit_permutation(
73 const Eigen::VectorXcd &v, const qubit_map_t &perm);
74
75std::pair<MatrixXb, MatrixXb> binary_LLT_decomposition(const MatrixXb &a);
76std::vector<std::pair<unsigned, unsigned>> gaussian_elimination_col_ops(
77 const MatrixXb &a, unsigned blocksize = 6);
78std::vector<std::pair<unsigned, unsigned>> gaussian_elimination_row_ops(
79 const MatrixXb &a, unsigned blocksize = 6);
80
98std::tuple<Eigen::Matrix4cd, std::array<double, 3>, Eigen::Matrix4cd>
99get_information_content(const Eigen::Matrix4cd &X);
100
101// given a 4x4 unitary matrix (ILO-BE), returns two 2x2 unitaries that
102// approximately make the input by kronecker product
103std::pair<Eigen::Matrix2cd, Eigen::Matrix2cd> kronecker_decomposition(
104 Eigen::Matrix4cd &U);
105
110unsigned get_matrix_size(unsigned number_of_qubits);
111
114unsigned get_number_of_qubits(unsigned matrix_size);
115
119typedef Eigen::Triplet<std::complex<double>> TripletCd;
120
121typedef Eigen::SparseMatrix<std::complex<double>> SparseMatrixXcd;
122
124 const std::vector<TripletCd> &triplets, unsigned rows, unsigned cols);
125
127 const std::vector<TripletCd> &triplets, unsigned rows);
128
133std::vector<TripletCd> get_triplets(
134 const SparseMatrixXcd &matr, double abs_epsilon = EPS);
135
144std::vector<TripletCd> get_triplets(
145 const Eigen::MatrixXcd &matr, double abs_epsilon = EPS);
146
167double trace_fidelity(double a, double b, double c);
168
174bool in_weyl_chamber(const std::array<Expr, 3> &k);
175
179Eigen::Matrix2cd nth_root(const Eigen::Matrix2cd &u, unsigned long long n);
180
181template <class MatrixT>
182static inline MatrixT clamp_to_unitary(const MatrixT &A) {
183 if (is_unitary(A)) {
184 return A;
185 } else {
186 tket_log()->warn(
187 "Non-unitary product of matrices assumed unitary: "
188 "presuming rounding error and applying correction.");
189 // Fact: if A is an arbitrary complex matrix, and
190 // A = U * S * V^+
191 // is its singular-value decomposition, then
192 // U * V^+
193 // is the unitary matrix closest to A in the Frobenius norm.
194 // See e.g. https://math.stackexchange.com/a/2215371 for a proof.
195 Eigen::JacobiSVD<MatrixT, Eigen::NoQRPreconditioner> svd(
196 A, Eigen::DecompositionOptions::ComputeFullU |
197 Eigen::DecompositionOptions::ComputeFullV);
198 return svd.matrixU() * svd.matrixV().adjoint();
199 }
200}
201
207template <class MatrixT>
208MatrixT unitary_product2(const MatrixT &U, const MatrixT &V) {
209 MatrixT A = U * V;
210 return clamp_to_unitary(A);
211}
212
218template <class MatrixT>
219MatrixT unitary_product3(const MatrixT &U, const MatrixT &V, const MatrixT &W) {
220 MatrixT A = U * V * W;
221 return clamp_to_unitary(A);
222}
223
224} // namespace tket
Generally useful typedefs and constants.
Include this file rather than including the Eigen headers directly.
Functions related to (possibly symbolic) phase values.
std::vector< TripletCd > triplets
Named registers of arrays of (quantum or classical) nodes.
Defines tket::DeviceCharacterisation, used in NoiseAwarePlacement and in commute_SQ_gates_through_SWA...
Definition Path.cpp:22
SparseMatrixXcd get_sparse_matrix(const std::vector< TripletCd > &triplets, unsigned rows, unsigned cols)
Eigen::Matrix< bool, Eigen::Dynamic, 1 > VectorXb
Eigen::Matrix< bool, 2, 1 > Vector2b
Eigen::MatrixXcd apply_qubit_permutation(const Eigen::MatrixXcd &m, const qubit_map_t &perm)
std::map< Qubit, Qubit > qubit_map_t
Definition UnitID.hpp:316
std::pair< Eigen::Matrix2cd, Eigen::Matrix2cd > kronecker_decomposition(Eigen::Matrix4cd &U)
unsigned get_matrix_size(unsigned number_of_qubits)
Returns 2^n, but throws if n is too large (causes overflow).
Eigen::PermutationMatrix< Eigen::Dynamic > lift_perm(const std::map< unsigned, unsigned > &p)
Lift a permutation of to a permutation of as a matrix.
bool in_weyl_chamber(const std::array< Expr, 3 > &k)
Whether a triplet of TK2 angles are normalised.
bool is_projector(const Eigen::MatrixXcd &P, double tol)
std::vector< TripletCd > get_triplets(const SparseMatrixXcd &matr, double abs_epsilon)
abs_epsilon is used to decide if a near-zero entry should be set to zero exactly.
std::pair< MatrixXb, MatrixXb > binary_LLT_decomposition(const MatrixXb &a)
bool is_unitary(const Eigen::MatrixXcd &U, double tol)
Test matrix for unitarity.
double trace_fidelity(double a, double b, double c)
Similarity measure of TK2(a, b, c) to SU(4) identity.
std::tuple< Eigen::Matrix4cd, std::array< double, 3 >, Eigen::Matrix4cd > get_information_content(const Eigen::Matrix4cd &X)
Performs KAK decomposition.
constexpr double EPS
Default tolerance for floating-point comparisons.
Definition Constants.hpp:38
unsigned get_number_of_qubits(unsigned matrix_size)
We have a matrix size, which should be 2^n.
Eigen::Matrix< std::complex< double >, 8, 8 > Matrix8cd
Eigen::SparseMatrix< std::complex< double > > SparseMatrixXcd
SparseMatrixXcd get_sparse_square_matrix(const std::vector< TripletCd > &triplets, unsigned rows)
MatrixT unitary_product3(const MatrixT &U, const MatrixT &V, const MatrixT &W)
Compute the product of three unitary matrices, with error correction.
Eigen::Matrix4cd reverse_indexing(const Eigen::Matrix4cd &m)
std::vector< std::pair< unsigned, unsigned > > gaussian_elimination_col_ops(const MatrixXb &a, unsigned blocksize)
MatrixT unitary_product2(const MatrixT &U, const MatrixT &V)
Compute the product of two unitary matrices, with error correction.
Eigen::Triplet< std::complex< double > > TripletCd
It is sometimes more convenient to deal with Triplets directly, rather than sparse matrices.
Eigen::Matrix2cd nth_root(const Eigen::Matrix2cd &u, unsigned long long n)
Get an nth root of a 2x2 unitary matrix.
std::vector< std::pair< unsigned, unsigned > > gaussian_elimination_row_ops(const MatrixXb &a, unsigned blocksize)
Eigen::Matrix< bool, Eigen::Dynamic, Eigen::Dynamic > MatrixXb