是否有一个Rust ndarray等效于片上的numpy算法?

时间:2018-05-17 21:46:49

标签: multidimensional-array rust

以下Python代码将重复将向量[1, 2, 3, 4]添加到二维数组a中的每一行,仅从第20行开始。

import numpy as np

# an array of shape (100, 4)
a = np.zeros((100, 4), dtype=np.float32)

# and this is the operation explained above
a[20:, :] += [1.0, 2.0, 3.0, 0.0]

ndarray有一个简单的等价物吗? 我已经可以用更复杂的杂乱外观代码做我需要的东西,但觉得可能有一个整洁的ndarray.rs等效。

好的,冒着让问题过于复杂的风险,我认为可能有一个简单的答案,我无法发现......

我使用的f32形状(n,8)数组代表三个顶点位置,三个正常分量和两个纹理贴图坐标。我正在将多个3D对象的缓冲区合并为一个,以实现更高效的图形渲染。在8个宽阵列中,前三个值需要缩放,即乘以&[sx, sy, sz],然后使用标准rz.dot(&rx.dot(&ry.dot()))函数旋转,最后添加位移&[dx, dy, dz]。法线只需旋转即可。我当前的系统涉及将数据保存在中间数组变量中。

use ndarray as nd;
array_buffer: nd::Array2<f32>, loc: &[f32; 3], scl: &[f32; 3]...
...
// scale then rotate new verts then add displacement
let new_verts = &new_buf.array_buffer.slice(s![.., 0..3]) * &nd::arr1(scl);
let new_verts = rotate_vec(rot, &new_verts) + &nd::arr1(loc);
// then add them to existing verts
let mut verts = nd::stack(nd::Axis(0),
                &[old_buf.array_buffer.slice(s![.., 0..3]),
                  new_verts.view()]).unwrap();
...

我知道我无法将它减少到numpy one liner

verts = np.append(old_buf.array_buffer[:,0:3], 
        rotate_vec(rot, (new_buf.array_buffer[:,0:3] * scl) + loc))

但我认为也许某些地图或zip变体或宏可能对我有所帮助。

1 个答案:

答案 0 :(得分:10)

可以使用与在Python中执行的步骤相同的两个步骤来完成:slicing,然后添加分配broadcast右手数组。

use ndarray::Array2;

let mut a: Array2<f32> = Array2::zeros((100, 4));
{ 
    let mut slice = a.slice_mut(s![20.., ..]);
    slice += &ArrayView::from(&[1.0, 2.0, 3.0, 4.0]);
}

使用slice_muts!宏完成切片以定义预期范围。 切片的结果是一个可变数组视图,因此,ArrayBase中看到的大多数操作都可用,包括算术运算。 通过广播规则,右侧的形状[4]数组可以自动广播到[100, 4]运算符的形状+=之一。

如果从Python到Rust的ndarray包转换中存在其他混淆,则文档包含guide for Python users