fn qrfac(&mut self) {
        // Compute the QR factorization of the jacobian
        // compute the initial column norms and initialize several arrays.
        for (j, ij) in (0..self.nfree).zip((0..self.m * self.nfree).step_by(self.m)) {
            self.wa2[j] = self.fjac[ij..ij + self.m].enorm();
            self.wa1[j] = self.wa2[j];
            self.wa3[j] = self.wa1[j];
            self.ipvt[j] = j;
        }
        // reduce a to r with householder transformations.
        for j in 0..self.m.min(self.nfree) {
            // bring the column of largest norm into the pivot position.
            let mut kmax = j;
            for k in j..self.nfree {
                if self.wa1[k] > self.wa1[kmax] {
                    kmax = k;
                }
            }
            if kmax != j {
                let mut ij = self.m * j;
                let mut jj = self.m * kmax;
                for _ in 0..self.m {
                    self.fjac.swap(jj, ij);
                    ij += 1;
                    jj += 1;
                }
                self.wa1[kmax] = self.wa1[j];
                self.wa3[kmax] = self.wa3[j];
                self.ipvt.swap(j, kmax);
            }
            let jj = j + self.m * j;
            let jjj = self.m - j + jj;
            let mut ajnorm = self.fjac[jj..jjj].enorm();
            if ajnorm == 0. {
                self.wa1[j] = -ajnorm;
                continue;
            }
            if self.fjac[jj] < 0. {
                ajnorm = -ajnorm;
            }
            for fjac in self.fjac[jj..jjj].iter_mut() {
                *fjac /= ajnorm;
            }
            self.fjac[jj] += 1.;
            // apply the transformation to the remaining columns
            // and update the norms.
            let jp1 = j + 1;
            if jp1 < self.nfree {
                for k in jp1..self.nfree {
                    let mut sum = 0.;
                    let mut ij = j + self.m * k;
                    let mut jj = j + self.m * j;
                    for _ in j..self.m {
                        sum += self.fjac[jj] * self.fjac[ij];
                        ij += 1;
                        jj += 1;
                    }
                    let temp = sum / self.fjac[j + self.m * j];
                    ij = j + self.m * k;
                    jj = j + self.m * j;
                    for _ in j..self.m {
                        self.fjac[ij] -= temp * self.fjac[jj];
                        ij += 1;
                        jj += 1;
                    }
                    if self.wa1[k] != 0. {
                        let temp = self.fjac[j + self.m * k] / self.wa1[k];
                        let temp = (1. - temp.powi(2)).max(0.);
                        self.wa1[k] *= temp.sqrt();
                        let temp = self.wa1[k] / self.wa3[k];
                        if 0.05 * temp * temp < f64::EPSILON {
                            let start = jp1 + self.m * k;
                            self.wa1[k] = self.fjac[start..start + self.m - j - 1].enorm();
                            self.wa3[k] = self.wa1[k];
                        }
                    }
                }
            }
            self.wa1[j] = -ajnorm;
        }
    }
/// subroutine qrfac
///
/// this subroutine uses householder transformations with column pivoting
/// (optional) to compute a qr factorization of the m by n matrix a. that
/// is, qrfac determines an orthogonal matrix q, a permutation matrix p, and
/// an upper trapezoidal matrix r with diagonal elements of nonincreasing
/// magnitude, such that a*p = q*r. the householder transformation for
/// column k, k = 1,2,...,min(m,n), is of the form
///
/// i - (1/u(k))*u*u
///
/// where u has zeros in the first k-1 positions. the form of this
/// transformation and the method of pivoting first appeared in the
/// corresponding linpack subroutine.
///
/// the subroutine statement is
///
/// subroutine qrfac(m,n,a,lda,pivot,ipvt,lipvt,rdiag,acnorm,wa)
///
/// where
///
/// m is a positive integer input variable set to the number of rows of a.
///
/// n is a positive integer input variable set to the number of columns of
/// a.
///
/// a is an m by n array. on input a contains the matrix for which the qr
/// factorization is to be computed. on output the strict upper trapezoidal
/// part of a contains the strict upper trapezoidal part of r, and the lower
/// trapezoidal part of a contains a factored form of q (the non-trivial
/// elements of the u vectors described above).
///
/// lda is a positive integer input variable not less than m which specifies
/// the leading dimension of the array a.
///
/// pivot is a logical input variable. if pivot is set true, then column
/// pivoting is enforced. if pivot is set false, then no column pivoting is
/// done.
///
/// ipvt is an integer output array of length lipvt. ipvt defines the
/// permutation matrix p such that a*p = q*r. column j of p is column
/// ipvt(j) of the identity matrix. if pivot is false, ipvt is not
/// referenced.
///
/// lipvt is a positive integer input variable. if pivot is false, then
/// lipvt may be as small as 1. if pivot is true, then lipvt must be at
/// least n.
///
/// rdiag is an output array of length n which contains the diagonal
/// elements of r.
///
/// acnorm is an output array of length n which contains the norms of the
/// corresponding columns of the input matrix a. if this information is not
/// needed, then acnorm can coincide with rdiag.
///
/// wa is a work array of length n. if pivot is false, then wa can coincide
/// with rdiag.
subroutine qrfac
this subroutine uses householder transformations with column pivoting
(optional) to compute a qr factorization of the m by n matrix a. that
is, qrfac determines an orthogonal matrix q, a permutation matrix p, and
an upper trapezoidal matrix r with diagonal elements of nonincreasing
magnitude, such that a*p = q*r. the householder transformation for
column k, k = 1,2,...,min(m,n), is of the form





the subroutine statement is





m is a positive integer input variable set to the number of rows of a.

n is a positive integer input variable set to the number of columns of
a.

a is an m by n array. on input a contains the matrix for which the qr
factorization is to be computed. on output the strict upper trapezoidal
part of a contains the strict upper trapezoidal part of r, and the lower
trapezoidal part of a contains a factored form of q (the non-trivial
elements of the u vectors described above).

lda is a positive integer input variable not less than m which specifies
the leading dimension of the array a.

pivot is a logical input variable. if pivot is set true, then column
pivoting is enforced. if pivot is set false, then no column pivoting is
done.

ipvt is an integer output array of length lipvt. ipvt defines the
permutation matrix p such that a*p = q*r. column j of p is column
ipvt(j) of the identity matrix. if pivot is false, ipvt is not
referenced.

lipvt is a positive integer input variable. if pivot is false, then
lipvt may be as small as 1. if pivot is true, then lipvt must be at
least n.

rdiag is an output array of length n which contains the diagonal
elements of r.

acnorm is an output array of length n which contains the norms of the
corresponding columns of the input matrix a. if this information is not
needed, then acnorm can coincide with rdiag.

wa is a work array of length n. if pivot is false, then wa can coincide
with rdiag.
subroutine qrfac this subroutine uses householder transformations with column pivoting ( optional ) to compute a qr factorization of the m by n matrix a . that is qrfac determines an orthogonal matrix q a permutation matrix p and an upper trapezoidal matrix r with diagonal elements of nonincreasing magnitude such that a * p = q * r . the householder transformation for column k k = 1 2 ... min ( m n ) is of the form the subroutine statement is m is a positive integer input variable set to the number of rows of a . n is a positive integer input variable set to the number of columns of a . a is an m by n array . on input a contains the matrix for which the qr factorization is to be computed . on output the strict upper trapezoidal part of a contains the strict upper trapezoidal part of r and the lower trapezoidal part of a contains a factored form of q ( the non - trivial elements of the u vectors described above ) . lda is a positive integer input variable not less than m which specifies the leading dimension of the array a . pivot is a logical input variable . if pivot is set true then column pivoting is enforced . if pivot is set false then no column pivoting is done . ipvt is an integer output array of length lipvt . ipvt defines the permutation matrix p such that a * p = q * r . column j of p is column ipvt ( j ) of the identity matrix . if pivot is false ipvt is not referenced . lipvt is a positive integer input variable . if pivot is false then lipvt may be as small as 1 . if pivot is true then lipvt must be at least n . rdiag is an output array of length n which contains the diagonal elements of r . acnorm is an output array of length n which contains the norms of the corresponding columns of the input matrix a . if this information is not needed then acnorm can coincide with rdiag . wa is a work array of length n . if pivot is false then wa can coincide with rdiag .
fn qrfac(&mut self) {
        // Compute the QR factorization of the jacobian
        // compute the initial column norms and initialize several arrays.
        for (j, ij) in (0..self.nfree).zip((0..self.m * self.nfree).step_by(self.m)) {
            self.wa2[j] = self.fjac[ij..ij + self.m].enorm();
            self.wa1[j] = self.wa2[j];
            self.wa3[j] = self.wa1[j];
            self.ipvt[j] = j;
        }
        // reduce a to r with householder transformations.
        for j in 0..self.m.min(self.nfree) {
            // bring the column of largest norm into the pivot position.
            let mut kmax = j;
            for k in j..self.nfree {
                if self.wa1[k] > self.wa1[kmax] {
                    kmax = k;
                }
            }
            if kmax != j {
                let mut ij = self.m * j;
                let mut jj = self.m * kmax;
                for _ in 0..self.m {
                    self.fjac.swap(jj, ij);
                    ij += 1;
                    jj += 1;
                }
                self.wa1[kmax] = self.wa1[j];
                self.wa3[kmax] = self.wa3[j];
                self.ipvt.swap(j, kmax);
            }
            let jj = j + self.m * j;
            let jjj = self.m - j + jj;
            let mut ajnorm = self.fjac[jj..jjj].enorm();
            if ajnorm == 0. {
                self.wa1[j] = -ajnorm;
                continue;
            }
            if self.fjac[jj] < 0. {
                ajnorm = -ajnorm;
            }
            for fjac in self.fjac[jj..jjj].iter_mut() {
                *fjac /= ajnorm;
            }
            self.fjac[jj] += 1.;
            // apply the transformation to the remaining columns
            // and update the norms.
            let jp1 = j + 1;
            if jp1 < self.nfree {
                for k in jp1..self.nfree {
                    let mut sum = 0.;
                    let mut ij = j + self.m * k;
                    let mut jj = j + self.m * j;
                    for _ in j..self.m {
                        sum += self.fjac[jj] * self.fjac[ij];
                        ij += 1;
                        jj += 1;
                    }
                    let temp = sum / self.fjac[j + self.m * j];
                    ij = j + self.m * k;
                    jj = j + self.m * j;
                    for _ in j..self.m {
                        self.fjac[ij] -= temp * self.fjac[jj];
                        ij += 1;
                        jj += 1;
                    }
                    if self.wa1[k] != 0. {
                        let temp = self.fjac[j + self.m * k] / self.wa1[k];
                        let temp = (1. - temp.powi(2)).max(0.);
                        self.wa1[k] *= temp.sqrt();
                        let temp = self.wa1[k] / self.wa3[k];
                        if 0.05 * temp * temp < f64::EPSILON {
                            let start = jp1 + self.m * k;
                            self.wa1[k] = self.fjac[start..start + self.m - j - 1].enorm();
                            self.wa3[k] = self.wa1[k];
                        }
                    }
                }
            }
            self.wa1[j] = -ajnorm;
        }
    }
fn qrfac ( & mut self ) { // Compute the QR factorization of the jacobian // compute the initial column norms and initialize several arrays. for ( j , ij ) in ( 0 .. self . nfree ) . zip ( ( 0 .. self . m * self . nfree ) . step_by ( self . m ) ) { self . wa2 [ j ] = self . fjac [ ij .. ij + self . m ] . enorm ( ) ; self . wa1 [ j ] = self . wa2 [ j ] ; self . wa3 [ j ] = self . wa1 [ j ] ; self . ipvt [ j ] = j ; } // reduce a to r with householder transformations. for j in 0 .. self . m . min ( self . nfree ) { // bring the column of largest norm into the pivot position. let mut kmax = j ; for k in j .. self . nfree { if self . wa1 [ k ] > self . wa1 [ kmax ] { kmax = k ; } } if kmax != j { let mut ij = self . m * j ; let mut jj = self . m * kmax ; for _ in 0 .. self . m { self . fjac . swap ( jj , ij ) ; ij += 1 ; jj += 1 ; } self . wa1 [ kmax ] = self . wa1 [ j ] ; self . wa3 [ kmax ] = self . wa3 [ j ] ; self . ipvt . swap ( j , kmax ) ; } let jj = j + self . m * j ; let jjj = self . m - j + jj ; let mut ajnorm = self . fjac [ jj .. jjj ] . enorm ( ) ; if ajnorm == 0. { self . wa1 [ j ] = - ajnorm ; continue ; } if self . fjac [ jj ] < 0. { ajnorm = - ajnorm ; } for fjac in self . fjac [ jj .. jjj ] . iter_mut ( ) { * fjac /= ajnorm ; } self . fjac [ jj ] += 1. ; // apply the transformation to the remaining columns // and update the norms. let jp1 = j + 1 ; if jp1 < self . nfree { for k in jp1 .. self . nfree { let mut sum = 0. ; let mut ij = j + self . m * k ; let mut jj = j + self . m * j ; for _ in j .. self . m { sum += self . fjac [ jj ] * self . fjac [ ij ] ; ij += 1 ; jj += 1 ; } let temp = sum / self . fjac [ j + self . m * j ] ; ij = j + self . m * k ; jj = j + self . m * j ; for _ in j .. self . m { self . fjac [ ij ] -= temp * self . fjac [ jj ] ; ij += 1 ; jj += 1 ; } if self . wa1 [ k ] != 0. { let temp = self . fjac [ j + self . m * k ] / self . wa1 [ k ] ; let temp = ( 1. - temp . powi ( 2 ) ) . max ( 0. ) ; self . wa1 [ k ] *= temp . sqrt ( ) ; let temp = self . wa1 [ k ] / self . wa3 [ k ] ; if 0.05 * temp * temp < f64 :: EPSILON { let start = jp1 + self . m * k ; self . wa1 [ k ] = self . fjac [ start .. start + self . m - j - 1 ] . enorm ( ) ; self . wa3 [ k ] = self . wa1 [ k ] ; } } } } self . wa1 [ j ] = - ajnorm ; } }
subroutine qrfac
this subroutine uses householder transformations with column pivoting
(optional) to compute a qr factorization of the m by n matrix a. that
is, qrfac determines an orthogonal matrix q, a permutation matrix p, and
an upper trapezoidal matrix r with diagonal elements of nonincreasing
magnitude, such that a*p = q*r. the householder transformation for
column k, k = 1,2,...,min(m,n), is of the form
subroutine qrfac this subroutine uses householder transformations with column pivoting ( optional ) to compute a qr factorization of the m by n matrix a . that is qrfac determines an orthogonal matrix q a permutation matrix p and an upper trapezoidal matrix r with diagonal elements of nonincreasing magnitude such that a * p = q * r . the householder transformation for column k k = 1 2 ... min ( m n ) is of the form
&mut self
&mut self