1

我正在尝试na::Matrix2x3通过从 a 的前两行复制来创建 a na::Matrix3。结果将存储在结构中。

我不知道该怎么做,文档很混乱。我尝试了clone(), into(),from(...)等,但似乎没有任何效果。

这是我尝试使用.clone()游乐场)的可重现示例:

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);
4

3 回答 3

2

…或者可能更适合: fixed_rows()

let proj33 = na::Matrix2x3::<f64>::zeros();
let proj: na::Matrix2x3<f64> = proj33.fixed_rows::<2>(0).into();
于 2021-07-15T16:10:56.887 回答
1

现在,我有点同意@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没有很好的记录,所以我不知道这是否真的安全,或者是否有一些我不知道的不变量。我不明白为什么这不应该是好的,但这些当然是著名的遗言。

于 2021-07-12T20:18:37.987 回答
1

好的,我已经想通了。我必须使用fixed_slice而不是(或除此之外)rows--- 因为Matrix2x3编译器知道输出 ( ) 的大小,所以切片也必须是。

关键是使用:

.fixed_slice::<2, 3>(0, 0).into()

这适用于动态矩阵(游乐场)

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 的矩阵)(游乐场)

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();
}

但是,在对动态矩阵进行切片时,请记住,如果切片超出范围,它会出现恐慌。

于 2021-07-14T17:48:24.813 回答