📄 sqr.c
字号:
/* Copyright (c) Colorado School of Mines, 1990./* All rights reserved. *//*****************************************************************************Single precision QR decomposition functions adapted from LINPACK FORTRAN:sqrdc Compute QR decomposition of a matrix.sqrsl Use QR decomposition to solve for coordinate transformations, projections, and least squares solutions.sqrst Solve under-determined or over-determined least squares problems, with a user-specified tolerance.!!! WARNING !!!These functions have many options, not all of which have been tested!(Dave Hale, 12/31/89)*****************************************************************************/#include "cwp.h"voidsqrdc (float **x, int n, int p, float *qraux, int *jpvt, float *work, int job)/*****************************************************************************Use Householder transformations to compute the QR decomposition of an n by pmatrix x. Column pivoting based on the 2-norms of the reduced columns may beperformed at the user's option.******************************************************************************Input:x matrix[p][n] to decompose (see notes below)n number of rows in the matrix xp number of columns in the matrix xjpvt array[p] controlling the pivot columns (see notes below)job =0 for no pivoting; =1 for pivotingOutput:x matrix[p][n] decomposed (see notes below)qraux array[p] containing information required to recover the orthogonal part of the decompositionjpvt array[p] with jpvt[k] containing the index of the original matrix that has been interchanged into the k-th column, if pivoting is requested.Workspace:work array[p] of workspace******************************************************************************Notes:This function was adapted from LINPACK FORTRAN. Because two-dimensional arrays cannot be declared with variable dimensions in C, the matrix xis actually a pointer to an array of pointers to floats, as declaredabove and used below.Elements of x are stored as follows:x[0][0] x[1][0] x[2][0] ... x[p-1][0]x[0][1] x[1][1] x[2][1] ... x[p-1][1]x[0][2] x[1][2] x[2][2] ... x[p-1][2]. .. . .. . .. .x[0][n-1] x[1][n-1] x[2][n-1] ... x[p-1][n-1]After decomposition, x contains in its upper triangular matrix R of the QRdecomposition. Below its diagonal x contains information from which theorthogonal part of the decomposition can be recovered. Note that ifpivoting has been requested, the decomposition is not that of the originalmatrix x but that of x with its columns permuted as described by jpvt.The selection of pivot columns is controlled by jpvt as follows.The k-th column x[k] of x is placed in one of three classes according tothe value of jpvt[k]. if jpvt[k] > 0, then x[k] is an initial column. if jpvt[k] == 0, then x[k] is a free column. if jpvt[k] < 0, then x[k] is a final column.Before the decomposition is computed, initial columns are moved to thebeginning of the array x and final columns to the end. Both initial andfinal columns are frozen in place during the computation and only freecolumns are moved. At the k-th stage of the reduction, if x[k] is occupiedby a free column it is interchanged with the free column of largest reducednorm. jpvt is not referenced if job == 0.******************************************************************************Author: Dave Hale, Colorado School of Mines, 12/29/89*****************************************************************************/{ int j,jp,l,lup,maxj,pl,pu,negj,swapj; float maxnrm,t,tt,ttt,nrmxl; pl = 0; pu = -1; /* if pivoting has been requested */ if (job!=0) { /* rearrange columns according to jpvt */ for (j=0; j<p; j++) { swapj = jpvt[j]>0; negj = jpvt[j]<0; jpvt[j] = j; if (negj) jpvt[j] = -j; if (swapj) { if (j!=pl) sswap(n,x[pl],1,x[j],1); jpvt[j] = jpvt[pl]; jpvt[pl] = j; pl++; } } pu = p-1; for (j=p-1; j>=0; j--) { if (jpvt[j]<0) { jpvt[j] = -jpvt[j]; if (j!=pu) { sswap(n,x[pu],1,x[j],1); jp = jpvt[pu]; jpvt[pu] = jpvt[j]; jpvt[j] = jp; } pu--; } } } /* compute the norms of the free columns */ for (j=pl; j<=pu; j++) { qraux[j] = snrm2(n,x[j],1); work[j] = qraux[j]; } /* perform the Householder reduction of x */ lup = MIN(n,p); for (l=0; l<lup; l++) { if (l>=pl && l<pu) { /* * locate the column of largest norm and * bring it into pivot position. */ maxnrm = 0.0; maxj = l; for (j=l; j<=pu; j++) { if (qraux[j]>maxnrm) { maxnrm = qraux[j]; maxj = j; } } if (maxj!=l) { sswap(n,x[l],1,x[maxj],1); qraux[maxj] = qraux[l]; work[maxj] = work[l]; jp = jpvt[maxj]; jpvt[maxj] = jpvt[l]; jpvt[l] = jp; } } qraux[l] = 0.0; if (l!=n-1) { /* * compute the Householder transformation * for column l */ nrmxl = snrm2(n-l,&x[l][l],1); if (nrmxl!=0.0) { if (x[l][l]!=0.0) nrmxl = (x[l][l]>0.0) ? ABS(nrmxl) : -ABS(nrmxl); sscal(n-l,1.0/nrmxl,&x[l][l],1); x[l][l] += 1.0; /* * apply the transformation to the remaining * columns, updating the norms */ for (j=l+1; j<p; j++) { t = -sdot(n-l,&x[l][l],1,&x[j][l],1)/ x[l][l]; saxpy(n-l,t,&x[l][l],1,&x[j][l],1); if (j>=pl && j<=pu && qraux[j]!=0.0) { tt = ABS(x[j][l])/qraux[j]; tt = 1.0-tt*tt; tt = MAX(tt,0.0); t = tt; ttt = qraux[j]/work[j]; tt = 1.0+0.05*tt*ttt*ttt; if (tt!=1.0) { qraux[j] *= sqrt(t); } else { qraux[j] = snrm2(n-l-1, &x[j][l+1],1); work[j] = qraux[j]; } } } /* save the transformation */ qraux[l] = x[l][l]; x[l][l] = -nrmxl; } } }} voidsqrsl (float **x, int n, int k, float *qraux, float *y, float *qy, float *qty, float *b, float *rsd, float *xb, int job, int *info)/*****************************************************************************Use the output of sqrdc to compute coordinate transformations, projections,and least squares solutions. For k <= MIN(n,p), let xk be the matrix xk = (x[jpvt[0]], x[jpvt[1]], ..., x[jpvt[k-1]])formed from columns jpvt[0], jpvt[1], ..., jpvt[k-1] of the originaln by p matrix x that was input to sqrdc. (If no pivoting was done, xkconsists of the first k columns of x in their original order.) sqrdcproduces a factored orthogonal matrix Q and an upper triangular matrix Rsuch that xk = Q * (R) (0)This information is contained in coded form in the arrays x and qraux.******************************************************************************Input:x matrix[p][n] containing output of sqrdc.n number of rows in the matrix xk; same as in sqrdc.k number of columns in the matrix xk; k must not be greater than MIN(n,p), where p is the same as in sqrdc.qraux array[p] containing auxiliary output from sqrdc.y array[n] to be manipulated by sqrsl.job specifies what is to be computed. job has the decimal expansion ABCDE, with the following meaning: if A != 0, compute qy. if B, C, D, or E != 0, compute qty. if C != 0, compute b. if D != 0, compute rsd. if E != 0, compute xb. Note that a request to compute b, rsd, or xb automatically triggers the computation of qty, for which an array must be provided.Output:qy array[n] containing Qy, if its computation has been requested.qty array[n] containing Q'y, if its computation has been requested. Here Q' denotes the transpose of Q.b array[k] containing solution of the least squares problem: minimize norm2(y - xk*b), if its computation has been requested. (Note that if pivoting was requested in sqrdc, the j-th component of b will be associated with column jpvt[j] of the original matrix x that was input into sqrdc.)rsd array[n] containing the least squares residual y - xk*b,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -