/* ========================== C MeatAxe =============================
   genmod.c - This program calculates a basis of any submodule
   listed in the .out file.

   (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: genmod.c,v 2.9 1994/03/26 06:34:04 mringe Exp $
 *
 * $Log: genmod.c,v $
 * Revision 2.9  1994/03/26  06:34:04  mringe
 * basename umbenannt wg. Namenskonflikt.
 *
 * Revision 2.8  1994/02/19  15:18:49  mringe
 * Neu: Option -n (make mountain).
 *
 * Revision 2.7  1994/02/15  13:39:15  mringe
 * Benutze os_fseek().
 *
 * Revision 2.6  1994/02/13  18:26:56  mringe
 * Neu: os.c, os.h.
 *
 * Revision 2.5  1994/02/12  04:10:13  mringe
 * UMFANGREICHE AENDERUNGEN AN VIELEN DATENTYPEN.
 *
 * Revision 2.4  1993/12/13  08:25:53  mringe
 * Reihenfolge der Fkt.-argumente vereinheitlicht.
 *
 * Revision 2.3  1993/12/02  17:59:28  mringe
 * Ersetze bitstring_t durch bitstring_t *.
 *
 * Revision 2.2  1993/10/28  19:10:15  mringe
 * Beginne Mit modul Nr. 0
 *
 * 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.10  1993/10/11  19:05:28  mringe
 * Neue Library-Struktur.
 *
 * Revision 1.9  1993/10/02  16:23:02  mringe
 * matread() und matwrite() in matload() bzw. matsave() umbenannt.
 *
 * Revision 1.8  1993/09/30  12:58:31  mringe
 * Lese Bitstring von xxx.sub.
 *
 * Revision 1.7  1993/08/10  14:29:19  mringe
 * Include string.h
 *
 * Revision 1.6  1993/08/06  14:01:59  mringe
 * Neuer File-header.
 *
 * Revision 1.5  1993/02/17  11:16:12  mringe
 * Include-Files...
 *
 * Revision 1.4  1993/02/15  13:49:24  mringe
 * Funktionen aus cyclic.c -> yyy-Lib verschoben.
 *
 * Revision 1.3  1993/02/10  19:40:54  mringe
 * Libraries angelegt (YYY und ZZZ).
 *
 * Revision 1.2  1992/07/22  07:10:30  mringe
 * Changed 'global.h' to 'lattice.h'
 *
 * Revision 1.1  1992/05/26  07:29:08  mringe
 * Initial revision
 *
 */


#include <string.h>
#include <stdlib.h>

#include "meataxe.h"
#include "lattice.h"
#include "files.h"


/* ------------------------------------------------------------------
   Function prototypes
   ------------------------------------------------------------------ */

static void init _PL((char *arg));
static void sp _PL((void));



/* ------------------------------------------------------------------
   Global data
   ------------------------------------------------------------------ */

matrix_t *gen[MAXGEN];		/* Generators for the algebra */
matrix_t *mountains;		/* Genrators for all mountains */
int nmount;			/* Number of mountains */
int modnum;
bitstring_t *bs;		/* Bit string read from .sub file */
int opt_m = 0;			/* Option -m used */

static char *helptext[] = {
"SYNTAX",
"    genmod [-QVm] <Name> <Number>",
"",
"OPTIONS",
"    -m    Make mountain (works after mkinc)",
"    -V    Verbose",
"    -Q    Quiet, no messages",
"",
"FILES",
"    <Name>.sub       i  Submodule information (generated by mksub)",
"    <Name>.v         i  Mountains",
"    <Name>.s<Number> o  The result (without -m)",
"    <Name>.m<Number> o  The result (with -m)",
NULL};

static proginfo_t pinfo =
   { "genmod", "Make Submodule", "$Revision: 2.9 $", helptext };




/* -----------------------------------------------------------------
   init() - Read generators and mountains
   ----------------------------------------------------------------- */

static void init(arg)
char *arg;

{
    char fn[200];
    FILE *f;
    int i;

    mtxinit();

    /* Read the generators
       ------------------- */
    readcfinfo();
    for (i = 0; i < ngen; ++i)
    {
    	sprintf(fn,"%s.%d",cfbasename,i+1);
	gen[i] = matload(fn);
    }

    /* Read the mountains
       ------------------ */
    mountains = matload(strcat(strcpy(fn,cfbasename),".v"));
    nmount = (int) mountains->nor;
    bs_setlen(nmount);
    MESSAGE(1,("%d mountains\n",nmount));
    fflush(stdout);
    

    /* Read the bit string from xxx.sub or set up the bit string
       to contain only the requested mountain (-m)
      ------------------------ --------------------------------- */
    modnum = atoi(arg);
    if (opt_m)
    {
	bs = bs_alloc();
	bs_reset(bs);
	bs_set(bs,modnum);
    }
    else
    {
    	f = os_fopen(strcat(strcpy(fn,cfbasename),".sub"),FM_READ);
    	if (f == NULL) FATAL("CANNOT OPEN .sub FILE");
    	os_fseek(f,modnum*bs_size);
    	bs = bs_read(f);
    	if (MSG1)
    	{
	    printf("Mountains: ");
	    for (i = 0; i < nmount; ++i)
	    	if (bs_test(bs,i)) printf("%d ",i);
	    printf("\n");
    	}
	fclose(f);
    }
}



/* -----------------------------------------------------------------
   sp()
   ----------------------------------------------------------------- */

static void sp()

{	int i;
	matrix_t *m, *subsp;
	PTR p;
	char fn[200];

	m = matalloc(gen[0]->fl,(long)nmount,gen[0]->noc);
	p = m->d;
	for (i = 0; i < nmount; ++i)
	{	if (bs_test(bs,i))
		{	PTR q = mountains->d;
			zadvance(&q,(long)i);
			zmoverow(p,q);
			zadvance(&p,(long)1);
		}
	}
	m = echelon(m);
	MESSAGE(0,("Seed space has dimension %ld\n",m->nor));
	subsp = matspin(m,ngen,gen);
	MESSAGE(0,("Submodule has dimension %ld\n",subsp->nor));
	sprintf(fn,"%s.%c%d",cfbasename,opt_m ? 'm' : 's',modnum);
	matsave(subsp,fn);
	MESSAGE(0,("Module written to `%s'\n",fn));
}


/* -----------------------------------------------------------------
   main()
   ----------------------------------------------------------------- */

int main(argc, argv)
int argc;
char *argv[];

{
    int i;

    mtxinit();
    initargs(argc, argv, &pinfo);
    while ((i = zgetopt("m")) != OPT_END)
    {
	switch (i)
	{
	    case 'm': opt_m = 1; break;
	}
    }
    if (opt_ind != argc-2) errexit(ERR_NARGS,"genmod");
    setbasename(argv[opt_ind]);
    init(argv[opt_ind+1]);
    sp();
    return 0;
}


