public static Scsn cs_qr(Scs A, Scss S) {
        float Rx[], Vx[], Ax[], x[], Beta[];
        int i, k, p, n, vnz, p1, top, m2, len, col, rnz, s[], leftmost[], Ap[], Ai[], parent[], Rp[], Ri[], Vp[], Vi[], w[], pinv[], q[];
        Scs R, V;
        Scsn N;
        if (!Scs_util.CS_CSC(A) || S == null)
            return (null);
        n = A.n;
        Ap = A.p;
        Ai = A.i;
        Ax = A.x;
        q = S.q;
        parent = S.parent;
        pinv = S.pinv;
        m2 = S.m2;
        vnz = S.lnz;
        rnz = S.unz;
        leftmost = S.leftmost;
        w = new int[m2 + n]; /* get int workspace */
        x = new float[m2]; /* get float workspace */
        N = new Scsn(); /* allocate result */
        s = w;
        int s_offset = m2; /* s is size n */
        for (k = 0; k < m2; k++)
            x[k] = 0; /* clear workspace x */
        N.L = V = Scs_util.cs_spalloc(m2, n, vnz, true, false); /* allocate result V */
        N.U = R = Scs_util.cs_spalloc(m2, n, rnz, true, false); /* allocate result R */
        N.B = Beta = new float[n]; /* allocate result Beta */
        Rp = R.p;
        Ri = R.i;
        Rx = R.x;
        Vp = V.p;
        Vi = V.i;
        Vx = V.x;
        for (i = 0; i < m2; i++)
            w[i] = -1; /* clear w, to mark nodes */
        rnz = 0;
        vnz = 0;
        for (k = 0; k < n; k++) /* compute V and R */
        {
            Rp[k] = rnz; /* R(:,k) starts here */
            Vp[k] = p1 = vnz; /* V(:,k) starts here */
            w[k] = k; /* add V(k,k) to pattern of V */
            Vi[vnz++] = k;
            top = n;
            col = q != null ? q[k] : k;
            for (p = Ap[col]; p < Ap[col + 1]; p++) /* find R(:,k) pattern */
            {
                i = leftmost[Ai[p]]; /* i = min(find(A(i,q))) */
                for (len = 0; w[i] != k; i = parent[i]) /* traverse up to k */
                {
                    s[s_offset + (len++)] = i;
                    w[i] = k;
                }
                while (len > 0)
                    s[s_offset + (--top)] = s[s_offset + (--len)]; /* push path on stack */
                i = pinv[Ai[p]]; /* i = permuted row of A(:,col) */
                x[i] = Ax[p]; /* x (i) = A(:,col) */
                if (i > k && w[i] < k) /* pattern of V(:,k) = x (k+1:m) */
                {
                    Vi[vnz++] = i; /* add i to pattern of V(:,k) */
                    w[i] = k;
                }
            }
            for (p = top; p < n; p++) /* for each i in pattern of R(:,k) */
            {
                i = s[s_offset + p]; /* R(i,k) is nonzero */
                Scs_happly.cs_happly(V, i, Beta[i], x); /* apply (V(i),Beta(i)) to x */
                Ri[rnz] = i; /* R(i,k) = x(i) */
                Rx[rnz++] = x[i];
                x[i] = 0;
                if (parent[i] == k)
                    vnz = Scs_scatter.cs_scatter(V, i, 0, w, null, k, V, vnz);
            }
            for (p = p1; p < vnz; p++) /* gather V(:,k) = x */
            {
                Vx[p] = x[Vi[p]];
                x[Vi[p]] = 0;
            }
            Ri[rnz] = k; /* R(k,k) = norm (x) */
            float[] beta = new float[1];
            beta[0] = Beta[k];
            Rx[rnz++] = Scs_house.cs_house(Vx, p1, beta, vnz - p1); /* [v,beta]=house(x) */
            Beta[k] = beta[0];
        }
        Rp[n] = rnz; /* finalize R */
        Vp[n] = vnz; /* finalize V */
        return N;
    }
public static Scsn cs_qr ( Scs A , Scss S ) { float Rx [ ] , Vx [ ] , Ax [ ] , x [ ] , Beta [ ] ; int i , k , p , n , vnz , p1 , top , m2 , len , col , rnz , s [ ] , leftmost [ ] , Ap [ ] , Ai [ ] , parent [ ] , Rp [ ] , Ri [ ] , Vp [ ] , Vi [ ] , w [ ] , pinv [ ] , q [ ] ; Scs R , V ; Scsn N ; if ( ! Scs_util . CS_CSC ( A ) || S == null ) return ( null ) ; n = A . n ; Ap = A . p ; Ai = A . i ; Ax = A . x ; q = S . q ; parent = S . parent ; pinv = S . pinv ; m2 = S . m2 ; vnz = S . lnz ; rnz = S . unz ; leftmost = S . leftmost ; w = new int [ m2 + n ] ; x = new float [ m2 ] ; N = new Scsn ( ) ; s = w ; int s_offset = m2 ; for ( k = 0 ; k < m2 ; k ++ ) x [ k ] = 0 ; N . L = V = Scs_util . cs_spalloc ( m2 , n , vnz , true , false ) ; N . U = R = Scs_util . cs_spalloc ( m2 , n , rnz , true , false ) ; N . B = Beta = new float [ n ] ; Rp = R . p ; Ri = R . i ; Rx = R . x ; Vp = V . p ; Vi = V . i ; Vx = V . x ; for ( i = 0 ; i < m2 ; i ++ ) w [ i ] = - 1 ; rnz = 0 ; vnz = 0 ; for ( k = 0 ; k < n ; k ++ ) { Rp [ k ] = rnz ; Vp [ k ] = p1 = vnz ; w [ k ] = k ; Vi [ vnz ++ ] = k ; top = n ; col = q != null ? q [ k ] : k ; for ( p = Ap [ col ] ; p < Ap [ col + 1 ] ; p ++ ) { i = leftmost [ Ai [ p ] ] ; for ( len = 0 ; w [ i ] != k ; i = parent [ i ] ) { s [ s_offset + ( len ++ ) ] = i ; w [ i ] = k ; } while ( len > 0 ) s [ s_offset + ( -- top ) ] = s [ s_offset + ( -- len ) ] ; i = pinv [ Ai [ p ] ] ; x [ i ] = Ax [ p ] ; if ( i > k && w [ i ] < k ) { Vi [ vnz ++ ] = i ; w [ i ] = k ; } } for ( p = top ; p < n ; p ++ ) { i = s [ s_offset + p ] ; Scs_happly . cs_happly ( V , i , Beta [ i ] , x ) ; Ri [ rnz ] = i ; Rx [ rnz ++ ] = x [ i ] ; x [ i ] = 0 ; if ( parent [ i ] == k ) vnz = Scs_scatter . cs_scatter ( V , i , 0 , w , null , k , V , vnz ) ; } for ( p = p1 ; p < vnz ; p ++ ) { Vx [ p ] = x [ Vi [ p ] ] ; x [ Vi [ p ] ] = 0 ; } Ri [ rnz ] = k ; float [ ] beta = new float [ 1 ] ; beta [ 0 ] = Beta [ k ] ; Rx [ rnz ++ ] = Scs_house . cs_house ( Vx , p1 , beta , vnz - p1 ) ; Beta [ k ] = beta [ 0 ] ; } Rp [ n ] = rnz ; Vp [ n ] = vnz ; return N ; }
Sparse QR factorization of an m-by-n matrix A, A= Q*R

@param A
column-compressed matrix
@param S
symbolic QR analysis
@return numeric QR factorization, null on error