?PUTPROP(?QUOTE(gcdivide),?FILESTRIP(?CDR([functs,lisp,dsk,share])),
	?QUOTE(?AUTOLOAD));

det&&  det(m):=BLOCK([n],LOCAL(a),
    n:LENGTH(m),
    IF n < 2 THEN ERROR ("Improper argument:",m),
    ARRAY(a,n,n),
    FOR i THRU n DO FOR j THRU n DO a[i,j]:m[i,j],
    a[0,0]:1,
    CATCH(FOR k FROM 2 STEP 2 THRU n DO  /* Iterate for each pair of rows */
	(IF k#n THEN BLOCK([c0,L2,u],  /* Omit calculation on last
					iteration for n even */
	    L1:(IF a[k-1,k-1]#0 THEN  /* check for possible pivoting */
		FALSE
	    ELSE	/* Zero element means pivoting is necessary */
		FOR s FROM k THRU n DO  /* Search for nonzero element */
		    IF a[s,k-1]#0 THEN  /* Found pivot */
			(FOR j THRU n DO /* Interchange rows s and k-1 */
			    BLOCK([t],
			    t:a[k-1,j],
			    a[k-1,j]:a[s,j],
			    a[s,j]:t),
			RETURN(FALSE))  /* Indicate pivot was found */
		    ELSE  /* No pivot found means */
			IF s=n THEN THROW(0)),  /* Singular matrix */
	    L2:(IF L1 THEN
		TRUE
	    ELSE
		/* Search through rows for nonzero multiplier */
		FOR t FROM k THRU n DO
		    (c0:DETERMINANT(MATRIX([a[k-1,k-1],a[k-1,k]],
			[a[t,k-1],a[t,k]])),
		    IF c0#0 THEN
			(u:t,
			RETURN(FALSE))  /* Indicate multiplier was found */
		    ELSE  /* No multiplier means singular matrix */
		 	IF t=n THEN THROW(0))),
	    IF L2 THEN
		RETURN(TRUE)
	    ELSE  /* Calculate coefficient from multiplier */
		(c0:gcdivide(c0,a[k-2,k-2]),
		IF u#k THEN  /* If multiplier was found in a different row */
		    FOR j THRU n DO BLOCK([t],  /* interchange rows t and k */
			t:a[k,j],
			a[k,j]:a[t,j],
			a[t,j]:t),
		/* Iterate through remaining rows */
		FOR i FROM k+1 THRU n DO BLOCK([c1,c2],
		    c1:gcdivide(-DETERMINANT(MATRIX([a[k-1,k-1],a[k-1,k]],
			[a[i,k-1],a[i,k]])),a[k-2,k-2]),
		    c2:gcdivide(DETERMINANT(MATRIX([a[k,k-1],a[k,k]],
			[a[i,k-1],a[i,k]])),a[k-2,k-2]),
		    a[i,k-1]:0,
		    a[i,k]:0,
		    /* Iterate through remaining columns */
		    FOR j FROM k+1 THRU n DO
			a[i,j]:gcdivide(c0*a[i,j]+c1*a[k,j]+c2*a[k-1,j],
			    a[k-2,k-2])),
		c0:0,
		FOR j FROM k+1 THRU n DO
		    (a[k,j]:0,
		    a[k-1,j]:0))),
	/* Omit calculation on last iteration for n odd */
	a[k,k]:IF k=n-1 THEN 0 ELSE
		gcdivide(DETERMINANT(GENMATRIX(a,k,k,k-1)),a[k-2,k-2]),
	a[k-2,k-2]:0,
	a[k-1,k-1]:0,
	a[k,k-1]:0,
	a[k-1,k]:0,
	/* On last iteration indicate nonsingular matrix */
	IF k=n OR k=n-1 THEN RETURN(FALSE)),
    a[n,n]))  /* If a singular matrix has not been thrown,
		then catch the determinant */$
