GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#include "typedef.h"1#include "matrix.h"2#include "longtools.h"34extern int INFO_LEVEL;56/***************************************************************************7@8@---------------------------------------------------------------------------9@---------------------------------------------------------------------------10@ FILE: min_pol.c11@---------------------------------------------------------------------------12@---------------------------------------------------------------------------13@14****************************************************************************/151617/***************************************************************************18@19@---------------------------------------------------------------------------20@21@ matrix_TYP *min_pol(matrix_TYP *A)22@23@ Let A be an integral NON ZERO matrix. Then the function returns an24@ integral 1xn matrix B with the property:25@ \sum_i=0^n B->array.SZ[0][i] * A^i =0,26@ and n is minimal.27@28@ SIDEEFECTS: the matrix A is checked via Check_mat !!!29@---------------------------------------------------------------------------30@31****************************************************************************/32matrix_TYP *min_pol(matrix_TYP *A)33{34int i,35j,36k,37flag,38cols,39rank,40grad; /* actualy the degree +1 */4142matrix_TYP **potenzen,43*erg; /* will hold the result */4445MP_INT **lines,46**trf,47kgv;4849/* check some trivialities */50Check_mat(A);51if (A->flags.Integral == FALSE || A->cols != A->rows){52fprintf(stderr,"error in min_pol, A should be integral and quadratic\n");53exit(3);54}5556/* prepare all variables */57potenzen = (matrix_TYP **) calloc(1 + A->cols , sizeof(matrix_TYP));58potenzen[0] = init_mat(A->cols,A->cols,"1");59potenzen[1] = copy_mat(A);60lines = init_MP_mat(A->cols+1,A->cols*A->cols);61trf = init_MP_mat(A->cols+1,A->cols+1);62for (i=0;i<=A->cols;i++) mpz_set_ui(trf[i]+i,1);63mpz_init(&kgv);6465/* set the first two lines */66for (i=0;i<2;i++)67for (j=0;j<A->cols;j++)68for (k=0;k<A->cols;k++)69mpz_set_si(lines[i]+j*A->cols+k,potenzen[i]->array.SZ[j][k]);7071/* the calculation starts */72grad = 2;73do{74if (INFO_LEVEL & 4){75dump_MP_mat(lines,grad,A->cols*A->cols,"lines");76}77rank = MP_row_gauss_simultaneous(lines,grad,A->cols*A->cols,trf,grad);7879/* avoid getting trouble by big numbers, ie. the powers aren't really80powers because of a lack of precision */81if (rank > A->cols){82fprintf(stderr,"error in min_pol because of a lack of precision\n");83exit(3);84}8586if (rank == grad){87potenzen[grad] = mat_mul(potenzen[grad-1],A);88for (j=0;j<A->cols;j++)89for (k=0;k<A->cols;k++)90mpz_set_si(lines[grad]+j*A->cols+k,91potenzen[grad]->array.SZ[j][k]);92grad++;93flag = FALSE;94}95else{96flag = TRUE;97}98} while(!flag);99100/* we got the wanted result in trf */101erg = init_mat(1,grad,"");102for (i=0;i<grad;i++) erg->array.SZ[0][i] = mpz_get_si(&trf[grad-1][i]);103104/* "normalize" polynomial, ie. get the last coeff positive */105if (erg->array.SZ[0][grad-1] < 0)106for (i=0;i<grad;i++) erg->array.SZ[0][i] *= -1 ;107108/* clean up memory */109for (i=0;i<=A->cols;i++) if (potenzen[i] != NULL) free_mat(potenzen[i]);110free_MP_mat(trf,A->cols+1,A->cols+1);111free(trf);112free(potenzen);113free_MP_mat(lines,A->cols+1,A->cols*A->cols);114free(lines);115mpz_clear(&kgv);116117return erg;118} /* min_pol(....) */119120121