我正在尝试使用 Rust 对多个矩阵执行顺序克罗内克积,即我想做
在Python中,我知道我能做到
import numpy as np
from functools import reduce
X = np.array([[0, 1], [1, 0])
matrices = [X for _ in range(8)]
product = reduce(np.kron, matrices)
并得到想要的结果。如何在 Rust 中做同样的事情?
我的 Rust 代码现在如下所示:
use ndarray::{array, ArrayBase, OwnedRepr, Dim};
use ndarray::linalg::kron;
use num::complex::Complex64 as Complex;
fn X() -> ArrayBase<OwnedRepr<Complex>, Dim<[usize; 2]>> {
array![
[Complex::new(0.0, 0.0), Complex::new(1.0, 0.0)],
[Complex::new(1.0, 0.0), Complex::new(0.0, 0.0)]
]
}
fn main() {
let mut matrices = Vec::new();
for _ in 0..8 {
matrices.push(X());
}
let product = matrices
.iter()
.reduce(|g1, g2| kron(g1, g2));
}
这是我得到的误差矩阵:
以下是我不明白的地方:
我怎样才能实现这个目标?
与 Python 不同,在 Rust 中你需要考虑所有权。
ndarray
包括多个版本的数组:Array
,ArrayView
,ArrayViewMut
,ArcArray
和CowArray
。它们类似于在 Rust 中查看数据的多种方式:拥有(T
或 Box<T>
) - 这是 Array
,它是 ArrayBase<OwnedRepr>
的别名,共享引用 (&T
) - ArrayView
、可变引用 (&mut T
) - ArrayViewMut
、共享所有权(Rc<T>
和 Arc<T>
)- ArcArray
以及写入时复制 (Cow<T>
) - CowArray
。
iter()
为您提供一个对元素引用的迭代器,即 &Array
,而 kron()
返回拥有的数组 - Array
。但是 reduce()
要求输入和输出都是同一类型,因为输出成为下一项的输入。所以你需要统一它们。
有多种方法可以做到这一点。例如,使用
into_iter()
代替 iter()
:
let product = matrices.into_iter().reduce(|g1, g2| kron(&g1, &g2));
fold()
:
fn kron_many(matrices: &[Array2<Complex>]) -> Option<Array2<Complex>> {
let (first, rest) = matrices.split_first()?;
let first = first.clone();
Some(rest.iter().fold(first, |g1, g2| kron(&g1, g2)))
}
fn main() {
let mut matrices = Vec::new();
for _ in 0..8 {
matrices.push(X());
}
let product = kron_many(&matrices);
}
或者不进行克隆,使用
CowArray
来表示可能拥有的数组:
let product = matrices
.iter()
.map(|matrix| CowArray::from(matrix))
.reduce(|g1, g2| kron(&g1, &g2).into());