问题
I'm learning Rust by porting a small program that was written in C. It works with comparable performance to the C version. Still, I can't help but feeling my code could be better, hence this post.
The following code solves a matrix equation using Gaussian elimination, which requires iterating over portions of an array.
pub struct MatrixEquation {
vec: Vec<f64>,
mat: Vec<Vec<f64>>,
}
impl MatrixEquation {
fn solve(&mut self) {
let size = self.vec.len();
// Transform matrix to upper triangular
for row in 0..size {
let mut rfabs = self.mat[row][row].abs();
let mut pivot = row;
for trow in row + 1..size {
let tfabs = self.mat[trow][row].abs();
if tfabs > rfabs {
pivot = trow;
rfabs = tfabs;
}
}
if pivot != row {
self.vec.swap(pivot, row);
self.mat.swap(pivot, row);
}
if !self.mat[row][row].is_normal() {
die!("Matrix is singular");
}
for elem in row + 1..size {
if self.mat[elem][row] != 0.0 {
let scale = self.mat[elem][row] / self.mat[row][row];
for tcol in row..size {
self.mat[elem][tcol] -= self.mat[row][tcol] * scale;
}
self.vec[elem] -= self.vec[row] * scale;
}
}
}
for row in (0..size).rev() {
self.vec[row] /= self.mat[row][row];
let backsub = self.vec[row];
for trow in 0..row {
self.vec[trow] -= self.mat[trow][row] * backsub;
}
}
}
}
My first concern is the back substitution loop at the end. I have to loop through the rows backwards. It seems like there would be a straight forward way to do this. Constructing a range and calling rev() seems to be an accepted way to do this, but it seems heavy handed. What is regarded as best practice for doing something like this?
My other concern is that I'm using numerical indices rather than iterators, and I don't want to do anything which forces the compiler to do bounds checking. I found the zip() method which could potentially be useful for what I'm trying to do, but since I am not starting at the beginning of the rows when I traverse them, I'd have to call skip() which I think is less efficient than numerically indexing into the middle of the row. If you were writing the elem loop in the program above, how would you do it?
来源:https://stackoverflow.com/questions/43293834/the-best-way-to-iterate-over-sections-of-2d-arrays-in-rust