【问题标题】:Is there a good way to do an overlapping copy in ndarray in rust?有没有一种好方法可以在 ndarray 中进行 rust 的重叠复制?
【发布时间】:2019-08-29 20:08:27
【问题描述】:

这是我尝试过的

use ndarray::{arr2, s};
let mut a = arr2(&[[1, 2, 3],
                   [4, 5, 6]]);
let b = arr2(&[[2, 3, 3],
               [5, 6, 6]]);

a.slice_mut(s![.., ..2]).assign(&a.slice_mut(s![.., 1..]));

由于借用规则显然失败了(playround link):

error[E0499]: cannot borrow `a` as mutable more than once at a time
  --> src/main.rs:13:38
   |
13 |     a.slice_mut(s![.., ..2]).assign(&a.slice_mut(s![.., 1..]));
   |     -                        ------  ^ second mutable borrow occurs here
   |     |                        |
   |     |                        first borrow later used by call
   |     first mutable borrow occurs here

a 是我所拥有的,b 是我想要获得的。

在 numpy 中就像 a[:, :2] = a[:, 1:] 一样简单。

PS 也许nalgebra crate 有一个简单的解决方案?

【问题讨论】:

  • 你为什么不写一个for循环呢?
  • @FrenchBoiethios 只是一个 for 循环不会解决所有可能出现的混叠问题(例如从左到右与从右到左复制)。我也希望图书馆为我做这件事,或者至少帮我做这件事。否则我会求助于纯 C。

标签: multidimensional-array rust copy borrowing nalgebra


【解决方案1】:

在 ndarray 的 master 分支中,有一个特殊的宏,比 split_at_mut() 更方便,因为它支持任意切片 - 但是当切片重叠时它会恐慌:

use ndarray::multislice;
use ndarray::prelude::*;
let mut arr: Array1<_> = (0..4).collect();
let (mut a, mut b) = multislice!(arr, mut [..;2], mut [1..;2]);
a.assign(&b);

[1,1,3,3]

他们甚至解决了丢番图方程来检查它。它发生在运行时而不是编译时split_at_mut

【讨论】:

    【解决方案2】:

    好的,知道了

    use ndarray::{arr2, s,Array};
    
    let mut a = arr2(&[[1, 2, 3],
                       [4, 5, 6]]);
    unsafe{
        let b = a.as_mut_ptr();
        let c = Vec::<i32>::from_raw_parts(b, 6, 6);
        let mut d = Array::from_shape_vec((2, 3), c).unwrap();
        a.slice_mut(s![.., ..2]).assign(&d.slice_mut(s![.., 1..]));
        std::mem::forget(d);
    }
    println!("{:?}",a);
    

    【讨论】:

    • 请注意,无法保证此代码会起作用:assign 移动元素的顺序未定义,因此未来版本的 Rust 或 ndarray 可能会破坏您的代码。跨度>
    • 如果你想将数据向右移动而不是向左移动,它也行不通……
    • 这个程序会导致未定义的行为。
    • @Jmb 是的,它需要一些类似于 memmove 实现的逻辑:如果向左移动则反转切片
    猜你喜欢
    • 1970-01-01
    • 2017-11-14
    • 2010-09-17
    • 2015-11-02
    • 2021-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多