# Solving upper triangular matrix-vector equation in Rust

Most linear algebra libraries written for Rust, e.g. nalgebra or ndarray have type or trait requirements that mean their inherent methods don't work on generic data types. When working exclusively with f64 these libraries might use other optimisations. I am working with custom generics, however, so have to implement my own functions.

Below is one such function which solves an upper triangular matrix equation system:

$$\mathbf{U x} = \mathbf{b}$$

use ndarray::prelude::*;
use ndarray::Zip;
use num_traits::identities::Zero;
use std::iter::Sum;
use std::ops::{Div, Mul, Sub};

/// Inner product between two 1d-arrays.
fn dmul11_<T>(a: &ArrayView1<T>, b: &ArrayView1<T>) -> T
where
for<'a> &'a T: Mul<&'a T, Output = T>,
T: Sum,
{
assert_eq!(a.len(), b.len());
a.iter().zip(b.iter()).map(|(x, y)| x * y).sum()
}

/// Solve the upper triangular matrix equation: Ux=b, for x.
fn dsolve_upper21_<T>(u: &ArrayView2<T>, b: &ArrayView1<T>) -> Array1<T>
where
T: Clone + Sum + Zero,
for<'a> &'a T: Sub<&'a T, Output = T> + Mul<&'a T, Output = T> + Div<&'a T, Output = T>,
{
let n: usize = u.len_of(Axis(0));
let mut x: Array1<T> = Array::zeros(n);
for i in (0..n).rev() {
let v = &b[i] - &dmul11_(&u.slice(s![i, (i + 1)..]), &x.slice(s![(i + 1)..]));
x[i] = &v / &u[[i, i]]
}
x
}


Is this code satisfactory or am I missing something obvious performance wise?