I am struggling to convert an Array2 of Cartesian Coordinates to Polar Coordinates. The two columns of each row have to be mutated based on each others values, and I can't figure out how to make it.
After different trials, I implemented the following code, but I think it is a dead end:
use ndarray::{array, Axis};
use num_traits::float::Float;
fn main() {
let mut coords = array![[1., 0.], [1. / 2., (3.).sqrt() / 2.0], [0., 1.]];
for mut row in coords.axis_iter_mut(Axis(0)) {
let col_0 = row.get(0).unwrap();
let col_1 = row.get(1).unwrap();
let mut row_polar_coord = array![
(col_0.powi(2) + col_1.powi(2)).sqrt(),
(col_1 / col_0).atan()
];
//row = row_polar_coord;
// Error: mismatched types
// expected struct `ndarray::ArrayBase<ndarray::ViewRepr<&mut {float}>, _>`
// found struct `ndarray::ArrayBase<ndarray::OwnedRepr<{float}>, _>`
row = row_polar_coord.view_mut();
// Diagnostics:
// `row_polar_coord` does not live long enough
// borrowed value does not live long enough
}
}
How should be handled these kinds of transformations in ndarray?
I would suggest not using an ndarray
to store the real and imaginary part of your values but a tuple. This has way less overhead.
For inplace mutation you can use map_inplace()
:
use ndarray::{array, Axis};
fn main() {
let mut coords = array![(1_f32, 0_f32), (1. / 2., (3_f32).sqrt() / 2.0), (0., 1.)];
coords.map_inplace(|(a,b)| {
let c = (a.powi(2) + b.powi(2)).sqrt();
let d = (*b / *a).atan();
*a = c;
*b = d;
});
print!("{:?}", coords);
}
When you really need to stick to this input you can do
use ndarray::{array, Axis};
fn main() {
let mut coords = array![[1_f32, 0_f32], [1. / 2., (3_f32).sqrt() / 2.0], [0., 1.]];
coords.axis_iter_mut(Axis(0)).for_each(|mut x| {
let a : f32 = *x.get(0).unwrap();
let b : f32 = *x.get(1).unwrap();
x[0] = (a.powi(2) + b.powi(2)).sqrt();
x[1] = (b / a).atan();
});
print!("{:?}", coords);
}