/********************************************************************/
/*                                                                  */
/*  Module        : G-Module                                        */
/*                                                                  */
/*  Version       : 1.3                                             */
/*  Last revision : 03/23/94 09:37:34                               */
/*                                                                  */
/*  Description :                                                   */
/*     Supplies routines to deal with G-modules.                    */
/*                                                                  */
/*  Functions supplied :                                            */
/*                                                                  */
/*                                                                  */
/********************************************************************/

#include "aglobals.h"
#include "fdecla.h"
#include	"pc.h"
#include	"hgroup.h"
#include	"grpring.h"
#include	"storage.h"

#ifdef ANSI
void exit ( int status );
#endif

int is_id 		_(( PCELEM el ));
int inc_el 		_(( PCELEM el ));
VEC *triv_mod 		_(( int dim, int numgen ));
VEC *ig_op		_(( void ));
VEC *tensor_prod 	_(( VEC rep1[], VEC rep2[], int dim1, int dim2 ));

extern int prime;
extern PCGRPDESC *group_desc;
extern GRPDSC *h_desc;
extern int new_xdim, new_cut;
extern char matrix[YMAX][XMAX];
extern VEC absolut, inhom;
extern VEC fsolution[XMAX];
extern int x_dim, y_dim;
extern int dim, dquad;
extern int adim, adquad;
extern int bperelem;
extern PCELEM *rho;

VEC *triv_mod ( int dim, int numgen )
{
	int i, j;
	int dq = dim * dim;
	VEC *g_list;
	
	g_list = ARRAY ( numgen, VEC );
	for ( i = numgen; i--; ) {
		g_list[i] = CALLOCATE ( dq );
		for ( j = 0; j < dim; j++ )
			g_list[i][j*dim+j] = 1;
	}
	return ( g_list );
}

VEC *ig_op ( void )
{
	int i, j;
	int dim = GCARD - 1;
	int dq;
	VEC *g_op_ig;
	PCELEM hi, el, pr;

	dq = dim * dim;
	
	g_op_ig = ARRAY ( bperelem, VEC );
	for ( i = 0; i < bperelem; i++ )
		g_op_ig[i] = CALLOCATE ( dq );
		
	PUSH_STACK();
	el = IDENTITY;
	j = 0;
	while ( inc_el ( el ) ) {
		PUSH_STACK();
		for ( i = 0; i < bperelem; i++ ) {
			hi = g_invers ( GNOM[i] );
			pr = monom_mul ( el, hi );
			if ( !is_id ( pr ) )
				g_op_ig[i][j*dim + nr ( monom_mul ( el, hi ) ) - 1] = 1;
			g_op_ig[i][j*dim + nr ( hi )- 1] = GPRIME - 1;
		}
		POP_STACK();
		j++;
	}
	POP_STACK();
	return ( g_op_ig );
}

VEC *tensor_prod ( VEC rep1[], VEC rep2[], int dim1, int dim2 )
{
	int i, j, k, i1;
	long xoffset, yoffset;
	int dim;
	long dq, dq2;
	VEC help;
	VEC *rep;
	
	dim = dim1*dim2;
	dq = (long)dim*(long)dim;
	dq2 = (long)dim2*(long)dim2;
	
	rep = ARRAY ( bperelem, VEC );
	for ( i = 0; i < bperelem; i++ )
		rep[i] = ALLOCATE ( dq );

	PUSH_STACK();
	help = ALLOCATE ( dq2 );
	for ( i = 0; i < dim1; i++ ) {
		yoffset = (long)(i*dim2*dim);
		for ( j = 0; j < dim1; j++ ) {
			xoffset = j*dim2;
			for ( k = 0; k < bperelem; k++ ) {
				copy_vector ( rep2[k], help, dq2 );
				SMUL_VECTOR ( rep1[k][j*dim1+i], help, dq2 );
				for ( i1 = 0; i1 < dim2; i1++ )
					copy_vector ( help+i1*dim2,
						rep[k]+yoffset+i1*dim+xoffset, dim2 );
			}
		}
	}
	POP_STACK();
	return ( rep );
}

void show_m ( VEC mat, int xdim, int ydim )
{
	register int i, j;
	for ( i = 0; i < ydim; i++ ) {
		for ( j = 0; j < xdim; j++ )
			printf ( "%1d", mat[i*xdim+j] );
		printf ( "\n" );
	}
}

/**************************************************************
int main()
{
	int i, j, cnr, n;
	int z_dim, h_dim;
	char list[MAXGEN];
	char gr_f_name[13];
	char ans[2];
	int dim1, dim2;
	VEC g_op1[MAXGEN], g_op2[MAXGEN];
	
	puts ( "\noperation on IG\n" );
	dim1 = group_desc.group_card -1;
	ig_op ( g_op1 );
	for ( i = 0; i < NUMGEN; i++ ) {
		printf ( "%c : \n", i + 'a' );
		showmat ( g_op1[i], dim1, dim1 );
		puts ( "\n" );
	}
	
	puts ( "\noperation on trivial module\n" );
	dim2 = 1;
	triv_mod ( dim2, g_op2 );
	for ( i = 0; i < NUMGEN; i++ ) {
		printf ( "%c : \n", i + 'a' );
		showmat ( g_op2[i], dim2, dim2 );
		puts ( "\n" );
	}
	
	puts ( "\noperation on HOM(IG,F)\n" );
	tensor_prod ( g_op, g_op1, g_op2, dim1, dim2 );
	dim = dim1*dim2;
	dquad = dim * dim;
	for ( i = 0; i < NUMGEN; i++ ) {
		printf ( "%c : \n", i + 'a' );
		showmat ( g_op[i], dim, dim );
		puts ( "\n" );
	}
	
	printf ( "number of cohomology group : " );
	scanf ( "%d", &n );
	cohomology ( n, g_op2, dim2, &z_dim, &h_dim );
	printf ( "dimension of Z%1d : %d\n", n, z_dim );
	printf ( "dimension of H%1d : %d\n", n, h_dim );
	getchar(); getchar();
	return 0;
}
*******************************************************************/
/* end of module g-module */
