void qr_solve(double x[], int m, int n, double a[], double b[]) /******************************************************************************/ /* Purpose: QR_SOLVE solves a linear system in the least squares sense. Discussion: If the matrix A has full column rank, then the solution X should be the unique vector that minimizes the Euclidean norm of the residual. If the matrix A does not have full column rank, then the solution is not unique; the vector X will minimize the residual norm, but so will various other vectors. Licensing: This code is distributed under the GNU LGPL license. Modified: 11 September 2012 Author: John Burkardt Reference: David Kahaner, Cleve Moler, Steven Nash, Numerical Methods and Software, Prentice Hall, 1989, ISBN: 0-13-627258-4, LC: TA345.K34. Parameters: Input, int M, the number of rows of A. Input, int N, the number of columns of A. Input, double A[M*N], the matrix. Input, double B[M], the right hand side. Output, double QR_SOLVE[N], the least squares solution. */ { double a_qr[n * m], qraux[n], r[m], tol; int ind, itask, jpvt[n], kr, lda; r8mat_copy(a_qr, m, n, a); lda = m; tol = r8_epsilon() / r8mat_amax(m, n, a_qr); itask = 1; ind = dqrls(a_qr, lda, m, n, tol, &kr, b, x, r, jpvt, qraux, itask); UNUSED(ind); }
void triangle_node_data_example ( int node_num, int node_dim, int node_att_num, int node_marker_num, double node_coord[], double node_att[], int node_marker[] ) /******************************************************************************/ /* Purpose: TRIANGLE_NODE_DATA_EXAMPLE returns the node information for the example. Licensing: This code is distributed under the GNU LGPL license. Modified: 09 November 2010 Author: John Burkardt Parameters: Input, int NODE_NUM, the number of nodes. Input, int NODE_DIM, the spatial dimension. Input, int NODE_ATT_NUM, number of node attributes listed on each node record. Input, int NODE_MARKER_NUM, 1 if every node record includes a final boundary marker value. Output, double NODE_COORD[NODE_DIM*NODE_NUM], the nodal coordinates. Output, double NODE_ATT[NODE_ATT_NUM*NODE_NUM], the nodal attributes. Output, int NODE_MARKER[NODE_MARKER_NUM*NODE_NUM], the node markers. */ { double node_coord_save[2*21] = { 0.0, 0.0, 1.0, 0.0, 2.0, 0.0, 3.0, 0.0, 4.0, 0.0, 0.0, 1.0, 1.0, 1.0, 2.0, 1.0, 3.0, 1.0, 4.0, 1.0, 0.0, 2.0, 1.0, 2.0, 2.0, 2.0, 3.0, 2.0, 4.0, 2.0, 0.0, 3.0, 1.0, 3.0, 2.0, 3.0, 0.0, 4.0, 1.0, 4.0, 2.0, 4.0 }; int node_marker_save[21] = { 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1 }; r8mat_copy ( 2, 21, node_coord_save, node_coord ); i4vec_copy ( 21, node_marker_save, node_marker ); return; }
void r8mat_orth_uniform ( int n, int *seed, double a[] ) /******************************************************************************/ /* Purpose: R8MAT_ORTH_UNIFORM returns a random orthogonal matrix. Discussion: An R8MAT is a doubly dimensioned array of R8 values, stored as a vector in column-major order. The inverse of A is equal to A'. A * A' = A' * A = I. Columns and rows of A have unit Euclidean norm. Distinct pairs of columns of A are orthogonal. Distinct pairs of rows of A are orthogonal. The L2 vector norm of A*x = the L2 vector norm of x for any vector x. The L2 matrix norm of A*B = the L2 matrix norm of B for any matrix B. The determinant of A is +1 or -1. All the eigenvalues of A have modulus 1. All singular values of A are 1. All entries of A are between -1 and 1. Discussion: Thanks to Eugene Petrov, B I Stepanov Institute of Physics, National Academy of Sciences of Belarus, for convincingly pointing out the severe deficiencies of an earlier version of this routine. Essentially, the computation involves saving the Q factor of the QR factorization of a matrix whose entries are normally distributed. However, it is only necessary to generate this matrix a column at a time, since it can be shown that when it comes time to annihilate the subdiagonal elements of column K, these (transformed) elements of column K are still normally distributed random values. Hence, there is no need to generate them at the beginning of the process and transform them K-1 times. For computational efficiency, the individual Householder transformations could be saved, as recommended in the reference, instead of being accumulated into an explicit matrix format. Licensing: This code is distributed under the GNU LGPL license. Modified: 26 August 2011 Author: John Burkardt Reference: Pete Stewart, Efficient Generation of Random Orthogonal Matrices With an Application to Condition Estimators, SIAM Journal on Numerical Analysis, Volume 17, Number 3, June 1980, pages 403-409. Parameters: Input, int N, the order of A. Input/output, int *SEED, a seed for the random number generator. Output, double A[N*N], the orthogonal matrix. */ { double *a2; int i; int j; double *v; double *x; /* Start with A = the identity matrix. */ r8mat_identity ( n, a ); /* Now behave as though we were computing the QR factorization of some other random matrix. Generate the N elements of the first column, compute the Householder matrix H1 that annihilates the subdiagonal elements, and set A := A * H1' = A * H. On the second step, generate the lower N-1 elements of the second column, compute the Householder matrix H2 that annihilates them, and set A := A * H2' = A * H2 = H1 * H2. On the N-1 step, generate the lower 2 elements of column N-1, compute the Householder matrix HN-1 that annihilates them, and and set A := A * H(N-1)' = A * H(N-1) = H1 * H2 * ... * H(N-1). This is our random orthogonal matrix. */ x = ( double * ) malloc ( n * sizeof ( double ) ); for ( j = 1; j < n; j++ ) { /* Set the vector that represents the J-th column to be annihilated. */ for ( i = 1; i < j; i++ ) { x[i-1] = 0.0; } for ( i = j; i <= n; i++ ) { x[i-1] = r8_normal_01 ( seed ); } /* Compute the vector V that defines a Householder transformation matrix H(V) that annihilates the subdiagonal elements of X. */ v = r8vec_house_column ( n, x, j ); /* Postmultiply the matrix A by H'(V) = H(V). */ a2 = r8mat_house_axh_new ( n, a, v ); free ( v ); r8mat_copy ( n, n, a2, a ); free ( a2 ); } free ( x ); return; }