void dqrank(double a[], int lda, int m, int n, double tol, int* kr, int jpvt[], double qraux[]) /******************************************************************************/ /* Purpose: DQRANK computes the QR factorization of a rectangular matrix. Discussion: This routine is used in conjunction with DQRLSS to solve overdetermined, underdetermined and singular linear systems in a least squares sense. DQRANK uses the LINPACK subroutine DQRDC to compute the QR factorization, with column pivoting, of an M by N matrix A. The numerical rank is determined using the tolerance TOL. Note that on output, ABS ( A(1,1) ) / ABS ( A(KR,KR) ) is an estimate of the condition number of the matrix of independent columns, and of R. This estimate will be <= 1/TOL. Licensing: This code is distributed under the GNU LGPL license. Modified: 21 April 2012 Author: C version by John Burkardt. Reference: Jack Dongarra, Cleve Moler, Jim Bunch, Pete Stewart, LINPACK User's Guide, SIAM, 1979, ISBN13: 978-0-898711-72-1, LC: QA214.L56. Parameters: Input/output, double A[LDA*N]. On input, the matrix whose decomposition is to be computed. On output, the information from DQRDC. The triangular matrix R of the QR factorization is contained in the upper triangle and information needed to recover the orthogonal matrix Q is stored below the diagonal in A and in the vector QRAUX. Input, int LDA, the leading dimension of A, which must be at least M. Input, int M, the number of rows of A. Input, int N, the number of columns of A. Input, double TOL, a relative tolerance used to determine the numerical rank. The problem should be scaled so that all the elements of A have roughly the same absolute accuracy, EPS. Then a reasonable value for TOL is roughly EPS divided by the magnitude of the largest element. Output, int *KR, the numerical rank. Output, int JPVT[N], the pivot information from DQRDC. Columns JPVT(1), ..., JPVT(KR) of the original matrix are linearly independent to within the tolerance TOL and the remaining columns are linearly dependent. Output, double QRAUX[N], will contain extra information defining the QR factorization. */ { double work[n]; for (int i = 0; i < n; i++) jpvt[i] = 0; int job = 1; dqrdc(a, lda, m, n, qraux, jpvt, work, job); *kr = 0; int k = i4_min(m, n); for (int j = 0; j < k; j++) { if (r8_abs(a[j + j * lda]) <= tol * r8_abs(a[0 + 0 * lda])) return; *kr = j + 1; } }
int pdsdgn(int ndim, double *s, double *a, double *work1, double *qraux, int *jpvt, double *rcond) { /******************************************************************* * * Parameters * * Input * * N dimension of the problem to be solved * * S two-dimensional array containing the vertex * specified by the user to begin the search * (as well as the remaining N vertices of the * initial simplex if they have already been * entered by the user) * * A workspace vector of length N*N to hold the * adjacency matrix, if needed * * WORK1 workspace vector of length N used as * auxiliary storage during the QR * decomposition * * QRAUX workspace vector of length N used as * auxiliary storage during the QR * decomposition * * JPVT workspace vector of length N to control * pivoting during the QR decomposition * Output * * RCOND an estimate of the inverse of the condition * number of the adjacency matrix. This should * give some warning as to whether or not the * initial simplex is degenerate. * *******************************************************************/ /* Local variables */ static int i, j, k; /* Form the matrix of edges adjacent to the initial vertex. */ static int one = 1; for (j = 0; j < ndim; j++) { k = j + 1; for (i = 0; i < ndim; i++) { a[i + j * ndim] = s[i + k * ndim] - s[i]; } jpvt[j] = 0; } /* Call QR with pivoting. */ dqrdc(a, ndim, ndim, ndim, qraux, jpvt, work1, one); *rcond = fabs(a[ndim - 1 + (ndim-1)*ndim]) / fabs(a[0]); return 0; }