首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用数组创建结构(矩阵)

用数组创建结构(矩阵)
EN

Stack Overflow用户
提问于 2015-11-17 04:22:26
回答 2查看 4.6K关注 0票数 5

我目前正在做一个简单的项目,让自己熟悉锈菌。我没有太多的系统编程经验,但我希望学习!

我试图创建一个矩阵结构,但我发现很难弄清楚我应该如何存储数据。我觉得我应该可以使用数组了。矩阵的大小必须在构造时定义,因此我希望可以将数组存储在堆栈上。

现在,我的代码如下所示:

代码语言:javascript
运行
复制
use std::ops::Mul;
use std::ops::Add;
use std::ops::Div;

struct Matrix {
    cols: i32,
    rows: i32,
    // Of course this doesn't work!
    data: [f32; ..cols*rows]
}

// Below here are a bunch of stub methods.
impl Mul<f32> for Matrix {
    type Output = Matrix;

    fn mul(self, m: f32) -> Matrix {
        return self;
    }
}

impl Mul<Matrix> for Matrix {
    type Output = Matrix;

    fn mul(self, m: Matrix) -> Matrix {
        // Will use Strassen algorithm if large, traditional otherwise
        return self;
    }
}

impl Add<Matrix> for Matrix {
    type Output = Matrix;

    fn add(self, m: Matrix) -> Matrix {
        return self;
    }
}

impl Div<f32> for Matrix {
    type Output = Matrix;

    fn div(self, f: f32) -> Matrix {
        return self;
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-11-17 04:38:57

最简单的方法是使用Vec

代码语言:javascript
运行
复制
struct Matrix {
    cols: i32,
    rows: i32,
    data: Vec<f32>
}

impl Matrix {
    fn new(cols: i32, rows: i32) -> Matrix {
        Matrix {
            cols: cols,
            rows: rows,
            data: vec![0.0; cols * rows]
        }
    }
}

如果不想将数据存储在堆中,可以将Matrix设置为动态大小的类型,但这是很难做到的,也不是真正支持的。见关于这个主题的Reddit帖子

如果您不想使用Vec,但是可以将数据存储在堆中,则可以使用装箱片(Box<[f32]>)。请参阅Vec::into_boxed_slice,以获得一种创建方法。

当然,如果您真的不想使用堆,您可以为不同大小的矩阵创建不同的Matrix类型。这就是板条箱N代数所做的。

票数 4
EN

Stack Overflow用户

发布于 2020-09-19 01:55:58

您也可以使用向量向量(Vec<Vec<T>>),而不需要实现自己的Matrix或使用库。但在索引方面,这比禤浩焯的方法要慢得多。nalgebra擅长矢量化计算,但对于元素级运算,它的性能要比由Vec<T>Vec<Vec<T>>组成的简单矩阵差。以下是一些基准:

代码语言:javascript
运行
复制
test bench_vec               ... bench:  84,694,933 ns/iter (+/- 7,412,836)
test bench_vec_of_vec        ... bench:  87,083,636 ns/iter (+/- 1,171,842)
test bench_vec_unsafe        ... bench:  41,440,947 ns/iter (+/- 752,463)
test bench_vec_of_vec_unsafe ... bench:  44,532,595 ns/iter (+/- 629,209)
test bench_nalgebra          ... bench: 452,872,630 ns/iter (+/- 40,284,295)
代码语言:javascript
运行
复制
#![feature(test)]

extern crate test;
use na::Matrix;
use na::{Dynamic, VecStorage};
use nalgebra as na;

type DMatrixi32 = Matrix<u8, Dynamic, Dynamic, VecStorage<u8, Dynamic, Dynamic>>;

use test::Bencher;

#[bench]
fn bench_vec_of_vec(b: &mut Bencher) {
    let (m, n) = (10000, 10000);
    let mut matrix = vec![vec![0u8; n]; m];
    b.iter(|| {
        for i in 0..m {
            for j in 0..n {
                matrix[i][j] = 1u8;
            }
        }
    });
}

#[bench]
fn bench_vec(b: &mut Bencher) {
    let (m, n) = (10000, 10000);
    let mut matrix = vec![0u8; n * m];
    b.iter(|| {
        for i in 0..m {
            for j in 0..n {
                matrix[i * n + j] = 1u8;
            }
        }
    });
}

#[bench]
fn bench_vec_of_vec_unsafe(b: &mut Bencher) {
    let (m, n) = (10000, 10000);
    let mut matrix = vec![vec![0u8; n]; m];
    b.iter(|| {
        for i in 0..m {
            for j in 0..n {
                unsafe {
                    *matrix.get_unchecked_mut(i).get_unchecked_mut(j) = 1u8;
                }
            }
        }
    });
}

#[bench]
fn bench_vec_unsafe(b: &mut Bencher) {
    let (m, n) = (10000, 10000);
    let mut matrix = vec![0u8; n * m];
    b.iter(|| {
        for i in 0..m {
            for j in 0..n {
                unsafe { *matrix.get_unchecked_mut(i * n + j) = 1u8 };
            }
        }
    });
}

#[bench]
fn bench_nalgebra(b: &mut Bencher) {
    let (m, n) = (10000, 10000);
    let mut matrix = DMatrixi32::from_vec(m, n, vec![0u8; n * m]);
    b.iter(|| {
        for i in 0..m {
            for j in 0..n {
                matrix[(i, j)] = 1u8;
            }
        }
    });
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33749114

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档