private static boolean cs_vcount(Dcs A, Dcss S) {
        int i, k, p, pa, n = A.n, m = A.m, Ap[] = A.p, Ai[] = A.i, next[], head[], tail[], nque[], pinv[], leftmost[], w[], parent[] = S.parent;
        S.pinv = pinv = new int[m + n]; /* allocate pinv, */
        S.leftmost = leftmost = new int[m]; /* and leftmost */
        w = new int[m + 3 * n]; /* get workspace */
        next = w;
        head = w;
        int head_offset = m;
        tail = w;
        int tail_offset = m + n;
        nque = w;
        int nque_offset = m + 2 * n;
        for (k = 0; k < n; k++)
            head[head_offset + k] = -1; /* queue k is empty */
        for (k = 0; k < n; k++)
            tail[tail_offset + k] = -1;
        for (k = 0; k < n; k++)
            nque[nque_offset + k] = 0;
        for (i = 0; i < m; i++)
            leftmost[i] = -1;
        for (k = n - 1; k >= 0; k--) {
            for (p = Ap[k]; p < Ap[k + 1]; p++) {
                leftmost[Ai[p]] = k; /* leftmost[i] = min(find(A(i,:)))*/
            }
        }
        for (i = m - 1; i >= 0; i--) /* scan rows in reverse order */
        {
            pinv[i] = -1; /* row i is not yet ordered */
            k = leftmost[i];
            if (k == -1)
                continue; /* row i is empty */
            if (nque[nque_offset + k]++ == 0)
                tail[tail_offset + k] = i; /* first row in queue k */
            next[i] = head[head_offset + k]; /* put i at head of queue k */
            head[head_offset + k] = i;
        }
        S.lnz = 0;
        S.m2 = m;
        for (k = 0; k < n; k++) /* find row permutation and nnz(V)*/
        {
            i = head[head_offset + k]; /* remove row i from queue k */
            S.lnz++; /* count V(k,k) as nonzero */
            if (i < 0)
                i = S.m2++; /* add a fictitious row */
            pinv[i] = k; /* associate row i with V(:,k) */
            if (--nque[nque_offset + k] <= 0)
                continue; /* skip if V(k+1:m,k) is empty */
            S.lnz += nque[nque_offset + k]; /* nque [nque_offset+k] is nnz (V(k+1:m,k)) */
            if ((pa = parent[k]) != -1) /* move all rows to parent of k */
            {
                if (nque[nque_offset + pa] == 0)
                    tail[tail_offset + pa] = tail[tail_offset + k];
                next[tail[tail_offset + k]] = head[head_offset + pa];
                head[head_offset + pa] = next[i];
                nque[nque_offset + pa] += nque[nque_offset + k];
            }
        }
        for (i = 0; i < m; i++)
            if (pinv[i] < 0)
                pinv[i] = k++;
        w = null;
        return (true);
    }
private static boolean cs_vcount ( Dcs A , Dcss S ) { int i , k , p , pa , n = A . n , m = A . m , Ap [ ] = A . p , Ai [ ] = A . i , next [ ] , head [ ] , tail [ ] , nque [ ] , pinv [ ] , leftmost [ ] , w [ ] , parent [ ] = S . parent ; S . pinv = pinv = new int [ m + n ] ; S . leftmost = leftmost = new int [ m ] ; w = new int [ m + 3 * n ] ; next = w ; head = w ; int head_offset = m ; tail = w ; int tail_offset = m + n ; nque = w ; int nque_offset = m + 2 * n ; for ( k = 0 ; k < n ; k ++ ) head [ head_offset + k ] = - 1 ; for ( k = 0 ; k < n ; k ++ ) tail [ tail_offset + k ] = - 1 ; for ( k = 0 ; k < n ; k ++ ) nque [ nque_offset + k ] = 0 ; for ( i = 0 ; i < m ; i ++ ) leftmost [ i ] = - 1 ; for ( k = n - 1 ; k >= 0 ; k -- ) { for ( p = Ap [ k ] ; p < Ap [ k + 1 ] ; p ++ ) { leftmost [ Ai [ p ] ] = k ; } } for ( i = m - 1 ; i >= 0 ; i -- ) { pinv [ i ] = - 1 ; k = leftmost [ i ] ; if ( k == - 1 ) continue ; if ( nque [ nque_offset + k ] ++ == 0 ) tail [ tail_offset + k ] = i ; next [ i ] = head [ head_offset + k ] ; head [ head_offset + k ] = i ; } S . lnz = 0 ; S . m2 = m ; for ( k = 0 ; k < n ; k ++ ) { i = head [ head_offset + k ] ; S . lnz ++ ; if ( i < 0 ) i = S . m2 ++ ; pinv [ i ] = k ; if ( -- nque [ nque_offset + k ] <= 0 ) continue ; S . lnz += nque [ nque_offset + k ] ; if ( ( pa = parent [ k ] ) != - 1 ) { if ( nque [ nque_offset + pa ] == 0 ) tail [ tail_offset + pa ] = tail [ tail_offset + k ] ; next [ tail [ tail_offset + k ] ] = head [ head_offset + pa ] ; head [ head_offset + pa ] = next [ i ] ; nque [ nque_offset + pa ] += nque [ nque_offset + k ] ; } } for ( i = 0 ; i < m ; i ++ ) if ( pinv [ i ] < 0 ) pinv [ i ] = k ++ ; w = null ; return ( true ) ; }
/* compute nnz(V) = S->lnz, S->pinv, S->leftmost, S->m2 from A and S->parent