-
Notifications
You must be signed in to change notification settings - Fork 320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Indexing points via parallel arrays #526
Comments
extern crate ndarray;
use ndarray::prelude::*;
fn main() {
let mut x = Array::zeros((10, 10));
for (&i, &j) in [0, 0, 1, 1].iter().zip(&[0, 1, 2, 3]) {
x[(i, j)] = 1.;
}
println!("{}", x);
}
In principle, a loop shouldn't be worse than what NumPy has to do for "advanced indexing" like that. When using Python/NumPy, it's typically very advantageous to avoid Python loops and instead try to make NumPy do as much of the work as possible, since Python is slow but NumPy is largely written in C. In contrast, when using Rust/ It is worth noting, though, that indexing individual elements will generally be slower than using an iterator or a method like |
questions: let dxs: Array or similar;
let dys: Array or similar;
Zip::from(&(dxs + xx[0])).and(&(dys + yy[0])).apply(|x, y| {} What's the difference between Is this how I'm supposed to iterate over 2 arrays? It seems a bit clunky. And if I omit a single ampersand, omit the parens, or stack on extra
It took me over 10 minutes to find out what went wrong, and to add This looks nearly as impenetrable as C++ template errors. Is it normal for Rust to have confusing errors? Does this error clearly tell an experienced Rust user to pass a reference instead? image
.subview_mut(Axis(0), *x as usize)
.subview_mut(Axis(0), *y as usize)
.fill(0xff); This syntax seems quite ugly. Is there any better way to replicate Numpy's Is looping |
See also this article introducing
What are #[macro_use(azip)]
extern crate ndarray;
azip!(dxs, dys in {
let x = dxs + xx[0];
let y = dxs + yy[0];
// do something
}); This avoids creating temporary arrrays for the results of If they're arrays, I'd recommend zipping over them too (broadcasting if necessary).
Rust is known for having good error messages. The compiler may not always be able to suggest exactly what change you need to make (because it doesn't necessary know your intent), but it generally does a good job indicating what the problem is. Let's break down this error message.
So, the compiler identifies where the problem is occurring and what it is, and it even provides suggestions of types that work. Given this message, we know that we need to somehow transform In general, I would suggest first going to the docs for the function where the error is occurring ( Alternatively, the compiler told us that it expected a type that implements [Edit: The error message is somewhat misleading in that it indicates we need a type that implements The most confusing part is the long type names, which is a result of Fwiw, the equivalent error in Python would be something like
and it would occur at runtime (maybe after the program has already been running for hours), not compile time. This error message gives very little information on how to fix the problem, and it's especially problematic if the
See Slicing and the #[macro_use(s)]
extern crate ndarray;
image.slice_mut(s![*x, *y, ..]).fill(0xff);
Yes; avoid indexing where possible. |
Thanks for the help. I'm not sure if I'll continue learning Rust, seems I could learn Nim and https://github.com/mratsim/Arraymancer, it could be faster to work with and have less ownership quirks, while still building to a self-contained binary, and being fast at runtime. For anything other than Python and numerically-focused languages, I may have to reimplement a lot of DSP-related things, but it should be fine since I can just reference the Scipy source code. Is there a reason you didn't instead use more concise syntax like |
I don't know anything about Nim; it looks interesting. You might also be interested in Julia. I haven't used it myself but have heard good things about it. In favor of Rust, I will say that the powerful type system and borrow checker really help me to write correct code, which is important to me for scientific research because I don't like having to fix something and restart my program after it's been running for a long time doing calculations. It also makes me more confident that my results are correct. Before Rust, I used Python for many years, and I found that large programs became difficult to manage due to the highly dynamic nature of the language. Learning Rust did take some investment (reading the book and working with the language for a while), but I've been really happy with the language once I became comfortable with it. The primary disadvantage right now is the lack of full-featured, established scientific libraries like NumPy/SciPy/Pandas/Matplotlib.
That syntax isn't supported right now. There's a proposal for that feature (postfix macros) in rust-lang/rfcs#2442. |
maybe i'll try that, and screw around with https://github.com/JuliaLang/PackageCompiler.jl to distribute binaries to users
honestly it's more like casting back and forth between i32, usize, and f32. |
This issue seems to be resolved, and there haven't been any comments in a few months, so I'm closing it. |
Numpy python:
Can I accomplish this in Rust ndarray? Should I loop over x and y indices instead? Will I lose performance using a loop?
Should I instead generate x and y indices in a loop, and assign to 1 array point at a time?
The text was updated successfully, but these errors were encountered: