/*Copyright (C) 1992, 1995 by Thomas Glen Smith. All Rights Reserved.*/ /* matinv APL2 V1.0.0 ************************************************** * Produces the matrix inverse. Implements APL monadic DOMINO. * * An argument of rank greater than two is rejected. A scalar is * * treated as a 1-by-1 matrix, and a vector as a one-column matrix. * ***********************************************************************/ #define INCLUDES APLCB #include "includes.h" Aplcb matinv(rite) Aplcb rite; { Errinit; Errstop; Getcb; Invert; Mdivarg; Real; Regress; extern int aplerr; int cols,*dimptr,i,rows; double *dataptr,f,*inv; Aplcb out=NULL; if (errinit()) return(errstop(0,NULL,rite,out)); if (ERR == mdivarg(rite,&rows,&cols)) return(errstop(0,NULL,rite,out)); if (rows < cols) return(errstop(6,NULL,rite,out)); if (!(rite->aplflags & APLNUMB)) { rite = real(rite); if (aplerr) return(NULL); } if (rows == cols) { /* square matrix? */ dataptr = invert(rite->aplptr.apldata,rows); if (NULL == dataptr) return(errstop(8,NULL,rite,out)); /* not invertible */ } else { /* non-square matrix */ dataptr = regress(NULL,rite,rows,rows,rows,cols); if (aplerr) return(NULL); } out=getcb(dataptr,rite->aplcount,APLTEMP+APLNUMB,rite->aplrank,NULL); if (rite->aplrank > 1) { /* build new dimensions? */ dimptr=out->apldim; *dimptr++=*(rite->apldim+1); *dimptr=*(rite->apldim); } return(errstop(0,NULL,rite,out)); }