(FILECREATED "29-May-86 12:41:55" {QV}<PEDERSEN>LISP>OTHERMATRIXOPS.;2 19199 changes to: (VARS OTHERMATRIXOPSCOMS) (FNS SVDNASH) previous date: "27-May-86 22:00:09" {QV}<PEDERSEN>LISP>OTHERMATRIXOPS.;1) (* Copyright (c) 1986 by Xerox Corporation. All rights reserved.) (PRETTYCOMPRINT OTHERMATRIXOPSCOMS) (RPAQQ OTHERMATRIXOPSCOMS ((* File created by Coms Manager.) (FNS DIAGXTXINVERSE OLSMGS QRMGS SVDNASH))) (* File created by Coms Manager.) (DEFINEQ (DIAGXTXINVERSE [LAMBDA (R D) (* jop: " 3-Feb-86 15:41") (* * Return (as the P vector D) the diagonal elements of the matrix (R-transpose R) Inverse, where R is P x P upper triangular with non-zero diagonal elements. When the decomposition X=Q*R has been formed, these diagonal elements are just those of (X-transpose X) Inverse (mathematically)%. Notice that the vector D must be created by the CALLER!) (BLAS.CHECKARRAY R) (BLAS.CHECKARRAY D) (PROG [(P (ARRAY-DIMENSION R 0)) (C (MAKE-ARRAY (ARRAY-DIMENSION R 0) (QUOTE :ELEMENT-TYPE) (QUOTE FLOAT] (* * Check args) (if (NOT (IEQP P (ARRAY-DIMENSION R 1))) then (HELP "R not P x P" R)) (if (NOT (IEQP P (ARRAY-DIMENSION D 0))) then (HELP "D not a P vector" D)) (* * The solution proceeds as a succession of back substitutions against columns of the identity matrix.) (BLAS.ARRAYFILL 0.0 D) (bind FTEMP declare (TYPE FLOATP FTEMP) for K from (SUB1 P) to 0 by -1 do (\FLOATASET (FQUOTIENT 1.0 (\FLOATAREF R K K)) C K) (SETQ FTEMP (\FLOATAREF C K)) (\FLOATASET (FPLUS (\FLOATAREF D K) (FTIMES FTEMP FTEMP)) D K) (for J from (SUB1 K) to 0 by -1 do (SETQ FTEMP 0.0) (for I from (ADD1 J) to K do [SETQ FTEMP (FDIFFERENCE FTEMP (FTIMES (\FLOATAREF R J I) (\FLOATAREF C I] finally (\FLOATASET (FQUOTIENT FTEMP (\FLOATAREF R J J)) C J)) (SETQ FTEMP (\FLOATAREF C J)) (\FLOATASET (FPLUS (\FLOATAREF D J) (FTIMES FTEMP FTEMP)) D J))) (RETURN NIL]) (OLSMGS [LAMBDA (Y X Q R B) (* jop: "27-May-86 17:08") (* * OLSMGS calculates the least squares (multiple) regression of Y on X. An N vector Y, and a N x P matrix X are required. Q is a N x P matrix containing an orthogonal basis for the column spce of X. R is an upper triangular P x P array. B is a P vector of coefficients) (PROG ((N (ARRAY-DIMENSION X 0)) (P (ARRAY-DIMENSION X 1)) C) (* * Arg checks) (if (NOT (IEQP (ARRAY-TOTAL-SIZE Y) N)) then (HELP "Y not an N vector" Y)) (if (NULL Q) then (SETQ Q (MAKE-ARRAY (ARRAY-DIMENSIONS X) (QUOTE :ELEMENT-TYPE) (QUOTE FLOAT))) elseif (NOT (EQUAL (ARRAY-DIMENSIONS Q) (ARRAY-DIMENSIONS X))) then (HELP "Q not N x P" Q)) (if (NULL R) then (SETQ R (MAKE-ARRAY (LIST P P) (QUOTE :ELEMENT-TYPE) (QUOTE FLOAT))) elseif (NOT (EQUAL (ARRAY-DIMENSIONS R) (LIST P P))) then (HELP "R not P x P" R)) (if (NULL B) then (SETQ B (MAKE-ARRAY P (QUOTE :ELEMENT-TYPE) (QUOTE FLOAT))) elseif (NOT (IEQP (ARRAY-TOTAL-SIZE R) P)) then (HELP "B not a P vector" B)) (SETQ C (MAKE-ARRAY P (QUOTE :ELEMENT-TYPE) (QUOTE FLOAT))) (* * Compute Q R decomposition) (QRMGS X Q R) (for J from 0 to (SUB1 P) do (bind (FTEMP ← 0.0) declare (TYPE FLOATP FTEMP) for I from 0 to (SUB1 N) do [SETQ FTEMP (FPLUS FTEMP (FTIMES (\FLOATAREF Q I J) (\FLOATAREF Y I] finally (\FLOATASET FTEMP C J))) (RSOLV R C B) (RETURN B]) (QRMGS [LAMBDA (X Q R) (* jop: " 3-Feb-86 16:04") (* * This function determines a decomposition X = Q*R for the rectangular CMLArray matrix X, where Q is an orthonormal basis for the column space of X and R is a square upper triangular matrix.) (* * On entry: X is an n x p CMLARRAY, i.e. a matrix, whose QR decomposition is required; Q is an n x p array; R is a p x p array) (* * On return: the value of the function is NIL for a normal return. Should this routine be unable to complete the QR decomposition of X because of near singularity of its columns, the function will have a nonNIL value; the matrix Q has been OVERWRITTEN by the orthonormal basis Q; R contains in its upper triangle the factor R from the decomposition.) (* * Algorithm notes: The method employed for the decomposition is modified-Gram-Schmidt with reorthogonalization of the columns of Q. A test relative to the machine arithmetic precision is made to recognize possible singularity of X. The decision to reorthoganalize is based on the relative decrease in column norm obtained in the Gram-Schmidt process. These ideas are due to David M. Gay. For the sake of time and space economy, this function does not perform column pivoting; this will exclude successful decomposition for only the most severely ill-conditioned problems. For the sake of time and space economy, no special precautions have been taken in the computation of inner products and vector 2-norms. Only those problems where intermediate quantities lie outside the range 10↑-19 to 10↑19 will notice difficulties, but values of these magnitudes are surely indication of very poor scaling or severe ill-conditioning.) (BLAS.CHECKARRAY X) (BLAS.CHECKARRAY Q) (BLAS.CHECKARRAY R) (PROG [(N (ARRAY-DIMENSION X 0)) (P (ARRAY-DIMENSION X 1)) (C (MAKE-ARRAY (ARRAY-DIMENSION X 1) (QUOTE :ELEMENT-TYPE) (QUOTE FLOAT] (* * Check args) (if (NOT (AND (IEQP (ARRAY-DIMENSION Q 0) N) (IEQP (ARRAY-DIMENSION Q 1) P))) then (HELP "Q not n x p" Q)) (if (NOT (AND (IEQP (ARRAY-DIMENSION R 0) P) (IEQP (ARRAY-DIMENSION R 1) P))) then (HELP "R not p x p" R)) (* * Copy X to Q) (BLAS.ARRAYBLT X 0 1 Q 0 1) (* * Initialize diagonal of R to 2-norms of columns of Q) (bind NORMXJ for J from 0 to (SUB1 P) do (SETQ NORMXJ (BLAS.NRM2 Q J P N)) (\FLOATASET NORMXJ R J J) (\FLOATASET (if (FGREATERP NORMXJ 0.0) then 0.0 else 1.0) C J)) (* Loop over each column of Q in turn.) [bind RKK CK V8 V9 declare (TYPE FLOATP RKK CK V8) for K from 0 to (SUB1 P) do (SETQ RKK (\FLOATAREF R K K)) (\FLOATASET 1.0 R K K) (SETQ V9 RKK) (SETQ CK (\FLOATAREF C K)) (bind NO.ORTHOFLG repeatuntil NO.ORTHOFLG do [if (UFGREATERP CK .75) then (* Weight loss has been substantial, recompute 2-norm.) (SETQ V8 (BLAS.NRM2 Q K P N)) else (* Otherwise, fast update of length.) (SETQ V8 (FTIMES V9 (SQRT (SETQ V8 (FDIFFERENCE 1.0 CK] (\FLOATASET (FTIMES V8 (\FLOATAREF R K K)) R K K) (* Test if new column length is so much smaller than original length that we must give up and declare singularity. The test relies implicitly on the finite precision of machine addition.) (if [NOT (UFLESSP RKK (FPLUS RKK (\FLOATAREF R K K] then (RETURN K) else (* Otherwise, accept column length.) (for I from 0 to (SUB1 N) do (\FLOATASET (FQUOTIENT (\FLOATAREF Q I K) V8) Q I K))) (* Column K should be nearly orthogonal to the previous ones, and we check if it can benefit from reorthoganalization.) (if (UFLESSP (FQUOTIENT V8 V9) .25) then (SETQ NO.ORTHOFLG NIL) (* Reorthoganalize with respect preceding columns.) (bind DOTXJXK declare (TYPE FLOATP DOTXJXK) for J from 0 to (SUB1 K) do (SETQ DOTXJXK (BLAS.DOTPROD Q J P Q K P N)) (\FLOATASET (FPLUS (\FLOATAREF R J K) (FTIMES DOTXJXK (\FLOATAREF R K K))) R J K) (for I from 0 to (SUB1 N) do (\FLOATASET (FDIFFERENCE (\FLOATAREF Q I K) (FTIMES DOTXJXK (\FLOATAREF Q I J))) Q I K))) (SETQ V9 1.0) else (SETQ NO.ORTHOFLG T))) (* Orthogonalize remaining columns with respect to current one.) (bind DOTXJXK declare (TYPE FLOATP DOTXJXK) for J from (ADD1 K) to (SUB1 P) do (SETQ DOTXJXK (BLAS.DOTPROD Q J P Q K P N)) (\FLOATASET DOTXJXK R K J) (for I from 0 to (SUB1 N) do (\FLOATASET (FDIFFERENCE (\FLOATAREF Q I J) (FTIMES DOTXJXK (\FLOATAREF Q I K))) Q I J)) (SETQ V9 (\FLOATAREF R J J)) (if (UFGREATERP V9 0.0) then (\FLOATASET (FPLUS (\FLOATAREF C J) (FTIMES (FQUOTIENT DOTXJXK V9) (FQUOTIENT DOTXJXK V9))) C J] (RETURN NIL]) (SVDNASH [LAMBDA (UMATRIX SVECTOR VMATRIX) (* jop: "31-Jan-86 13:50") (* * Singular-value decomposition by means of orthogonalization by plane rotations. Taken from Nash and Shlien: "Partial svd algorithms." On entry UMATRIX contains the m by n matrix to be decomposed, SVECTOR must be a vector of length n, and VMATRIX must be a square n by n matrix. On return UMATRIX has been overwritten by the left singular vectors, SVECTOR contains the singular values, and VMATRIX contains the right singular vectors.) (LET* ((M (ARRAY-DIMENSION UMATRIX 0)) (N (ARRAY-DIMENSION UMATRIX 1)) (EPS 1.0E-6) (SLIMIT (IMAX (IQUOTIENT N 4) 6)) (NT N)) (* * Initialize VMATRIX to identity matrix.) (BLAS.ARRAYFILL 0.0 VMATRIX) (for I from 0 to (SUB1 N) do (LASET 1.0 VMATRIX I I)) (* * The main loop: repeatedly sweep over all pairs of columns in U, rotating as needed, until no rotations in a complete sweep are effective. Check the opportunity for rank reduction at the conclusion of each sweep.) [bind (SCOUNT ← 0) RCOUNT (FEPS ← EPS) (FEPSSQUARED ← (FTIMES EPS EPS)) declare (TYPE FLOATP FEPS FEPSSQUARED) repeatwhile (IGREATERP RCOUNT 0) eachtime (SETQ RCOUNT (IQUOTIENT (ITIMES NT (SUB1 NT)) 2)) (SETQ SCOUNT (ADD1 SCOUNT)) do (if (IGREATERP SCOUNT SLIMIT) then (HELP "Number of sweeps exceeds sweep limit." SCOUNT)) [for J from 0 to (IDIFFERENCE NT 2) do (bind P Q R C FC S FS V for K from (IPLUS J 1) to (SUB1 NT) declare (TYPE FLOATP P Q R FC FS V) do (SETQ P (BLAS.DOTPROD UMATRIX J N UMATRIX K N M)) (SETQ Q (BLAS.DOTPROD UMATRIX J N UMATRIX J N M)) (SETQ R (BLAS.DOTPROD UMATRIX K N UMATRIX K N M)) (LASET Q SVECTOR J) (LASET R SVECTOR K) (if (UFLESSP Q R) then (SETQ Q (FDIFFERENCE (FQUOTIENT Q R) 1.0)) (SETQ P (FQUOTIENT P R)) [SETQ V (SQRT (SETQ V (FPLUS (FTIMES 4.0 P P) (FTIMES Q Q] [SETQ FS (SQRT (SETQ FS (FTIMES .5 (FDIFFERENCE 1.0 (FQUOTIENT Q V] (if (UFLESSP P 0.0) then (SETQ FS (FDIFFERENCE 0.0 FS))) (SETQ FC (FQUOTIENT P (FTIMES V FS))) (* box before the COLROT calls) (SETQ C FC) (SETQ S FS) (BLAS.ROT C S UMATRIX J N UMATRIX K N M) (BLAS.ROT C S VMATRIX J N VMATRIX K N N) elseif (OR (UFLEQ (FTIMES Q R) FEPSSQUARED) (UFLEQ (FTIMES (FQUOTIENT P Q) (FQUOTIENT P R)) FEPS)) then (SETQ RCOUNT (SUB1 RCOUNT)) else (SETQ R (FDIFFERENCE 1.0 (FQUOTIENT R Q))) (SETQ P (FQUOTIENT P Q)) [SETQ V (SQRT (SETQ V (FPLUS (FTIMES 4.0 P P) (FTIMES R R] [SETQ FC (SQRT (SETQ FC (FTIMES .5 (FPLUS 1.0 (FQUOTIENT R V] (SETQ FS (FQUOTIENT P (FTIMES V FC))) (* box before the COLROT calls) (SETQ C FC) (SETQ S FS) (BLAS.ROT C S UMATRIX J N UMATRIX K N M) (BLAS.ROT C S VMATRIX J N VMATRIX K N N] (bind (TOL ← EPS) declare (TYPE FLOATP TOL) while (AND (IGEQ NT 3) (UFLEQ (FQUOTIENT (LAREF SVECTOR (SUB1 NT)) (FPLUS (LAREF SVECTOR 0) TOL)) TOL)) do (SETQ NT (SUB1 NT] (* * Finish the decomposition by returning all N singular values, and by normalizing those columns of UMATRIX judged to be non-zero.) (bind Q for J from 0 to (SUB1 N) do (SETQ Q (SQRT (LAREF SVECTOR J))) (LASET Q SVECTOR J) (if (ILEQ J NT) then (BLAS.SCAL (FQUOTIENT 1.0 Q) UMATRIX J N M]) ) (PUTPROPS OTHERMATRIXOPS COPYRIGHT ("Xerox Corporation" 1986)) (DECLARE: DONTCOPY (FILEMAP (NIL (529 19114 (DIAGXTXINVERSE 539 . 2873) (OLSMGS 2875 . 5265) (QRMGS 5267 . 13239) ( SVDNASH 13241 . 19112))))) STOP