Allowing Matlab to Talk to Rust
smitec.io
smitec.io
One minor suggestion, completely beside the point so please forgive me: a safer and perhaps more idiomatic way to implement the multiply_safe function would be with a functional-style one-liner:
fn multiply_safe(a : Vec<f64>, b : Vec<f64>) -> Vec<f64> {
if a.len() != b.len() {
panic!("The two vectors differ in length!");
}
return a.iter().zip(b.iter()).map(|(x, y)| x * y).collect()
}
Safer because you don't manipulate indices and lengths directly like you would in C, so there is no opportunity of an off-by-one bug or things like that. Surprisingly, rustc optimizer makes sure that this performs as well as the index-wrangling implementation (according to some simple tests I just ran).Frequently functional style optimizes better than the equivalent loop and index implementations because the iterator functional implementation cannot go out of bounds on the array, so the bounds checks that are implicit in indexing are elided.
* The function should take slices as inputs for instance, that way not only doesn't it take ownership of the inputs you don't need to copy the C arrays to vecs in the C-exposed function, you can just convert them to slice (which is essentially 0-cost, you just create a std::raw::Slice on the stack)
* The function also shouldn't panic it should return a Result (or an Option)
* Maybe less rustic but more efficient would be to take the output as an &mut [f64] (as the extern function does), that way the whole thing can be allocation-free
1 and 3 also simplify the glue code, instead of having to copy data from the input f64 to brand new vecs and from the output vec to the output f64, just convert the three input pointers with from_raw_parts and from_raw_parts_mut. That makes for much simpler and easier to review unsafe code as well:
let a = unsafe { from_raw_parts(a_double, elements) };
let b = unsafe { from_raw_parts(b_double, elements) };
let c = unsafe { from_raw_parts_mut(c_double, elements) };
that's it, no mucking around with pointer offsets, and the rest if safe Rust.Something like this: http://is.gd/uFhx2J
A while ago I wrote a mexFunction purely in Cython, and it was wondeful because Python was immediately available to work with (instead of C). The problem was that the numerical libraries on which NumPy builds often shared symbol names with MATLAB (such as svd, or hdf5) that differ in implementation resulting segfaults or corrupted data.