Metropoli BBS
VIEWER: matinv.c MODE: TEXT (ASCII)
/*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));
}
[ RETURN TO DIRECTORY ]