\(\Complex^n\) como principal ejemplar.

Ejercicio 2.1.1

Add the following two vectors: \[\begin{bmatrix}5+13i\\6+2i\\0.53-6i\\12\end{bmatrix} + \begin{bmatrix}7-8i\\4i\\2\\9.4+3i\end{bmatrix}.\]

La suma de vectores es entrada a entrada:

\[\begin{bmatrix}5+13i+7-8i\\6+2i+4i\\0.53-6i+2\\12+9.4+3i\end{bmatrix}=\begin{bmatrix}12+5i\\6+6i\\2.53-6i\\21.4+3i\end{bmatrix}\]

Ejercicio 2.1.2

Formally prove the associativity property.

Usando la notación del libro. Sean 3 vectores \(V,W,X\in\Complex^n\).

\[\left(\left(V+W\right)+X\right)[j]=(V+W)[j]+X[j]=\left(V[j]+W[j]\right)+X[j]\]

Al ser \(V[j],W[j],X[j]\) números complejos, y sabemos que estos son asociativos:

\[\left(V[j]+W[j]\right)+X[j]=V[j]+\left(W[j]+X[j]\right)=V[j]+(W+X)[j]=\left(V+\left(W+X\right)\right)[j]\]

Ejercicio 2.1.3

Scalar multiply \(8-2i\) with \(\begin{bmatrix}16+2.3i\\-7i\\6\\5-4i\end{bmatrix}\).

La multiplicación por escalares es el escalar por cada entrada:

\[\begin{bmatrix}(8-2i)(16+2.3i)\\(8-2i)(-7i)\\(8-2i)6\\(8-2i)(5-4i)\end{bmatrix}=\begin{bmatrix}132.6-13.6i\\-14-56i\\48-12i\\32-42i\end{bmatrix}\]

Ejercicio 2.1.5

Formally prove that \((c_1+c_2)\cdot V=c_1\cdot V+c_2\cdot V\).

Sean \(V\in\Complex^n\) y \(c_1,c_2\in\Complex\).

\[\left((c_1+c_2)V\right)[j]=(c_1+c_2)\cdot V[j] =c_1 V[j]+c_2 V[j] = (c_1V)[j]+(c_2V)[j]\]

Lo anterior se cumple por la distributividad del producto con respecto a la suma de los números complejos.

Práctica de Programación 2.1.1

Write three functions that perform the addition, inverse, and scalar multiplication operations for \(\Complex^n\), i.e., write a function that accepts the appropriate input for each of the operations and outputs the vector.

Utilicé el patrón newtype (fan de Haskell) para encapsular un vector de números complejos (que creamos en el capítulo anterior) y poder añadir traits.

La siguiente función sirve para sumar dos vectores entrada a entrada, únicamente tomando como especial el caso en que tenemos vectores de tamaños distintos.

fn add_vectors(ComplexVector(lhs): ComplexVector, ComplexVector(rhs): ComplexVector) -> ComplexVector {
    if lhs.len() != rhs.len() {
        panic!("Cannot add vectors of different size.");
    }

    let result_vector: Vec<Complex> = lhs.iter().zip(rhs.iter()).map(|(&x,&y)| x + y).collect();

    ComplexVector(result_vector)
}

El siguiente es el código para multiplicar un vector por un escalar:

fn product_vector_scalar(ComplexVector(vector): ComplexVector, scalar: Complex) -> ComplexVector {
    ComplexVector(vector.iter().map(|&x| x * scalar).collect())
}

Y la función para conseguir el inverso aditivo:

fn inverse_vector(ComplexVector(vector): ComplexVector) -> ComplexVector {
    ComplexVector(vector.iter().map(|&x| -x).collect())
}

A su vez, los traits Add, Mul y Neg llaman a estas funciones. El código completo para la implementación de vectores complejos está en mi repositorio JPYamamoto/quantum_computing_studies.

Definiciones, propiedades y ejemplos.

Un espacio vectorial complejo es un conjunto no vacío \(𝕍\), cuyos elementos llamaremos vectores, con 3 operaciones:

  • Suma: \(+: 𝕍\times 𝕍\to 𝕍\)
  • Negación: \(-: 𝕍\to 𝕍\)
  • Multiplicación por escalar: \(\cdot: \Complex\times 𝕍\to 𝕍\)

y un elemento distinguido llamado el vector cero \(0\in 𝕍\) in el conjunto. Estas operaciones y el cero deben satisfacer las siguientes propiedades: para todos \(V,W,X\in 𝕍\) y para cualesquiera \(c,c_1,c_2\in\Complex\),

  1. Conmutatividad de la suma: \(V+W=W+V\).
  2. Asociatividad de la suma: \((V+W)+X=V+(W+X)\).
  3. El cero es una identidad aditiva: \(V+0=V=0+V\).
  4. Todo vector tiene un inverso: \(V+(-V)=0=(-V)+V\).
  5. La multiplicación por escalar tiene unidad: \(1\cdot V=V\).
  6. La multiplicación por escalar respeta la multiplicación entre complejos: \[c_1\cdot\left(c_2\cdot V\right)=\left(c_1\times c_2\right)\cdot V.\]
  7. La multiplicación por escalar distribuye sobre la suma: \[c\cdot\left(V+W\right)=c\cdot V+c\cdot W.\]
  8. La multiplicación escalar distribuye sobre la suma de complejos: \[ \left(c_1+c_2\right)\cdot V=c_1\cdot V + c_2\cdot V.\]

Ejercicio 2.2.1

Let \(r_1=2,r_2=3\), and \(V=\begin{bmatrix}2\\-4\\1\end{bmatrix}\). Verify Property 6, i.e., calculate \(r_1\cdot (r_2\cdot V)\) and \((r_1\times r_2)\cdot V\) and show that they coincide.

\[ 2\cdot\left(3\cdot\begin{bmatrix}2\\-4\\1\end{bmatrix}\right) = 2\cdot\begin{bmatrix}6\\-12\\3\end{bmatrix} = \begin{bmatrix}12\\-24\\6\end{bmatrix} \]

\[ \left(2\cdot 3\right)\cdot\begin{bmatrix}2\\-4\\1\end{bmatrix} = 6\cdot\begin{bmatrix}2\\-4\\1\end{bmatrix} = \begin{bmatrix}12\\-24\\6\end{bmatrix} \]

Ejercicio 2.2.2

Draw pictures in \(\R^3\) that explain Properties 6 and 8 of the definition of a real vector space.

Figura 1: Solución al ejercicio 2.2.2. Primera parte.

Figura 1: Solución al ejercicio 2.2.2. Primera parte.

En la imagen anterior podemos ver que reescalar 2 veces un vector, sería equivalente a reescalar por el producto de los escalares.

En la siguiente imagen se ve a la izquierda el resultado de escalar un vector por el producto de los escalares, y a la derecha la suma de el producto de escalares.

Figura 2: Solución al ejercicio 2.2.2. Segunda parte.

Figura 2: Solución al ejercicio 2.2.2. Segunda parte.

Ejercicio 2.2.3

Let $c_1=2i, c_2=1+2i,$ and \(A=\begin{bmatrix}1-i&3\\2+2i&4+i\end{bmatrix}\). Verify Properties 6 y 8 in showing \(\Complex^{2\times 2}\) is a complex vector space.

\[ 2i\cdot\left((1+2i)\begin{bmatrix}1-i&3\\2+2i&4+i\end{bmatrix}\right) = 2i\cdot\begin{bmatrix}3+i&3+6i\\-2+6i&2+9i\end{bmatrix} = \begin{bmatrix}-2+6i&-12+6i\\-12-4i&-18+4i\end{bmatrix} \]

\[ \left(2i\cdot(1+2i)\right)\begin{bmatrix}1-i&3\\2+2i&4+i\end{bmatrix} = \left(-4+2i\right)\begin{bmatrix}1-i&3\\2+2i&4+i\end{bmatrix} = \begin{bmatrix}-2+6i&-12+6i\\-12-4i&-18+4i\end{bmatrix} \]

Ambos resultados son iguales, por lo tanto se cumple que la multiplicación por escalares respeta la multiplicación entre complejos. Ahora verificamos que la multiplicación escalar distribuye sobre la suma de complejos:

\[ \left(2i+1+2i\right)\begin{bmatrix}1-i&3\\2+2i&4+i\end{bmatrix} = \left(1+4i\right)\begin{bmatrix}1-i&3\\2+2i&4+i\end{bmatrix} = \begin{bmatrix}5+3i&3+12i\\-6+10i&17i\end{bmatrix} \]

\[ \left(2i\right)\begin{bmatrix}1-i&3\\2+2i&4+i\end{bmatrix}+\left(1+2i\right)\begin{bmatrix}1-i&3\\2+2i&4+i\end{bmatrix} = \begin{bmatrix}2+2i&6i\\-4+4i&-2+8i\end{bmatrix}+\begin{bmatrix}3+i&3+6i\\-2+6i&2+9i\end{bmatrix} = \begin{bmatrix}5+3i&3+12i\\-6+10i&17i\end{bmatrix} \]

Ejercicio 2.2.4

Show that these operations (addition and product) on \(\Complex^{m\times n}\) satisfy Properties 5, 6 and 8 of being a complex vector space.

Sea \(A\in\Complex^{m\times n}\):

Para la propiedad 5:

\[ \left(1\cdot A\right)[j,k]=1\cdot (A[j,k])=A[j,k] \]

Propiedad 6:

\[ \left(c_1\cdot\left(c_2\cdot A\right)\right)[j,k] = c_1\cdot\left(\left(c_2\cdot A\right)[j,k]\right) = c_1\cdot c_2\cdot\left(A[j,k]\right) = \left(c_1\cdot c_2\right)\cdot A[j,k] \]

Propiedad 8:

\[ \left(\left(c_1+c_2\right)A\right)[j,k] = \left(c_1+c_2\right)\cdot\left(A[j,k]\right) = c_1\cdot A[j,k]+c_2\cdot A[j,k] \]

Práctica de Programación 2.2.1

Convert your functions from the last programming drill so that instead of accepting elements of \(\Complex^n\) they accept elements of \(\Complex^{m\times n}\).

En vez de modificar lo construido anteriormente, creé un estructura aparte: ComplexMatrix.

pub struct ComplexMatrix{
    elements: Vec<Complex>,
    rows: usize,
    columns: usize,
}

Como podemos ver, la matriz es en realidad un vector de tamaño \(m\cdot n\). Para acceder a cada elemento de la matriz, utilizamos un algoritmo de redireccionamiento, que podemos ver en la implementación del trait Index:

impl Index<[usize; 2]> for ComplexMatrix {
    type Output = Complex;

    fn index(&self, index: [usize; 2]) -> &Self::Output {
        let [row, column] = &index;

        if row >= &self.rows || column >= &self.columns {
            panic!("Index out of range.")
        }

        &self.elements[(row * &self.columns) + column]
    }
}

Las funciones para suma, multiplicación por escalares e inverso aditivo, no las escribo en el post, puesto que su implementación es análoga a la utilizada sobre vectores (porque nuestra implementación por debajo es únicamente un vector).

El código completo se puede encontrar en mi repositorio JPYamamoto/quantum_computing_studies.

Ejercicio 2.2.5

Find the transpose, conjugate, and adjoint of \[\begin{bmatrix}6-3i&2+12i&-19i\\0&5+2.1i&17\\1&2+5i&3-4.5i\end{bmatrix}.\]

Obtenemos la transpuesta intercambiando los índices de las entradas:

\[\begin{bmatrix}6-3i&0&1\\2+12i&5+2.1i&2+5i\\-19i&17&3-4.5i\end{bmatrix}\]

Para la conjugada, únicamente conjugamos cada uno de los números en las entradas:

\[\begin{bmatrix}6+3i&2-12i&19i\\0&5-2.1i&17\\1&2-5i&3+4.5i\end{bmatrix}\]

La adjunta resulta de combinar ambas operaciones anteriores:

\[\begin{bmatrix}6+3i&0&1\\2-12i&5-2.1i&2-5i\\19i&17&3+4.5i\end{bmatrix}\]

Ejercicio 2.2.6

Prove that conjugation respects scalar multiplication, i.e., \(\overline{c\cdot A}=\overline{c}\cdot\overline{A}\).

Sean \(c\) un escalar y \(A\) una matriz.

\[ \overline{c\cdot A}[j,k] = \overline{\left(c\cdot A\right)[j,k]} = \overline{c\times A[j,k]} \]

Por el Ejercicio 1.2.11 sabemos que lo anterior implica \(\overline{c}\times \overline{A[j,k]}\).

Ejercicio 2.2.7

Propiedades de las operaciones de transposición, conjugación y adjunta (o daga). Para toda \(c\in\Complex\) y para todas matrices \(A,B\in\Complex^{m\times n}\):

  1. La transposición es idempotente: \(\left(A^T\right)^T=A\).
  2. La transposición respeta la suma: \(\left(A+B\right)^T=A^T+B^T\).
  3. La transposición respeta el producto por escalares: \(\left(c\cdot A\right)^T=c\cdot A^T\).
  4. La conjugación es idempotente: \(\overline{\overline{A}}=A\).
  5. La conjugación respeta la suma: \(\overline{A+B}=\overline{A}+\overline{B}\).
  6. La conjugación respeta el producto por escalares: \(\overline{c\cdot A}=\overline{c}\cdot\overline{A}\).
  7. La adjunta es idempotente: \(\left(A^{\dag}\right)^{\dag}=A\).
  8. La adjunta respeta la suma: \(\left(A+B\right)^{\dag}=A^{\dag}+B^{\dag}\).
  9. La adjunta está relacionada con el producto por escalar: \(\left(c\cdot A\right)^{\dag}=\overline{c}\cdot A^{\dag}\).

Prove Properties 7, 8, and 9 using Properties 1-6.

Para la propiedad 7. Tenemos por definición de la adjunta que \(\left(A^{\dag}\right)^{\dag}=\overline{\overline{A^T}}^{T}\). Por la propiedad 4 lo anterior es igual que \({A^{T}}^{T}\). Y eso es igual a \(A\) por la propiedad 1.

Para la propiedad 8. \(\left(A+B\right)^{\dag}=\overline{A+B}^T\). Por la propiedad 5 es igual \(\left(\overline{A}+\overline{B}\right)^T\), y por la propiedad 2 es lo mismo \(\overline{A}^T+\overline{B}^T\). Por definición, lo anterior es igual que \(A^{\dag}+B^{\dag}\).

Para la propiedad 9. \(\left(c\cdot A\right)^{\dag}=\overline{c\cdot A}^T\). Por la propiedad 6 tenemos que es lo mismo \(\left(\overline{c}\cdot\overline{A}\right)^T\), y por la propiedad 3 tenemos \(\overline{c}\cdot\overline{A}^T\). Por definición de adjunta, lo anterior es \(\overline{c}\cdot A^{\dag}\).

Ejercicio 2.2.8

\[ A=\begin{bmatrix}3+2i&0&5-6i\\1&4+2i&i\\4-i&0&4\end{bmatrix} \] \[ B=\begin{bmatrix}5&2-i&6-4i\\0&4+5i&2\\7-4i&2+7i&0\end{bmatrix} \]

Find \(B\star A\). Does it equal \(A\star B\)?

Omito los pasos intermedios, solo aclarando que el operador \(\star\) corresponde a la multiplicación de matrices usual.

\[ B\star A=\begin{bmatrix}37-13i&10&50-44i\\12+3i&6+28i&3+4i\\31+9i&-6+32i&4-60i\end{bmatrix} \]

El resultado es distinto de \(A\star B\).

Ejercicio 2.2.9

La multiplicación de matrices satisface las siguientes propiedades: Para cualesquiera \(A,B\) y \(C\) en \(\Complex^{n\times n}\),

  1. La multiplicación de matrices es asociativa: \((A\star B)\star C=A\star (B\star C)\).
  2. La multiplicación de matrices tiene a \(I_n\) como la unidad: \(I_n\star A=A=A\star I_n\).
  3. La multiplicación de matrices distribuye sobre la suma: \[ A\star (B+C)=(A\star B)+(A\star C),\] \[(B+C)\star A=(B\star A)+(C\star A).\]
  4. La multiplicación de matrices respeta el producto escalar: \[c\cdot (A\star B)=(c\cdot A)\star B=A\star(c\cdot B).\]
  5. La multiplicación de matrices se relaciona a la transpuesta: \[\left(A\star B\right)^T = B^T\star A^T.\]
  6. La multiplicación de matrices respeta la conjugación: \[\overline{A\star B}=\overline{A}\star\overline{B}.\]
  7. La multiplicación de matrices se relaciona con la adjunta: \[\left(A\star B\right)^{\dag}=B^{\dag}\star A^{\dag}.\]

Prove Property 5 in the above list.

Sean \(A\) y \(B\) matrices en \(\Complex^{n\times n}\).

\[\begin{aligned}&\left(A\star B\right)^T[j,k] = \left(A\star B\right)[k,j]=\sum_{h=0}^{n-1}\left(A[k,h]\times B[h,j]\right)\&= \sum_{h=0}^{n-1}\left(B[h,j]\times A[k,h]\right) = \sum_{h=0}^{n-1}\left(B^T[j,h]\times A^T[h,k]\right) = \left(B^T\star A^T\right)[j,k]\end{aligned}\]

Ejercicio 2.2.10

\[ A=\begin{bmatrix}3+2i&0&5-6i\\1&4+2i&i\\4-i&0&4\end{bmatrix} \] \[ B=\begin{bmatrix}5&2-i&6-4i\\0&4+5i&2\\7-4i&2+7i&0\end{bmatrix} \]

Use \(A\) and \(B\) and show that \((A\star B)^{\dag}=B^{\dag}\star A^{\dag}\).

El libro nos dice que

\[ A\star B=\begin{bmatrix}26-52i&60+24i&26\\9+7i&1+29i&14\\48-21i&15+22i&20-22i\end{bmatrix} \]

por lo tanto

\[ \left(A\star B\right)^{\dag}=\begin{bmatrix}26+52i&9-7i&48+21i\\60-24i&1-29i&15-22i\\26&14&20+22i\end{bmatrix} .\]

por otro lado tenemos

\[ A^{\dag}=\begin{bmatrix}3-2i&1&4+i\\0&4-2i&0\\5+6i&-i&4\end{bmatrix} \] \[ B^{\dag}=\begin{bmatrix}5&0&7+4i\\2+i&4-5i&2-7i\\6+4i&2&0\end{bmatrix} \]

cuyo resultado es igual

\[ \left(A\star B\right)^{\dag}=\begin{bmatrix}26+52i&9-7i&48+21i\\60-24i&1-29i&15-22i\\26&14&20+22i\end{bmatrix} .\]

Ejercicio 2.2.11

Prove Property 7 from Properties 5 and 6.

\[ \left(A\star B\right)^{\dag}=\overline{A\star B}^T=\left(\overline{A}\star\overline{B}\right)^T=\overline{B}^T\star\overline{A}^T=B^{\dag}\star A^{\dag} \]

Práctica de Programación 2.2.2

Write a function that accepts two complex matrices of the appropriate size. The function should do matrix multiplication and return the result.

Esencialmente ya está resuelto este ejercicio, pues desde la práctica pasada agregué el trait Mul que a su vez invoca la siguiente función:

fn product_matrices(m1: ComplexMatrix, m2: ComplexMatrix) -> ComplexMatrix {
    if m1.columns != m2.rows {
        panic!("Number of columns in the left-hand side matrix should be the \
                same as number of rows in the right-hand side matrix.");
    }

    let mut m3 = ComplexMatrix::new(
        vec![Complex::new(0.0, 0.0); m1.rows * m2.columns], m1.rows, m2.columns);

    for j in 0..m3.rows {
        for k in 0..m3.columns {
            let mut sum = Complex::new(0.0, 0.0);

            for h in 0..m1.columns {
                sum += m1[[j,h]] * m2[[h,k]]
            }

            m3[[j,k]] = sum;
        }
    }

    m3
}

Únicamente implementé de manera prácticamente directa la definición de multiplicación de matrices. Estoy consciente de que esta implementación no es óptima (con complejidad cúbica), pero no es el objetivo de esta práctica trabajar con algoritmos eficientes de matrices.

El código completo se puede encontrar en mi repositorio JPYamamoto/quantum_computing_studies.

Práctica de Programación 2.2.3

Write a function that accepts a vector and a matrix and outputs the vector resulting from the “action”.

Puesto que un vector se puede considerar como una matriz de \(\Complex^{m \times 1}\), basta con proveer una forma de convertir vectores a matrices, y reutilizamos la implementación de producto anterior:

impl From<ComplexVector> for ComplexMatrix {
    fn from(ComplexVector(rhs): ComplexVector) -> Self {
        let rows = rhs.len();
        ComplexMatrix { elements: rhs, rows, columns: 1 }
    }
}

La implementación difiere en que el resultado no es un vector, sino una matriz de una sola columna. Esto se puede remediar convirtiendo el resultado a vector:

pub fn product_matrix_vector(matrix: ComplexMatrix, vector: ComplexVector) -> ComplexVector {
    let vec_to_mat = ComplexMatrix::from(vector);
    let ComplexMatrix { elements, .. } = matrix * vec_to_mat;
    ComplexVector(elements)
}

El código completo se puede encontrar en mi repositorio JPYamamoto/quantum_computing_studies.

Ejercicio 2.2.12

Show that Poly \({}_n\) with these operations satisfies the properties of being a complex vector space.

  1. Conmutatividad de la suma: Se cumple por la conmutatividad del campo sobre el que se define el campo vectorial.
  2. Asociatividad de la suma: Se cumple igualmente por las propiedades del campo y la definición de la suma de polinomios.
  3. Identidad adivitiva: \(P(x)+0(x)=\sum_{0\leq i\leq n}(p_i + 0)x^i = \sum_{0\leq i\leq n}p_ix^i = P(x)\).
  4. Inverso aditivo: \(P(x)-P(x)=\sum_{0\leq i\leq n}(p_i - p_i)x^i = \sum_{0\leq i\leq n}0x^i = 0(x)\).
  5. Multiplicación por identidad: \(1\cdot P(x)=\sum_{0\leq i\leq n}1\cdot p_ix^i=\sum_{0\leq i\leq n}p_ix^i = P(x)\).
  6. Multiplicación por escalar respeta el producto de complejos: Por la asociatividad del producto de complejos, y la definición del producto por escalares de polinomios, se cumple.
  7. Distributividad del producto sobre la suma: \(c\left(P(x)+Q(x)\right)=c\left(\sum_{0\leq i\leq n}(p_i+q_i)x^i\right)=c\left(\sum_{0\leq i\leq n}p_i x^i +q_i x^i\right)=c\left(\sum_{0\leq i\leq n}p_i x^i +q_i x^i\right)=c\left(\sum_{0\leq i\leq n}p_i x^i +\sum_{0\leq i\leq n}q_i x^i\right)=c\sum_{0\leq i\leq n}p_i x^i +c\sum_{0\leq i\leq n}q_i x^i=cP(x) +cQ(x)\).
  8. Producto escalar distribuye sobre suma de complejos: Se cumple por las propiedades del campo y la definición de las operaciones sobre polinomios.

Ejercicio 2.2.13

Show that Poly \({}_5\) is a complex subspace of Poly \({}_7\).

Se cumple la cerradura bajo la suma, pues la suma entre dos polinomios de grado a lo más 5 siempre genera un polinomio de grado a lo más 5.

Se cumple la cerradura bajo el producto escalar, pues el producto entre números complejos es cerrado.

Se cumple que \(0(x)\) es un polinomio de grado a lo más 5.

Ejercicio 2.2.14

Show that all real matrices of the form \[\begin{bmatrix}x&y\\-y&x\end{bmatrix}\] comprise a real subspace of \(\R^{2\times 2}\). Then show that this subspace is isomorphic to \(\Complex\) via the map \(f:\Complex \to \R^{2\times 2}\) that is defined as \[f(x+iy)=\begin{bmatrix}x&y\\-y&x\end{bmatrix}.\]

Cerradura bajo la suma: \[ \begin{bmatrix}x&y\\-y&x\end{bmatrix} + \begin{bmatrix}a&b\\-b&a\end{bmatrix} = \begin{bmatrix}x+a&y+b\\-(y+b)&x+a\end{bmatrix} \]

Cerradura bajo la multiplicación escalar: \[ c\begin{bmatrix}x&y\\-y&x\end{bmatrix} = \begin{bmatrix}cx&cy\\-cy)&cx\end{bmatrix} \]

La matriz 0 es parte del subespacio, pues cumple con la estructura mencionada. De lo anterior, concluimos que las matrices dadas son un subespacio real como indica el ejercicio.

La función \(f\) es inyectiva, pues solo hay una forma de construir la matriz dado un complejo. Cualquier par de matrices iguales vienen del mismo número. Además, es sobreyectiva pues para cada matriz de \(2\times 2\) con entradas reales en el espacio dado, podemos construir el número complejo que le corresponde. Entonces, \(\Complex\) es isomorfo a \(\R^{2\times 2}\).

Ejercicio 2.2.15

Show that Func \((\N,\Complex)\) with these operations forms a complex vector space.

  1. Conmutatividad de la suma: Se cumple por la conmutatividad de los números complejos.
  2. Asociatividad de la suma: Se cumple por la asociatividad de los números complejos.
  3. Identidad adivitiva: Se cumple con \(f(x)=0\) por la identidad aditiva de los complejos.
  4. Inverso aditivo: Se cumple por el inverso aditivo de complejos.
  5. Multiplicación por identidad: Se cumple por la identidad del producto en complejos.
  6. Multiplicación por escalar respeta el producto de complejos: Se cumple por las propiedades de complejos.
  7. Distributividad del producto sobre la suma: Se cumple por propiedades de los complejos.
  8. Producto escalar distribuye sobre suma de complejos: Se cumple por propiedades de los complejos.

Ejercicio 2.2.16

Show that Func \((\N, \R)\) and Func \(([a,b],\R)\) are real vector spaces.

Los argumentos son iguales a los del ejercicio anterior.

Base y Dimensión

Ejercicio 2.3.1

Show that the set of vectors \[\left\{\begin{bmatrix}1\\2\\3\end{bmatrix},\begin{bmatrix}3\\0\\2\end{bmatrix},\begin{bmatrix}1\\-4\\-4\end{bmatrix}\right\}\] is not linearly independent.

\[-2\begin{bmatrix}1\\2\\3\end{bmatrix}+\begin{bmatrix}3\\0\\2\end{bmatrix}=\begin{bmatrix}1\\-4\\-4\end{bmatrix}\]

Ejercicio 2.3.2

Verify that the three vectors \[\left\{\begin{bmatrix}1\\1\\1\end{bmatrix},\begin{bmatrix}0\\1\\1\end{bmatrix},\begin{bmatrix}0\\0\\1\end{bmatrix}\right\}\] are in fact a basis of \(\R^3\).

Basta con verificar que los vectores son linealmente independientes. La matriz \[\begin{bmatrix}1&0&0\\1&1&0\\1&1&1\end{bmatrix}\] se reduce por el método de eliminación Gaussiana a \[\begin{bmatrix}1&0&0\\0&1&0\\0&0&1\end{bmatrix}\] que tiene determinante 1. Por lo tanto, los vectores son linealmente independientes.

Ejercicio 2.3.3

Matriz de Hadamard: \[H=\dfrac{1}{\sqrt{2}}\begin{bmatrix}1&1\\1&1\end{bmatrix}\]

Show that \(H\) times itself gives you the identity matrix.

\[\dfrac{1}{\sqrt{2}}\begin{bmatrix}1&1\\1&1\end{bmatrix}\times \dfrac{1}{\sqrt{2}}\begin{bmatrix}1&1\\1&1\end{bmatrix} = \begin{bmatrix}\left(\frac{1}{\sqrt{2}}\right)^2+\left(\frac{1}{\sqrt{2}}\right)^2&\left(\frac{1}{\sqrt{2}}\right)^2+\left(\frac{1}{\sqrt{2}}\right)^2\\\left(\frac{1}{\sqrt{2}}\right)^2+\left(\frac{1}{\sqrt{2}}\right)^2&\left(\frac{1}{\sqrt{2}}\right)^2+\left(\frac{1}{\sqrt{2}}\right)^2\end{bmatrix} = \begin{bmatrix}1&1\\1&1\end{bmatrix}\]

Producto Interno y Espacios de Hilbert

Ejercicio 2.4.1

Let $V_1=\left[2,1,3\right]^T, V_2=\left[6,2,4\right]^T,$ and \(V_3=\left[0,-1,2\right]^T\). Show that the inner product in \(\mathbb{R}^3\) respects the addition.

Respeta la suma en la entrada izquierda: \[ \langle\begin{bmatrix}2\\1\\3\end{bmatrix}+\begin{bmatrix}6\\2\\4\end{bmatrix}, \begin{bmatrix}0\\ -1\\2\end{bmatrix}\rangle = \langle\begin{bmatrix}8\\3\\7\end{bmatrix}, \begin{bmatrix}0\\ -1\\2\end{bmatrix}\rangle = \begin{bmatrix}8\\3\\7\end{bmatrix}^T \star \begin{bmatrix}0\\ -1\\2\end{bmatrix}= 8\cdot 0 + 3\cdot (-1) + 7\cdot 2 = 11 \]

\[ \langle\begin{bmatrix}2\\1\\3\end{bmatrix}, \begin{bmatrix}0\\ -1\\2\end{bmatrix}\rangle + \langle\begin{bmatrix}6\\2\\4\end{bmatrix}, \begin{bmatrix}0\\ -1\\2\end{bmatrix}\rangle = \begin{bmatrix}2\\1\\3\end{bmatrix}^T \star \begin{bmatrix}0\\ -1\\2\end{bmatrix} + \begin{bmatrix}6\\2\\4\end{bmatrix}^T \star \begin{bmatrix}0\\ -1\\2\end{bmatrix} = (2\cdot 0 + 1\cdot (-1) + 3\cdot 2) + (6\cdot 0 + 2\cdot (-1) + 4\cdot 2) = (0-1+6)+(-2+8)=5+6=11 \]

Respeta la suma en la entrada derecha: \[ \langle\begin{bmatrix}2\\1\\3\end{bmatrix}, \begin{bmatrix}6\\2\\4\end{bmatrix} + \begin{bmatrix}0\\ -1\\2\end{bmatrix}\rangle = \langle\begin{bmatrix}2\\1\\3\end{bmatrix}, \begin{bmatrix}6\\1\\6\end{bmatrix}\rangle = \begin{bmatrix}2\\1\\3\end{bmatrix}^T \star \begin{bmatrix}6\\1\\6\end{bmatrix}= 2\cdot 6 + 1\cdot 1 + 3\cdot 6=31 \]

\[ \langle\begin{bmatrix}2\\1\\3\end{bmatrix}, \begin{bmatrix}6\\2\\4\end{bmatrix} + \langle\begin{bmatrix}2\\1\\3\end{bmatrix}, \begin{bmatrix}0\\ -1\\2\end{bmatrix}\rangle = \begin{bmatrix}2\\1\\3\end{bmatrix}^T \star \begin{bmatrix}6\\2\\4\end{bmatrix} + \begin{bmatrix}2\\1\\3\end{bmatrix}^T \star \begin{bmatrix}0\\ -1\\2\end{bmatrix}= (2\cdot 6 + 1\cdot 2 + 3\cdot 4) + (2\cdot 0 + 1\cdot (-1) + 3\cdot 2) = 26 + 5 = 31 \]

Ejercicio 2.4.2

Show that the functions \(\langle\;,\;\rangle:\mathbb{R}^n\times\mathbb{R}^n\) given satisfies all the properties of being an inner product on \(\mathbb{R}^n\).

Primero, notemos que dada la definición \(\langle V_1,V_2\rangle =V_1^{T}\star V_2\), en realidad estamos sacando el producto entrada a entrada de los dos vectores.

  • \(\langle V,V\rangle\geq 0\): Se cumple debido a que las entradas del resultado son de la forma \(v_i^2\) que en los números reales siempre es mayor o igual a 0.
  • \(\langle V,V\rangle=0\) si y sólo si \(V=0\): Dado que las entradas son de la forma \(v_i^2\), y por propiedades de los reales, sabemos que \(v_i^2=0\) si y sólo si \(v_i=0\).
  • \(\langle V_1+V_2,V_3\rangle+\langle V_1,V_3\rangle+\langle V_2,V_3\rangle\): Es verdadero puesto que \((v_{1_i} + v_{2_i})\cdot v_{3_i} = v_{1_i} v_{3_i} + v_{2_i} v_{3_i}\) por propiedades de los reales.
  • \(\langle V_1,V_2+V_3\rangle+\langle V_1,V_2\rangle+\langle V_1,V_3\rangle\): Análogo al caso anterior.
  • \(\langle c\cdot V_1,V_2\rangle=c\times \langle V_1,V_2\rangle\): Se cumple por \((c\times v_{1_i})(v_{2_i})=c\times(v_{1_i}v_{2_i})\).
  • \(\langle V_1,c\cdot V_2\rangle=\overline{c}\times \langle V_1,V_2\rangle\): Es análogo al caso anterior, tomando en cuenta que en \(\mathbb{R}\), \(c=\overline{c}\).
  • \(\langle V_1,V_2\rangle=\overline{\langle V_2,V_1\rangle}\): Como en \(\mathbb{R}\), \(c=\overline{c}\) y el producto es conmutativo, se cumple la propiedad.

Ejercicio 2.4.3

Let $A=\begin{bmatrix}1&2\\0&1\end{bmatrix}, B=\begin{bmatrix}0& -1\\ -1 &0\end{bmatrix},$ and \(C=\begin{bmatrix}2&1\\1&3\end{bmatrix}\). Show that the inner product in \(\mathbb{R}^{2\times 2}\) respects addition with these matrices.

\(\langle A,B\rangle = \textit{Trace}(A^T\star B)\)

Por un lado,

\[ \langle\begin{bmatrix}1&2\\0&1\end{bmatrix}+\begin{bmatrix}0& -1\\ -1 &0\end{bmatrix}, \begin{bmatrix}2&1\\1&3\end{bmatrix}\rangle=\textit{Trace}\left(\begin{bmatrix}1&1\\ -1&1\end{bmatrix}^T \star \begin{bmatrix}2&1\\1&3\end{bmatrix}\right)=\textit{Trace}\left(\begin{bmatrix}1& -1\\1&1\end{bmatrix} \star \begin{bmatrix}2&1\\1&3\end{bmatrix}\right)=\textit{Trace}\left(\begin{bmatrix}1& -2\\3&4\end{bmatrix}\right)=1+4=5 \]

Por otro lado, \[ \langle\begin{bmatrix}1&2\\0&1\end{bmatrix}, \begin{bmatrix}2&1\\1&3\end{bmatrix}\rangle + \langle\begin{bmatrix}0& -1\\ -1 &0\end{bmatrix}, \begin{bmatrix}2&1\\1&3\end{bmatrix}\rangle=\textit{Trace}\left(\begin{bmatrix}1&2\\0&1\end{bmatrix}^T \star \begin{bmatrix}2&1\\1&3\end{bmatrix}\right)+\textit{Trace}\left(\begin{bmatrix}0& -1\\ -1&0\end{bmatrix}^T \star \begin{bmatrix}2&1\\1&3\end{bmatrix}\right)=\textit{Trace}\left(\begin{bmatrix}1&0\\2&1\end{bmatrix} \star \begin{bmatrix}2&1\\1&3\end{bmatrix}\right)+\textit{Trace}\left(\begin{bmatrix}0& -1\\ -1&0\end{bmatrix} \star \begin{bmatrix}2&1\\1&3\end{bmatrix}\right)=\textit{Trace}\left(\begin{bmatrix}2&1\\5&5\end{bmatrix}\right)+\textit{Trace}\left(\begin{bmatrix}-1& -3\\ -2& -1\end{bmatrix}\right) = (2+5)+(-1-1)=7-2=5 \]

El caso para \(\langle V_1,V_2+V_3\rangle=\langle V_1,V_2\rangle + \langle V_1,V_3\rangle\) es análogo.

Ejercicio 2.4.4

Show that the function given for pairs of real matrices satisfies the inner product properties and converts the real vector space \(\mathbb{R}^{n\times n}\) to a real inner product space.

Notemos que por la definición dada de producto interno, la matriz de la cuál obtenemos su traza es \((A^T\star B)[j,k]=\sum_{h=0}^{n-1}(A[h,j]\times B[h,k])\).

  • \(\langle A,A\rangle \geq 0\): Como para la traza nos importan las entradas en la diagonal, tenemos \((A^T\star A)[j,j]=\sum_{h=0}^{n-1}(A[h,j]\times A[h,j])=\sum_{h=0}^{n-1}A[h,j]^2\). La suma de reales no negativos es no negativa.
  • \(\langle A,A\rangle = 0\) si y sólo si \(A=0\): Se cumple debido a que en números no negativos, solo la suma de ceros resulta en 0.
  • \(\langle A_1+A_2,A_3\rangle = \langle A_1,A_3\rangle + \langle A_2,A_3\rangle\): \(((A_1+A_2)^T \star A_3)[j,j]=\sum_{h=0}^{n-1}((A_1+A_2)[h,j]\times A_3[h,k])=\sum_{h=0}^{n-1}(A_1\times A_3[h,k]+A_2\times A_3[h,k])=\sum_{h=0}^{n-1}(A_1[h,j]\times A_3[h,k])+\sum_{h=0}^{n-1}(A_2[h,j]\times A_3[h,k])\).
  • \(\langle A_1,A_2+A_3\rangle = \langle A_1,A_2\rangle+\langle A_1,A_3\rangle\): Análogo al caso anterior, por distributividad.
  • \(\langle c\cdot A_1,A_2\rangle=c\times\langle A_1,A_2\rangle\): Se cumple por distributividad del producto sobre la suma.
  • \(\langle A_1, c\cdot A_2\rangle=\overline{c}\times\langle A_1,A_2\rangle\): Se cumple igualmente por distributividad, y porque en los reales \(c=\overline{c}\).
  • \(\langle A_1, c\cdot A_2\rangle=\overline{\langle A_2,A_1\rangle}\): Se cumple porque el producto y la suma son conmutativos en los reales, y porque \(c=\overline{c}\).

Práctica de Programación 2.4.1

Write a function that accepts two complex vectors of length \(n\) and calculates their inner product.

Implementé el trait Mul entre instancias de ComplexVector<N>. Es importante destacar que desde la práctica anterior hice modificaciones importantes a la estructura del proyecto.

Ahora, en vez de verificar manualmente que los dos operandos en las operaciones binarias sean de las dimensiones correctas, estoy utilizando const generics. Estos nos permiten dar argumentos numéricos genéricos, de tal manera que en tiempo de compilación estamos acotando las operaciones a vectores o matrices de dimensiones válidas. Para ver los cambios que esto implicó, se puede revisar el commit correspondiente en GitHub.

La parte importante del algoritmo para el producto interno es la siguiente:

fn inner_product_vector<const N: usize>(ComplexVector(v1): ComplexVector<N>, ComplexVector(v2): ComplexVector<N>) -> Complex {
    v1.iter()
      .zip(v2.iter())
      .map(|(&x1, &x2)| x1.conjugate() * x2)
      .sum()
}

Como podemos ver, basta hacer el producto de la adjunta de la primera matriz con la segunda. No obstante, en nuestro caso ese producto se puede ver como el producto entrada a entrada donde utilizamos el conjugado de las entradas del primer vector, por lo que omitimos las operaciones intermedias que corresponderían a obtener la transpuesta y a convertir entre matrices y vectores.

El código completo se puede encontrar en mi repositorio JPYamamoto/quantum_computing_studies.

Ejercicio 2.4.5

Calculate the norm of \([4+3i,6-4i,12-7i,13i]^T\).

Para cada espacio complejo con producto interno \(\mathbb{V},\langle-,-\rangle\), podemos definir una norma o longitud que es una función \[ |\;\;|:\mathbb{V}\to\mathbb{R} \] definida como \[ |V|=\sqrt{\langle V,V\rangle} \]

\[ \left|\begin{bmatrix}4+3i\\6-4i\\12-7i\\13i\end{bmatrix}\right| = \sqrt{\Big\langle \begin{bmatrix}4+3i\\6-4i\\12-7i\\13i\end{bmatrix}, \begin{bmatrix}4+3i\\6-4i\\12-7i\\13i\end{bmatrix}\Big\rangle} = \sqrt{\begin{bmatrix}4-3i & 6+4i & 12+7i & -13i\end{bmatrix} \star \begin{bmatrix}4+3i\\6-4i\\12-7i\\13i\end{bmatrix}} = \sqrt{(4-3i)\cdot (4+3i) + (6+4i)\cdot (6-4i) + (12+7i)\cdot (12-7i) + (-13i)(13i)}=\sqrt{25+52+193+169}=\sqrt{439}\approx 20.952 \]

Ejercicio 2.4.6

Let \(A=\begin{bmatrix}3&5\\2&3\end{bmatrix}\in\mathbb{R}^{2\times 2}\). Calculate the norm \(|A|=\sqrt{\langle A,A\rangle}\).

\[ \sqrt{\textit{Trace}\left(\begin{bmatrix}3&5\\2&3\end{bmatrix}^T \star \begin{bmatrix}3&5\\2&3\end{bmatrix}\right)}=\sqrt{\textit{Trace}\left(\begin{bmatrix}3&2\\5&3\end{bmatrix} \star \begin{bmatrix}3&5\\2&3\end{bmatrix}\right)}=\sqrt{\textit{Trace}\left(\begin{bmatrix}13&21\\21&34\end{bmatrix}\right)}=\sqrt{13+34}=\sqrt{47}\approx 6.855 \]

Práctica de Programación 2.4.2

Write a function that calculates the norm of a given complex vectors.

Para esto bastó utilizar el producto interno que ya habíamos desarrollado en la práctica pasada.

pub fn norm(self) -> f64 {
    (self * self).real.sqrt()
}

El código completo se encuentra en mi repositorio JPYamamoto/quantum_computing_studies.

Ejercicio 2.4.7

Let \(V_1=\begin{bmatrix}3\\1\\2\end{bmatrix}\) and \(V_2=\begin{bmatrix}2\\2\\ -1\end{bmatrix}\). Calculate the distance between these two vectors.

\[ d(\;,\;):\mathbb{V}\times\mathbb{V}\to\mathbb{R} \\ d(V_1,V_2)=|V_1-V_2|=\sqrt{\langle V_1-V_2, V_1-V_2\rangle} \]

Primero tenemos \[ V_1-V_2=\begin{bmatrix}1\\ -1\\3\end{bmatrix} \] Luego,

\[ \sqrt{\Big\langle\begin{bmatrix}1\\ -1\\3\end{bmatrix},\begin{bmatrix}1\\ -1\\3\end{bmatrix}\Big\rangle}=\sqrt{1^2+(-1)^2+3^2}=\sqrt{11} \]

Práctica de Programación 2.4.3

Write a function that calculates the distance of two given complex vectors.

Utilizamos la implementación de la norma de la práctica anterior. Si bien, no habíamos implementado el trait Sub para restar, sí teníamos Neg y Add, por lo que la implementación resulta trivial:

impl<const N: usize> Sub for ComplexVector<N> {
    fn sub(self, other: Self) -> Self {
        self + -other
    }
}

Y la implementación de distance_to queda como:

pub fn distance_to(self, rhs: ComplexVector<N>) -> f64 {
    let diff = self - rhs;
    diff.norm()
}

El código completo se encuentra en mi repositorio JPYamamoto/quantum_computing_studies.

Ejercicio 2.4.8

Let \(V=[3,-1,0]^T\) and \(V’=[2,-2,1]^T\). Calculate the angle \(\theta\) between these two vectors.

\[ \langle V,V’\rangle = |V||V’|\cos\theta \]

Primero obtenemos el producto interno entre ambos vectores:

\[ \langle V,V’\rangle=\begin{bmatrix}3 & -1 & 0\end{bmatrix}\star \begin{bmatrix}2\\ -2\\1\end{bmatrix}=3\cdot 2 + (-1)\cdot (-2)+0\cdot 1=6+2=8 \]

Luego la norma de cada uno:

\[ |V|=\sqrt{\langle V,V\rangle} = \sqrt{\begin{bmatrix}3 & -1 & 0\end{bmatrix}\star \begin{bmatrix}3 \\ -1 \\ 0\end{bmatrix}}=\sqrt{3\cdot 3 + (-1)\cdot (-1) + 0\cdot 0}=\sqrt{9+1}=\sqrt{10} \] \[ |V’|=\sqrt{\langle V’,V’\rangle} = \sqrt{\begin{bmatrix}2 & -2 & 1\end{bmatrix}\star \begin{bmatrix}2 \\ -2 \\ 1\end{bmatrix}}=\sqrt{2\cdot 2 + (-2)\cdot (-2) + 1\cdot 1}=\sqrt{4+4+1}=\sqrt{9}=3 \]

Finalmente, despejamos el valor deseado:

\[ 8=3\sqrt{10}\cos\theta \Rightarrow \dfrac{8}{3\sqrt{10}}=\cos\theta \Rightarrow \arccos\dfrac{8}{3\sqrt{10}}=\theta\approx 32.51^{\circ} \]

Eigenvalores y Eigenvectores

Ejercicio 2.5.1

The following vectors \[ \left\{ \begin{bmatrix}1\\1\\0\end{bmatrix},\begin{bmatrix}1\\0\\ -1\end{bmatrix},\begin{bmatrix}1\\1\\2\end{bmatrix}\right\} \] are eigenvectors of the matrix \[ \begin{bmatrix} 1&-3&3\\3&-5&3\\6& -6&4\end{bmatrix}\] Find the eigenvalues.

\[ \begin{bmatrix} 1&-3&3\\3&-5&3\\6& -6&4\end{bmatrix}\begin{bmatrix}1\\1\\0\end{bmatrix} = \begin{bmatrix}-2\\ -2\\0\end{bmatrix} = -2\begin{bmatrix}1\\ 1\\0\end{bmatrix} \]

\[ \begin{bmatrix} 1&-3&3\\3&-5&3\\6& -6&4\end{bmatrix}\begin{bmatrix}1\\0\\ -1\end{bmatrix} = \begin{bmatrix}-2\\ 0\\2\end{bmatrix} = -2\begin{bmatrix}1\\ 0\\ -1\end{bmatrix} \]

\[ \begin{bmatrix} 1&-3&3\\3&-5&3\\6& -6&4\end{bmatrix}\begin{bmatrix}1\\1\\2\end{bmatrix} = \begin{bmatrix}4\\4\\8\end{bmatrix} = 4\begin{bmatrix}1\\1\\2\end{bmatrix} \]

Matrices Hermitianas y Unitarias

Ejercicio 2.6.1

Show that the matrix \[ \begin{bmatrix} 7 & 6+5i\\ 6-5i & -3 \end{bmatrix} \] is hermitian.

Una matriz \(A\) de tamaño \(n\) por \(n\) se llama hermitiana si \(A^{\dag}=A\). Es decir, \(A[j,k] = \overline{A[k,j]}\).

\[ \begin{bmatrix} 7 & 6+5i\\ 6-5i & -3 \end{bmatrix}^{\dag} = \begin{bmatrix} 7 & 6-5i\\ 6+5i & -3 \end{bmatrix}^{T} = \begin{bmatrix} 7 & 6+5i\\ 6-5i & -3 \end{bmatrix} \]

Ejercicio 2.6.2

Show that \(A\) is hermitian if and only if \(A^T = \overline{A}\).

Sabemos que, por definición, \(A\) es hermitiana si y sólo si \(A=A^{\dag}\). Obtener la transpuesta de dos matrices iguales debe mantener la igualdad, por lo que lo anterior se da si y sólo si \(A^T = (A^{\dag})^T\). Recordando que \(A^{\dag}=\overline{A}^T\) y que \((A^T)^T=A\) tenemos que \(A^T=\overline{A}\).

Ejercicio 2.6.3

Si \(A\) es una matriz hermitiana de tamaño \(n\) por \(n\), entonces para todos \(V, V’\in\mathbb{C}\) tenemos que \(\langle AV,V’\rangle=\langle V,AV’\rangle\).

Prove the same proposition for symmetric real matrices.

Sean \(M,M’\in\mathbb{R}^{n\times n}\) y \(A\) una matriz simétrica real. Luego, \[ \langle AM,M’\rangle = \textit{Trace}\left((AM)^{T}\star M’\right)=\textit{Trace}\left(M^TA^TM’\right)=\textit{Trace}\left(M^T A^T M’\right) = \textit{Trace}\left(M^T\star AM’\right)=\langle V,AV’\rangle\]

La segunda igualdad se da por propiedades de la transpuesta, y la penúltima igualdad se da por ser simétrica. Los demás es por definiciones.

Ejercicio 2.6.4

Prove that the eigenvalues of a symmetric matrix are real.

Sea \(A\) una matriz real simétrica y \(c\) el eigenvalor del vector \(V\).

\[ c\langle V,V\rangle = \langle cV,V\rangle = \langle AV,V\rangle =^{a} \langle V,AV\rangle = \langle V, cV\rangle = \overline{c}\langle V,V\rangle \]

La igualdad \(=^a\) se da por lo mostrado en el ejercicio anterior. Todo lo demás es por definiciones y propiedades del producto interno.

Práctica de Programación 2.6.1

Write a function that accepts a square matrix and tells if it is a hermitian.

Primero debí implementar las funciones para obtener la transpuesta y la conjugada de una matriz.

pub fn conjugate(&self) -> ComplexMatrix<R, C> {
    let new_elements = self.0.map(|arr| arr.map(|x| x.conjugate()));

    ComplexMatrix(new_elements)
}

pub fn transpose(&self) -> ComplexMatrix<C, R> {
    let mut m = ComplexMatrix::new([[Complex::new(0.0, 0.0); R]; C]);

    for j in 0..R {
        for i in 0..C {
            m[[[[j, i]]]] = self[[[[i, j]]]];
        }
    }

    m
}

pub fn conjugate_transpose(&self) -> ComplexMatrix<C, R> {
    self.conjugate().transpose()
}

Con lo anterior implementado, verificar si la matriz es hermitiana fue cuestión de verificar una igualdad:

impl <const N: usize> ComplexMatrix<N, N> {
    pub fn is_hermitian(&self) -> bool {
        *self == self.conjugate_transpose()
    }
}

Aprovechamos la inferencia de tipos con constantes genéricas de Rust para implementar el método solo en matrices cuadradas.

El código completo se puede encontrar en mi repositorio JPYamamoto/quantum_computing_studies.