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 "symm.h"3#include "bravais.h"4#include "voronoi.h"5#include "longtools.h"6#include "tools.h"7#include "getput.h"8910/*********************************************************************\11@12@---------------------------------------------------------------------13@ FILE: first_perfect.c14@---------------------------------------------------------------------15@16\*********************************************************************/1718/*********************************************************************\19@20@ matrix_TYP *first_perfect(A, G, Ftr, trbifo, min)21@ matrix_TYP *A, **Ftr, *trbifo;22@ bravais_TYP *G;23@ int *min;24@25@ 'first_perfect' calculates a G-perfect Form.26@ The arguments of 'first_perfect' are27@ A: a G-invariant, positive definite Form28@ G: the group for which a perfect form will be calculated29@ Ftr: a Z-basis for the integral forms in the formspace of G^{tr}30@ trbifo: The matrix of the bilinear form31@ F(G)xF(G^{tr})--> R: (A,B)---> trace(AB)32@ with respect to the Z-bases given by G->form and Ftr33@ min: The pointer min returns the minimum of the calculated34@ perfect form.35@---------------------------------------------------------------------36@37\*********************************************************************/38matrix_TYP *first_perfect(A, G, Ftr, trbifo, min)39matrix_TYP *A, **Ftr, *trbifo;40bravais_TYP *G;41int *min;42{43int i,j,k, n, lc, rc, g;44matrix_TYP **V, *Vmat, *P, *M, *W, *W1, *M1;45int Vanz;46int rang;47int Pmin;484950n = G->form_no;51P = copy_mat(A);52/*****************************************************************\53| Check whether P is G-perfect or not54\*****************************************************************/55V = voronoi_vertices(P, G, &Vanz, &Pmin, &i);56Vmat = init_mat(Vanz, G->form_no, "");57for(i=0;i<Vanz;i++)58{59form_to_vec(Vmat->array.SZ[i], V[i], Ftr, n, &k);60free_mat(V[i]);61}62free(V);63rang = long_row_basis(Vmat,FALSE);64if(rang == n)65{66free_mat(Vmat);67Vmat = NULL;68/* inserted 11/2/97 tilman */69Vmat = shortest(P,min);70free_mat(Vmat);7172return(P);73}74W = init_mat(n, n, "");75M = init_mat(A->rows, A->cols, "");76while(rang != n)77{78/* printf("The Voronoi domain of the following form has dimension %d\n", rang);79put_mat(P, NULL, "next approximation", 2); */80/****************************************************************\81| Search for a form M perpendicular to the Voronoi-vertices82| (with respect to trbifo)83| if M is positive semidefinite take -M84\****************************************************************/85for(i=0;i<rang;i++)86for(j=0;j<n;j++)87{88W->array.SZ[i][j] = 0;89for(k=0;k<n;k++)90W->array.SZ[i][j] += Vmat->array.SZ[i][k] * trbifo->array.SZ[j][k];91}92free_mat(Vmat);93Vmat = NULL;94W1 = long_kernel_mat(W);95for(i=0;i<A->rows;i++)96for(j=0;j<=i;j++)97{98M->array.SZ[i][j] = 0;99for(k=0;k<n;k++)100M->array.SZ[i][j] += W1->array.SZ[k][W1->cols-1] * G->form[k]->array.SZ[i][j];101M->array.SZ[j][i] = M->array.SZ[i][j];102}103free_mat(W1);104k = definite_test(M);105if(k >= 0)106{107for(i=0;i<M->rows;i++)108for(j=0;j<M->cols;j++)109M->array.SZ[i][j] = -M->array.SZ[i][j];110}111/*****************************************************************\112| calculate next form with more shortest vectors113| and divide the matrix by the gcd of the entries114\*****************************************************************/115M1 = voronoi_neighbour(P, M, Pmin, &lc, &rc);116free_mat(P);117P = M1;118M1 = NULL;119Pmin = Pmin * lc;120g = Pmin;121for(i=0;i<P->rows && g != 1; i++)122for(j=0;j<=i && g != 1;j++)123{124if(P->array.SZ[i][j] != 0)125{ k = GGT(g, P->array.SZ[i][j]); g = k;}126}127if(g != 1 && g!= -1)128{129Pmin /= g;130for(i=0;i<P->cols;i++)131for(j=0;j<=i;j++)132{133P->array.SZ[i][j] /= g;134P->array.SZ[j][i] = P->array.SZ[i][j];135}136}137138/*****************************************************************\139| if rang < n-1, check whether P is G-perfect or not140| if rang = n-1, the new Form must be perfect141\*****************************************************************/142if(rang < n-1)143{144V = voronoi_vertices(P, G, &Vanz, &k, &i);145if(k != Pmin)146{147put_mat(P,NULL,"P",2);148printf("Minimum of P %d, Pmin %d\n",k,Pmin);149printf("Fehler in first_perfect, Minimum falsch\n");150exit(3);151}152Vmat = init_mat(Vanz, G->form_no, "");153for(i=0;i<Vanz;i++)154{155form_to_vec(Vmat->array.SZ[i], V[i], Ftr, n, &k);156free_mat(V[i]);157}158free(V);159rang = long_row_basis(Vmat,FALSE);160}161else{162rang = n;163}164}165free_mat(W);166free_mat(M);167*min = Pmin;168169if (Vmat != NULL){170free_mat(Vmat);171}172173return(P);174}175176177