fn bad_linear_solve<'a,'b,M,T>(
    matrix: M,
    rhs: impl IntoIterator<Item=&'b T>,
    close: &impl CloseTo<Item=T>,
    ) -> Result<Vec<T>>
where M: IntoIterator,
      M::Item: IntoIterator<Item=&'a T>,
      T: 'a + 'b + Clone + One + Mul<Output=T> + SubAssign + MulAssign + Inv<Output=T>,
{
    let mut workmat: Vec<Vec<_>> =
        matrix .into_iter()
            .map(|row| row.into_iter().map(Clone::clone).collect())
            .collect();
    let mut sol: Vec<_> = rhs.into_iter().map(Clone::clone).collect();

    let n = workmat.len();
    assert!(workmat.iter().all(|row| row.len() == n));
    assert_eq!(sol.len(), n);

    for i in 0..n {
        { // find pivot
            let mut j = i;
            while close.close_to_zero(&workmat[j][i]) {
                j += 1;
                if j == n {
                    return Err(Error::Singular);
                }
            }
            if i != j {
                workmat.swap(i, j);
                sol.swap(i, j);
            }
        }
        // normalize pivot row
        {
            let pivot_inverse = workmat[i][i].clone().inv();
            for x in workmat[i].split_at_mut(i+1).1 {
                *x *= pivot_inverse.clone();
            }
            sol[i] *= pivot_inverse;
            workmat[i][i].set_one();
        }
        // cancel
        {
            let (top, midbot) = workmat.split_at_mut(i);
            let (pivrow, bottom) = midbot.split_first_mut().expect("row index i must exist");
            let (soltop, solmidbot) = sol.split_at_mut(i);
            let (solpiv, solbot) = solmidbot.split_first_mut().expect("row index imust exist");
            for (row, solx) in top.iter_mut().chain(bottom.iter_mut())
                               .zip(soltop.iter_mut().chain(solbot.iter_mut()))
            {
                if !close.close_to_zero(&row[i]) {
                    let (left, right) = row.split_at_mut(i+1);
                    for (j, x) in (i+1..n).zip(right) {
                        *x -= left[i].clone() * pivrow[j].clone();
                    }
                    *solx -= left[i].clone() * solpiv.clone();
                }
            }
        }
    }
    Ok(sol)
}
// --- BAD LINEAR SOLVER, TODO REPLACE WITH BETTER "SUPERFAST" SOLVERS ---
BAD LINEAR SOLVER, TODO REPLACE WITH BETTER "SUPERFAST" SOLVERS
BAD LINEAR SOLVER TODO REPLACE WITH BETTER " SUPERFAST " SOLVERS
fn bad_linear_solve<'a,'b,M,T>(
    matrix: M,
    rhs: impl IntoIterator<Item=&'b T>,
    close: &impl CloseTo<Item=T>,
    ) -> Result<Vec<T>>
where M: IntoIterator,
      M::Item: IntoIterator<Item=&'a T>,
      T: 'a + 'b + Clone + One + Mul<Output=T> + SubAssign + MulAssign + Inv<Output=T>,
{
    let mut workmat: Vec<Vec<_>> =
        matrix .into_iter()
            .map(|row| row.into_iter().map(Clone::clone).collect())
            .collect();
    let mut sol: Vec<_> = rhs.into_iter().map(Clone::clone).collect();
    let n = workmat.len();
    assert!(workmat.iter().all(|row| row.len() == n));
    assert_eq!(sol.len(), n);
    for i in 0..n {
        { // find pivot
            let mut j = i;
            while close.close_to_zero(&workmat[j][i]) {
                j += 1;
                if j == n {
                    return Err(Error::Singular);
                }
            }
            if i != j {
                workmat.swap(i, j);
                sol.swap(i, j);
            }
        }
        // normalize pivot row
        {
            let pivot_inverse = workmat[i][i].clone().inv();
            for x in workmat[i].split_at_mut(i+1).1 {
                *x *= pivot_inverse.clone();
            }
            sol[i] *= pivot_inverse;
            workmat[i][i].set_one();
        }
        // cancel
        {
            let (top, midbot) = workmat.split_at_mut(i);
            let (pivrow, bottom) = midbot.split_first_mut().expect("row index i must exist");
            let (soltop, solmidbot) = sol.split_at_mut(i);
            let (solpiv, solbot) = solmidbot.split_first_mut().expect("row index imust exist");
            for (row, solx) in top.iter_mut().chain(bottom.iter_mut())
                               .zip(soltop.iter_mut().chain(solbot.iter_mut()))
            {
                if !close.close_to_zero(&row[i]) {
                    let (left, right) = row.split_at_mut(i+1);
                    for (j, x) in (i+1..n).zip(right) {
                        *x -= left[i].clone() * pivrow[j].clone();
                    }
                    *solx -= left[i].clone() * solpiv.clone();
                }
            }
        }
    }
    Ok(sol)
}
fn bad_linear_solve < ' a , ' b , M , T > ( matrix : M , rhs : impl IntoIterator < Item = & ' b T > , close : & impl CloseTo < Item = T > , ) -> Result < Vec < T > > where M : IntoIterator , M :: Item : IntoIterator < Item = & ' a T > , T : ' a + ' b + Clone + One + Mul < Output = T > + SubAssign + MulAssign + Inv < Output = T > , { let mut workmat : Vec < Vec < _ > > = matrix . into_iter ( ) . map ( | row | row . into_iter ( ) . map ( Clone :: clone ) . collect ( ) ) . collect ( ) ; let mut sol : Vec < _ > = rhs . into_iter ( ) . map ( Clone :: clone ) . collect ( ) ; let n = workmat . len ( ) ; assert ! ( workmat iter ( ) all ( row row len ( ) n ) ) ; assert_eq ! ( sol len ( ) n ) ; for i in 0 .. n { { // find pivot let mut j = i ; while close . close_to_zero ( & workmat [ j ] [ i ] ) { j += 1 ; if j == n { return Err ( Error :: Singular ) ; } } if i != j { workmat . swap ( i , j ) ; sol . swap ( i , j ) ; } } // normalize pivot row { let pivot_inverse = workmat [ i ] [ i ] . clone ( ) . inv ( ) ; for x in workmat [ i ] . split_at_mut ( i + 1 ) . 1 { * x *= pivot_inverse . clone ( ) ; } sol [ i ] *= pivot_inverse ; workmat [ i ] [ i ] . set_one ( ) ; } // cancel { let ( top , midbot ) = workmat . split_at_mut ( i ) ; let ( pivrow , bottom ) = midbot . split_first_mut ( ) . expect ( " " ) ; let ( soltop , solmidbot ) = sol . split_at_mut ( i ) ; let ( solpiv , solbot ) = solmidbot . split_first_mut ( ) . expect ( " " ) ; for ( row , solx ) in top . iter_mut ( ) . chain ( bottom . iter_mut ( ) ) . zip ( soltop . iter_mut ( ) . chain ( solbot . iter_mut ( ) ) ) { if ! close . close_to_zero ( & row [ i ] ) { let ( left , right ) = row . split_at_mut ( i + 1 ) ; for ( j , x ) in ( i + 1 .. n ) . zip ( right ) { * x -= left [ i ] . clone ( ) * pivrow [ j ] . clone ( ) ; } * solx -= left [ i ] . clone ( ) * solpiv . clone ( ) ; } } } } Ok ( sol ) }
BAD LINEAR SOLVER, TODO REPLACE WITH BETTER "SUPERFAST" SOLVERS
BAD LINEAR SOLVER TODO REPLACE WITH BETTER " SUPERFAST " SOLVERS
matrix
M
rhs
impl IntoIterator<Item=&'b T>
close
&impl CloseTo<Item=T>
matrix
M
rhs
impl IntoIterator<Item=&'b T>
close
&impl CloseTo<Item=T>