如何通过从动态矩阵视图复制来创建代数静态矩阵?
How do I create an nalgebra static matrix by copying from a dynamic matrix view?
我正在尝试通过复制 na::Matrix3
的前两行来创建 na::Matrix2x3
。结果将存储在结构中。
我不知道该怎么做,文档也很混乱。我尝试了 clone()
、into()
、from(...)
等,但似乎没有任何效果。
这是一个可重现的例子,我尝试使用 .clone()
(playground):
extern crate nalgebra as na; // 0.27.1
fn main() {
let proj33 = na::Matrix3::<f64>::zeros();
let proj: na::Matrix2x3<f64> = proj33.rows(0, 2).clone();
}
error[E0308]: mismatched types
--> src/main.rs:5:36
|
5 | let proj: na::Matrix2x3<f64> = proj33.rows(0, 2).clone();
| ------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Const`, found struct `Dynamic`
| |
| expected due to this
|
= note: expected struct `Matrix<_, Const<2_usize>, _, ArrayStorage<f64, 2_usize, 3_usize>>`
found struct `Matrix<_, Dynamic, _, SliceStorage<'_, f64, Dynamic, Const<3_usize>, Const<1_usize>, Const<3_usize>>>`
这似乎可行,但它很浪费,因为它首先将矩阵初始化为零:
let mut proj = na::Matrix2x3::<f64>::zeros();
proj.copy_from(&proj33.rows(0, 2));
在 Eigen (C++) 中我会这样做:
const Eigen::Matrix<double, 2, 3> proj = proj33.topRows(2);
现在,我有点同意@Shepmaster 的观点,这可能真的是完全没有必要的,但如果你绝对不能忍受用零初始化矩阵,你可以使用一些 unsafe
:
extern crate nalgebra as na;
fn main() {
let proj33 = na::Matrix3::<f64>::zeros();
let proj = unsafe {
// create a new matrix with probably a bunch of garbage in it
let mut p = na::Matrix2x3::<f64>::new_uninitialized();
// copy the data from the other matrix into the unitialized one
(*p.as_mut_ptr()).copy_from(&proj33.rows(0, 2));
// pinky promise that it's initialized now
p.assume_init()
};
println!("{}", proj);
}
免责声明:Matrix::new_unitialized
没有很好的记录,所以我不知道这是否真的安全,或者是否有一些我不知道的不变量的。我不明白为什么这不应该没问题,但这当然是著名的遗言。
好的,我已经弄明白了。我必须使用 fixed_slice
而不是(或除此之外) rows
--- 因为编译器知道输出 (Matrix2x3
) 的大小,所以切片必须是嗯。
关键是使用:
.fixed_slice::<2, 3>(0, 0).into()
这适用于动态矩阵(playground):
extern crate nalgebra as na;
fn main() {
let proj33 = na::DMatrix::identity(3, 3);
let proj: na::Matrix2x3<f64> = proj33.fixed_slice::<2, 3>(0, 0).into();
}
还有动态矩阵视图(也就是使用 SliceStorage 而不是 ArrayStorage 的矩阵)(playground):
extern crate nalgebra as na;
fn main() {
let proj33 = na::DMatrix::identity(3, 3);
let proj33_view = proj33.rows(0, 2);
dbg!(&proj33_view);
let proj: na::Matrix2x3<f64> = proj33_view.fixed_slice::<2, 3>(0, 0).into();
}
但是,在对动态矩阵进行切片时,请记住,如果切片超出范围,它会出现 panic。
……或者可能更适合: fixed_rows()
let proj33 = na::Matrix2x3::<f64>::zeros();
let proj: na::Matrix2x3<f64> = proj33.fixed_rows::<2>(0).into();
我正在尝试通过复制 na::Matrix3
的前两行来创建 na::Matrix2x3
。结果将存储在结构中。
我不知道该怎么做,文档也很混乱。我尝试了 clone()
、into()
、from(...)
等,但似乎没有任何效果。
这是一个可重现的例子,我尝试使用 .clone()
(playground):
extern crate nalgebra as na; // 0.27.1
fn main() {
let proj33 = na::Matrix3::<f64>::zeros();
let proj: na::Matrix2x3<f64> = proj33.rows(0, 2).clone();
}
error[E0308]: mismatched types
--> src/main.rs:5:36
|
5 | let proj: na::Matrix2x3<f64> = proj33.rows(0, 2).clone();
| ------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Const`, found struct `Dynamic`
| |
| expected due to this
|
= note: expected struct `Matrix<_, Const<2_usize>, _, ArrayStorage<f64, 2_usize, 3_usize>>`
found struct `Matrix<_, Dynamic, _, SliceStorage<'_, f64, Dynamic, Const<3_usize>, Const<1_usize>, Const<3_usize>>>`
这似乎可行,但它很浪费,因为它首先将矩阵初始化为零:
let mut proj = na::Matrix2x3::<f64>::zeros();
proj.copy_from(&proj33.rows(0, 2));
在 Eigen (C++) 中我会这样做:
const Eigen::Matrix<double, 2, 3> proj = proj33.topRows(2);
现在,我有点同意@Shepmaster 的观点,这可能真的是完全没有必要的,但如果你绝对不能忍受用零初始化矩阵,你可以使用一些 unsafe
:
extern crate nalgebra as na;
fn main() {
let proj33 = na::Matrix3::<f64>::zeros();
let proj = unsafe {
// create a new matrix with probably a bunch of garbage in it
let mut p = na::Matrix2x3::<f64>::new_uninitialized();
// copy the data from the other matrix into the unitialized one
(*p.as_mut_ptr()).copy_from(&proj33.rows(0, 2));
// pinky promise that it's initialized now
p.assume_init()
};
println!("{}", proj);
}
免责声明:Matrix::new_unitialized
没有很好的记录,所以我不知道这是否真的安全,或者是否有一些我不知道的不变量的。我不明白为什么这不应该没问题,但这当然是著名的遗言。
好的,我已经弄明白了。我必须使用 fixed_slice
而不是(或除此之外) rows
--- 因为编译器知道输出 (Matrix2x3
) 的大小,所以切片必须是嗯。
关键是使用:
.fixed_slice::<2, 3>(0, 0).into()
这适用于动态矩阵(playground):
extern crate nalgebra as na;
fn main() {
let proj33 = na::DMatrix::identity(3, 3);
let proj: na::Matrix2x3<f64> = proj33.fixed_slice::<2, 3>(0, 0).into();
}
还有动态矩阵视图(也就是使用 SliceStorage 而不是 ArrayStorage 的矩阵)(playground):
extern crate nalgebra as na;
fn main() {
let proj33 = na::DMatrix::identity(3, 3);
let proj33_view = proj33.rows(0, 2);
dbg!(&proj33_view);
let proj: na::Matrix2x3<f64> = proj33_view.fixed_slice::<2, 3>(0, 0).into();
}
但是,在对动态矩阵进行切片时,请记住,如果切片超出范围,它会出现 panic。
……或者可能更适合: fixed_rows()
let proj33 = na::Matrix2x3::<f64>::zeros();
let proj: na::Matrix2x3<f64> = proj33.fixed_rows::<2>(0).into();