pub struct UnitaryMatrix<C: ComplexScalar> { /* private fields */ }Expand description
A unitary matrix over a qudit system.
This is a thin wrapper around a matrix that ensures it is unitary.
Implementations§
Source§impl<C: ComplexScalar> UnitaryMatrix<C>
impl<C: ComplexScalar> UnitaryMatrix<C>
Sourcepub fn new<T: Into<Radices>>(radices: T, matrix: Mat<C>) -> Self
pub fn new<T: Into<Radices>>(radices: T, matrix: Mat<C>) -> Self
Create a new unitary matrix.
§Arguments
-
radices- The radices of the qudit system. -
matrix- The matrix to wrap.
§Panics
Panics if the matrix is not unitary.
§Example
use faer::Mat;
use qudit_core::UnitaryMatrix;
use qudit_core::c64;
let unitary: UnitaryMatrix<c64> = UnitaryMatrix::new([2, 2], Mat::<c64>::identity(4, 4));§See Also
- UnitaryMatrix::is_unitary - Check if a matrix is a unitary.
- UnitaryMatrix::new_unchecked - Create a unitary without checking unitary conditions.
- UnitaryMatrix::identity - Create a unitary identity matrix.
- UnitaryMatrix::random - Create a random unitary matrix.
Sourcepub fn new_unchecked<T: Into<Radices>>(radices: T, matrix: Mat<C>) -> Self
pub fn new_unchecked<T: Into<Radices>>(radices: T, matrix: Mat<C>) -> Self
Create a new unitary matrix without checking if it is unitary.
§Arguments
-
radices- The radices of the qudit system. -
matrix- The matrix to wrap.
§Safety
The caller must ensure that the provided matrix is unitary.
§Example
use faer::Mat;
use qudit_core::UnitaryMatrix;
use qudit_core::c64;
let unitary: UnitaryMatrix<c64> = UnitaryMatrix::new_unchecked([2, 2], Mat::identity(4, 4));§See Also
- UnitaryMatrix::new - Create a unitary matrix.
- UnitaryMatrix::identity - Create a unitary identity matrix.
- UnitaryMatrix::random - Create a random unitary matrix.
- UnitaryMatrix::is_unitary - Check if a matrix is a unitary.
Sourcepub fn identity<T: Into<Radices>>(radices: T) -> Self
pub fn identity<T: Into<Radices>>(radices: T) -> Self
Create a new identity unitary matrix for a given qudit system.
§Arguments
radices- The radices of the qudit system.
§Returns
A new unitary matrix that is the identity.
§Example
use faer::Mat;
use qudit_core::UnitaryMatrix;
use qudit_core::c64;
let unitary: UnitaryMatrix<c64> = UnitaryMatrix::identity([2, 2]);
assert_eq!(unitary, UnitaryMatrix::new([2, 2], Mat::identity(4, 4)));§See Also
- UnitaryMatrix::new - Create a unitary matrix.
- UnitaryMatrix::random - Create a random unitary matrix.
Sourcepub fn random<T: Into<Radices>>(radices: T) -> Self
pub fn random<T: Into<Radices>>(radices: T) -> Self
Generate a random Unitary from the haar distribution.
Reference:
§Arguments
radices- The radices of the qudit system.
§Returns
A new unitary matrix that is random.
§Example
use qudit_core::c64;
use qudit_core::UnitaryMatrix;
let unitary: UnitaryMatrix<c64> = UnitaryMatrix::random([2, 2]);
assert!(UnitaryMatrix::is_unitary(&unitary));§See Also
- UnitaryMatrix::new - Create a unitary matrix.
- UnitaryMatrix::identity - Create a unitary identity matrix.
Sourcepub fn is_unitary(mat: impl AsMatRef<T = C, Rows = usize, Cols = usize>) -> bool
pub fn is_unitary(mat: impl AsMatRef<T = C, Rows = usize, Cols = usize>) -> bool
Check if a matrix is unitary.
A matrix is unitary if it satisfies the following condition:
U U^\dagger = U^\dagger U = IWhere U is the matrix, U^\dagger is the dagger (conjugate-transpose)
of U, and I is the identity matrix of the same size.
§Arguments
mat- The matrix to check.
§Returns
true if the matrix is unitary, false otherwise.
§Example
use qudit_core::c64;
use faer::mat;
use faer::Mat;
use qudit_core::UnitaryMatrix;
let mat: Mat<c64> = Mat::identity(2, 2);
assert!(UnitaryMatrix::is_unitary(&mat));
let mat = Mat::from_fn(2, 2, |_, _| c64::new(1.0, 1.0));
assert!(!UnitaryMatrix::is_unitary(&mat));§Notes
The function checks the l2 norm or frobenius norm of the difference
between the product of the matrix and its adjoint and the identity.
Due to floating point errors, the norm is checked against a threshold
defined by the THRESHOLD constant in the ComplexScalar trait.
§See Also
- ComplexScalar - The floating point number type used for the matrix.
- RealScalar::is_close - The threshold used to check if a matrix is unitary.
Sourcepub fn get_distance_from(
&self,
x: impl AsMatRef<T = C, Rows = usize, Cols = usize>,
) -> C::R
pub fn get_distance_from( &self, x: impl AsMatRef<T = C, Rows = usize, Cols = usize>, ) -> C::R
Global-phase-agnostic, psuedo-metric over the space of unitaries.
This is based on the hilbert-schmidt inner product. It is defined as:
\sqrt{1 - \big(\frac{|\text{tr}(A B^\dagger)|}{\text{dim}(A)}\big)^2}Where A and B are the unitaries, B^\dagger is the conjugate transpose
of B, |\text{tr}(A B^\dagger)| is the absolute value of the trace of the
product of A and B^\dagger, and dim(A) is the dimension of A.
§Arguments
x- The other unitary matrix.
§Returns
The distance between the two unitaries.
§Panics
Panics if the two unitaries have different dimensions.
§Example
use qudit_core::c64;
use faer::mat;
use faer::Mat;
use qudit_core::UnitaryMatrix;
use qudit_core::ComplexScalar;
let u1: UnitaryMatrix<c64> = UnitaryMatrix::identity([2, 2]);
let u2 = UnitaryMatrix::identity([2, 2]);
let u3 = UnitaryMatrix::random([2, 2]);
assert_eq!(u1.get_distance_from(&u2), 0.0);
assert!(u1.get_distance_from(&u3) > 0.0);§See Also
- RealScalar::is_close - The threshold used to check if a matrix is unitary.
Sourcepub fn permute(&self, perm: &QuditPermutation) -> UnitaryMatrix<C>
pub fn permute(&self, perm: &QuditPermutation) -> UnitaryMatrix<C>
Permute the unitary matrix according to a qudit system permutation.
§Arguments
perm- The permutation to apply.
§Returns
A newly allocated unitary matrix that is the result of applying the permutation to the original unitary matrix.
§Panics
Panics if there is a radix mismatch between the unitary matrix and the permutation.
§Example
use qudit_core::c64;
use faer::mat;
use faer::Mat;
use qudit_core::UnitaryMatrix;
use qudit_core::QuditPermutation;
use num_traits::{One, Zero};
let unitary: UnitaryMatrix<c64> = UnitaryMatrix::identity([2, 2]);
let perm = QuditPermutation::new([2, 2], &vec![1, 0]);
let permuted = unitary.permute(&perm);
let mat = mat![
[c64::one(), c64::zero(), c64::zero(), c64::zero()],
[c64::zero(), c64::zero(), c64::one(), c64::zero()],
[c64::zero(), c64::one(), c64::zero(), c64::zero()],
[c64::zero(), c64::zero(), c64::zero(), c64::one()],
];
assert_eq!(permuted, UnitaryMatrix::new([2, 2], Mat::identity(4, 4)));Sourcepub fn conjugate(&self) -> UnitaryMatrix<C>
pub fn conjugate(&self) -> UnitaryMatrix<C>
Conjugate the unitary matrix.
§Returns
A newly allocated unitary matrix that is the conjugate of the original unitary matrix.
§Example
use qudit_core::c64;
use faer::mat;
use faer::Mat;
use qudit_core::UnitaryMatrix;
use num_traits::Zero;
let y_mat = mat![
[c64::zero(), c64::new(0.0, -1.0)],
[c64::new(0.0, 1.0), c64::zero()],
];
let unitary = UnitaryMatrix::new([2], y_mat);
let conjugate = unitary.conjugate();
let y_mat_conjugate = mat![
[c64::zero(), c64::new(0.0, 1.0)],
[c64::new(0.0, -1.0), c64::zero()],
];
assert_eq!(conjugate, UnitaryMatrix::new([2], y_mat_conjugate));Sourcepub fn transpose(&self) -> UnitaryMatrix<C>
pub fn transpose(&self) -> UnitaryMatrix<C>
Transpose the unitary matrix.
§Returns
A newly allocated unitary matrix that is the transpose of the original unitary matrix.
§Example
use qudit_core::c64;
use faer::mat;
use faer::Mat;
use qudit_core::UnitaryMatrix;
use num_traits::Zero;
let y_mat = mat![
[c64::zero(), c64::new(0.0, -1.0)],
[c64::new(0.0, 1.0), c64::zero()],
];
let unitary = UnitaryMatrix::new([2], y_mat);
let transpose = unitary.transpose();
let y_mat_transpose = mat![
[c64::zero(), c64::new(0.0, 1.0)],
[c64::new(0.0, -1.0), c64::zero()],
];
assert_eq!(transpose, UnitaryMatrix::new([2], y_mat_transpose));Sourcepub fn dagger(&self) -> Self
pub fn dagger(&self) -> Self
Adjoint or dagger the unitary matrix.
§Returns
A newly allocated unitary matrix that is the adjoint of the original unitary matrix.
§Example
use qudit_core::c64;
use faer::mat;
use faer::Mat;
use qudit_core::UnitaryMatrix;
use num_traits::Zero;
let y_mat: Mat<c64> = mat![
[c64::zero(), c64::new(0.0, -1.0)],
[c64::new(0.0, 1.0), c64::zero()],
];
let unitary = UnitaryMatrix::new([2], y_mat);
let dagger: UnitaryMatrix<c64> = unitary.dagger();
let y_mat_adjoint = mat![
[c64::zero(), c64::new(0.0, -1.0)],
[c64::new(0.0, 1.0), c64::zero()],
];
assert_eq!(dagger, UnitaryMatrix::new([2], y_mat_adjoint));
assert_eq!(dagger.dagger(), unitary);
assert_eq!(dagger.dot(&unitary), Mat::<c64>::identity(2, 2));
assert_eq!(unitary.dot(&dagger), Mat::<c64>::identity(2, 2));Sourcepub fn adjoint(&self) -> Self
pub fn adjoint(&self) -> Self
Adjoint or dagger the unitary matrix (Alias for Self::dagger).
Sourcepub fn dot(&self, rhs: impl AsMatRef<T = C, Rows = usize, Cols = usize>) -> Self
pub fn dot(&self, rhs: impl AsMatRef<T = C, Rows = usize, Cols = usize>) -> Self
Multiply the unitary matrix by another matrix.
§Arguments
rhs- The matrix to multiply by.
§Returns
A newly allocated unitary matrix that is the result of multiplying the original unitary matrix by the other matrix.
§Panics
Panics if the two matrices have different dimensions.
§Example
use qudit_core::c64;
use faer::mat;
use faer::Mat;
use qudit_core::UnitaryMatrix;
use num_traits::Zero;
let y_mat = mat![
[c64::zero(), c64::new(0.0, -1.0)],
[c64::new(0.0, 1.0), c64::zero()],
];
let unitary = UnitaryMatrix::new([2], y_mat.clone());
let result = unitary.dot(&unitary);
assert_eq!(result, UnitaryMatrix::new([2], y_mat.clone() * y_mat));§See Also
- crate::accel::matmul_unchecked - The accelerated version of the matrix multiplication.
Sourcepub fn kron(&self, rhs: &UnitaryMatrix<C>) -> Self
pub fn kron(&self, rhs: &UnitaryMatrix<C>) -> Self
Kronecker product the unitary matrix with another matrix.
§Arguments
rhs- The matrix to kronecker product with.
§Returns
A newly allocated unitary matrix that is the result of kronecker producting the original unitary matrix with the other matrix.
§Example
use qudit_core::c64;
use faer::mat;
use faer::Mat;
use qudit_core::UnitaryMatrix;
use num_traits::Zero;
let y_mat = mat![
[c64::zero(), c64::new(0.0, -1.0)],
[c64::new(0.0, 1.0), c64::zero()],
];
let unitary = UnitaryMatrix::new([2], y_mat.clone());
let result = unitary.kron(&unitary);
let y_mat_kron = mat![
[c64::zero(), c64::zero(), c64::zero(), c64::new(-1.0, 0.0)],
[c64::zero(), c64::zero(), c64::new(1.0, 0.0), c64::zero()],
[c64::zero(), c64::new(1.0, 0.0), c64::zero(), c64::zero()],
[c64::new(-1.0, 0.0), c64::zero(), c64::zero(), c64::zero()],
];
assert_eq!(result, UnitaryMatrix::new([2, 2], y_mat_kron));§See Also
- Mat::kron - The method used to perform the kronecker product.
- crate::accel::kron - The accelerated version of the kronecker product.
Trait Implementations§
Source§impl<C: ComplexScalar> AsMatRef for UnitaryMatrix<C>
impl<C: ComplexScalar> AsMatRef for UnitaryMatrix<C>
Source§impl<C: ComplexScalar> BitWidthConvertible for UnitaryMatrix<C>
impl<C: ComplexScalar> BitWidthConvertible for UnitaryMatrix<C>
Source§impl<C: Clone + ComplexScalar> Clone for UnitaryMatrix<C>
impl<C: Clone + ComplexScalar> Clone for UnitaryMatrix<C>
Source§fn clone(&self) -> UnitaryMatrix<C>
fn clone(&self) -> UnitaryMatrix<C>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more