/* ========================== C MeatAxe =============================
   ycomp.c - Compare cyclic modules.

   (C) Copyright 1993 Michael Ringe, Lehrstuhl D fuer Mathematik,
   RWTH Aachen, Germany  <mringe@tiffy.math.rwth-aachen.de>
   This program is free software; see the file COPYING for details.
   ================================================================== */

/* $Id: ycomp.c,v 2.2 1993/12/08 11:48:50 mringe Exp $
 *
 * $Log: ycomp.c,v $
 * Revision 2.2  1993/12/08  11:48:50  mringe
 * Compiler warnings.
 *
 * Revision 2.1  1993/10/20  18:17:07  mringe
 * MeatAxe-2.0, Phase II.
 *
 * Revision 2.0  1993/10/14  18:54:18  mringe
 * MeatAxe-2.0, Phase I
 *
 * Revision 1.8  1993/10/11  19:05:28  mringe
 * Neue Library-Struktur.
 *
 * Revision 1.7  1993/10/06  04:41:05  mringe
 * utils Library eliminiert.
 *
 * Revision 1.6  1993/10/05  19:17:50  mringe
 * *** empty log message ***
 *
 * Revision 1.5  1993/10/05  19:02:08  mringe
 * yerror eliminiert.
 *
 * Revision 1.4  1993/08/06  14:01:59  mringe
 * Neuer File-header.
 *
 * Revision 1.3  1993/08/06  12:54:10  mringe
 * ERR_NOECH in ERR_NOIECH umbenannt.
 *
 * Revision 1.2  1993/08/05  15:48:54  mringe
 * Neues message.c
 *
 * Revision 1.1  1993/02/15  13:50:28  mringe
 * Initial revision
 *
 */

#include <stdlib.h>
#include "meataxe.h"




/* ------------------------------------------------------------------
   ycompare() - Compare two modules. Both `m1' and `m2' must
	must be in semi-echelon form. It is assumed that both
	modules are generated by the first `n' basis vectors.

   return value:
	-1: m1 <= m2
	+1: m1 >= m2
	0 : m1 == m2
	9 : else
	-9: error
   ------------------------------------------------------------------ */

int ycompare(m1,m2,n)
matrix_t *m1, *m2;
long n;

{
    int swap = 0;
    PTR x1, x2, y;
    long i, k, piv = 0;
    FEL f;
    int issub = 1;

    if (m1->noc != m2->noc)
    {
	MTXFAIL(ERR_INCOMPAT,-9);
    }
    if (m1->nor > m2->nor)	/* make sure that dim(m1) <= dim(m2) */
    {
	matrix_t *m3;
	m3 = m1; m1 = m2; m2 = m3;
	swap=1;
    }
    zsetlen(zfl,m1->noc);
    x1 = zalloc((long)1);

    /* For each generator of m1 check if it is contained in m2
       ------------------------------------------------------- */
    y = m1->d;
    for (i = 1; issub && i <= n; ++i)
    {
	zmoverow(x1,y);
	zadvance(&y,(long)1);
	x2 = m2->d;
	for (k = m2->nor; k > 0; --k)
	{	piv = zfindpiv(x2,&f);
			if (piv == 0)
			{
			    MTXFAIL(ERR_NOTECH,-9);
			}
			f = zsub(0,zdiv(zextract(x1,piv),f));
			zaddmulrow(x1,x2,f);
			if ((piv = zfindpiv(x1,&f)) == 0)
				break;
			zadvance(&x2,(long)1);
	}
	if (piv != 0)
	    issub = 0;
    }
    free(x1);
    if (issub)
    {
	if (m1->nor == m2->nor)
	    return 0;			/* m1 == m2 */
	if (swap)
	    return 1;			/* m2 <= m1 */
	else
	    return -1;			/* m1 <= m2 */
    }
    else
	return 9;
}




