Loading...
Searching...
No Matches
unitary_exponential.hpp
Go to the documentation of this file.
1#pragma once
2
3/**
4 * exp(A) for an anti-Hermitian A, which is unitary: the rotation a gauge
5 * takes when it moves along a descent direction.
6 *
7 * Through the Hermitian H = -iA: exp(A) = exp(iH) = V diag(exp(i lambda))
8 * V^dagger, with V and lambda from the eigensolver. Exact for any step
9 * length, where a truncated series would be unitary only for a small one --
10 * and a line search takes steps of every size.
11 */
12
13#include <complex>
14#include <vector>
15
21
22namespace q3 {
23
24[[nodiscard]] inline DenseMatrix<Complex>
26 const HermitianEigenDecomposition decomposition =
27 HermitianEigensolver("exponential_of_anti_hermitian")
28 .solve(generator.scaled(Complex(0.0, -1.0)));
29
30 std::vector<Complex> phases;
31 phases.reserve(decomposition.eigenvalues.size());
32 for (const Real eigenvalue : decomposition.eigenvalues) {
33 phases.push_back(std::exp(Complex(0.0, eigenvalue)));
34 }
36 decomposition.eigenvectors.scaled_columns(phases),
38 decomposition.eigenvectors);
39}
40
41} // namespace q3
DenseMatrix scaled_columns(const std::vector< Factor > &factors) const
this * diag(factors): column j scaled by factors[j], which needs one factor per column.
DenseMatrix scaled(const Factor &factor) const
factor * this, element by element.
HermitianEigenDecomposition solve(DenseMatrix< Complex > matrix) const
DenseMatrix< Complex > exponential_of_anti_hermitian(const DenseMatrix< Complex > &generator)
double Real
std::complex< double > Complex
DenseMatrix< Complex > multiply(MatrixOperation left_operation, const DenseMatrix< Complex > &left, MatrixOperation right_operation, const DenseMatrix< Complex > &right, Complex alpha=Complex(1.0, 0.0))
alpha * op(left) * op(right), as a new matrix of the product's shape.