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 "voronoi.h"3#include "polyeder.h"4#include "tools.h"5#include "bravais.h"67/**********************************************************************\8@9@--------------------------------------------------------------------10@ FILE: all_vor_neighbours.c11@--------------------------------------------------------------------12@13\**********************************************************************/14151617/**********************************************************************\18@ matrix_TYP *all_voronoi_neighbours(P, G, Ftr, tr_bifo)19@ matrix_TYP *P, **Ftr, *tr_bifo;20@ bravais_TYP *G;21@--------------------------------------------------------------------22@23@ The arguments of 'all_voronoi_neighbours' are:24@ P: a G-perfect form25@ G: the group for which P is G-perfect26@ Ftr: a basis for the integral forms in the formspace of G^{tr}27@ trbifo: The matrix of the bilinear form28@ F(G)xF(G^{tr})--> R: (A,B)---> trace(AB)29@ with respect to the Z-bases given by G->form and Ftr30@ Let Fdim be the dimension of the formspace of G and m be the number of31@ G-perfect forms that are neighbours of P.32@ Then the result of 'all_perfect_neighbours' is a matrix N with m rows33@ and Fdim+3 columns.34@ For 0 < i< m let R[i] be the form in F(G) represented by the35@ first Fdim entries of the i-th row of N, t.m.36@ R[i] = N[i][0] * G->form[0] + ..... + N[i][Fdim-1] * G->form[Fdim-1]37@ Further let38@ p[i] := N[i][Fdim], r[i] := N[i][Fdim+1], c[i] := N[i][Fdim+2]39@ Then P[i] := (p[i]*P + r[i]*R[i]) / c[i]40@ is a G-perfect form neighboured to P.41@--------------------------------------------------------------------42@43\**********************************************************************/44matrix_TYP *all_voronoi_neighbours(P, G, Ftr, tr_bifo)45matrix_TYP *P, **Ftr, *tr_bifo;46bravais_TYP *G;47{48int i,j,k,l, Fdim, Gdim;49int Pmin, Vanz, Wanz;50matrix_TYP *erg;51matrix_TYP **V, *N, *X;52polyeder_TYP *pol;53wall_TYP **W;54int *ww, *pw;55int pos, lc, rc, g;565758Fdim = G->form_no;59Gdim = G->form[0]->cols;60/**********************************************************************\61| calculate the vertices of the Voronoidomain in F(G^{tr})62| and the forms in F(G) corresponding to the walls of the Voronoidomain.63| The coordinates of these forms with respect to the basis given in G->form64| are obtained as the coordinates of the vetrices of the polyeder_TYP *pol.65\**********************************************************************/66V = voronoi_vertices(P, G, &Vanz, &Pmin, &i);67Wanz = Vanz;68if( (W = (wall_TYP **)malloc(Wanz *sizeof(wall_TYP *))) == NULL)69{70printf("malloc of W failed in all_perfect_neighbours\n");71exit(2);72}73if( (ww = (int *)malloc(Fdim *sizeof(int))) == NULL)74{75printf("malloc of ww failed in all_perfect_neighbours\n");76exit(2);77}78if( (pw = (int *)malloc(Fdim *sizeof(int))) == NULL)79{80printf("malloc of pw failed in all_perfect_neighbours\n");81exit(2);82}83for(i=0;i<Vanz;i++)84{85W[i] = init_wall(Fdim);86form_to_vec(ww, V[i], Ftr, Fdim, &k);87for(j=0;j<Fdim; j++)88for(k=0;k<Fdim; k++)89W[i]->gl[j] += ww[k] * tr_bifo->array.SZ[j][k];90normal_wall(W[i]);91free_mat(V[i]);92}93free(V);94pol = first_polyeder(W, Wanz);95if(pol == NULL)96{97printf("Error in all_perfect_neighbours: P not G-perfekt\n");98exit(3);99}100for(i=0;i<Wanz;i++)101{102refine_polyeder(pol, W[i]);103free_wall(&W[i]);104}105free(W);106107/*108put_polyeder(pol);109*/110111/******************************************************************\112| Each G-perfect form A, that is a neighbour of P, is (up to113| multiplication with a positive scalar) given by114| N = lc *P + rc * X,115| where X is a form defined by a vertex of the polyeder pol.116| The coefficients are calculated with the function 'voronoi_neighbour'.117\******************************************************************/118form_to_vec(pw, P, G->form, Fdim, &k);119erg = init_mat(pol->vert_no, (Fdim+3), "");120X = init_mat(Gdim, Gdim, "");121X->flags.Integral = X->flags.Symmetric = TRUE;122X->flags.Diagonal = FALSE;123pos = 0;124for(i=0;i<pol->vert_no;i++)125{126/******************************************************\127| Calculate X128\******************************************************/129for(j=0;j<Gdim;j++)130for(k=0;k<=j;k++)131{132X->array.SZ[j][k] = 0;133for(l=0;l<Fdim;l++)134X->array.SZ[j][k] +=pol->vert[i]->v[l] * G->form[l]->array.SZ[j][k];135X->array.SZ[k][j] = X->array.SZ[j][k];136}137N = voronoi_neighbour(P, X, Pmin, &lc, &rc);138/******************************************************\139| Divide N by the greatest common divisor of its entries140\******************************************************/141if(N != NULL)142{143for(j=0;j<Fdim;j++)144erg->array.SZ[pos][j] = pol->vert[i]->v[j];145erg->array.SZ[pos][Fdim] = lc;146erg->array.SZ[pos][Fdim+1] = rc;147for(j=0;j<Fdim;j++)148ww[j] = lc * pw[j] + rc * erg->array.SZ[pos][j];149k = 0;150while(k<Fdim && ww[k] == 0)151k++;152g = ww[k];153for(j=k+1;j<Fdim;j++)154{155if(ww[j] != 0)156{157l = GGT(g, ww[j]);158g = l;159}160}161erg->array.SZ[pos][Fdim+2] = g;162free_mat(N);163pos++;164}165}166167/* changed on 14/1/97 tilman from168erg->rows = pos;169to: */170real_mat(erg,pos,erg->cols);171172free_mat(X);173free(pw); free(ww);174/*********************************175put_polyeder(pol);176***********************************/177free_polyeder(pol);178return(erg);179}180181182