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 "tools.h"4#include"bravais.h"56/****************************************************************************\7@ -----------------------------------------------------------------------8@ FILE: vor_neighbour.c:9@ -----------------------------------------------------------------------10@11\****************************************************************************/1213/****************************************************************************\14@15@ matrix_TYP *voronoi_neighbour(A, X, Amin, lc, rc)16@ matrix_TYP *A, *X;17@ int Amin, *lc, *rc;18@19@ The arguments of 'voronoi_neigbour' are20@ A: a positiv definite matrix21@ Amin: The Minimum of A, min(A) := min{yAy^{tr} | y in Z^n, y not 0}22@ X: a symmetric matrix, which is not positiv semidefinite23@ lc, rc: These pointer to an integer return the values of the24@ coefficients N = lc * A + rc *X for the result N of the25@ function26@27@ For A positive definite let M(A) denote the set of all y in Z^n28@ with yAy^{tr} = min(A) and29@ Z(A, X) the set of all y in M(A) with yXy^{tr} = 0.30@ The function voronoi_neigbbour calculates a Matrix N = lc *A + rc * X31@ with positive integral coefficients lc and rc such that32@ Z(A, X) is a proper subset of M(N).33@ In particular min(N) = lc * min(A).34@-----------------------------------------------------------------------35@36\****************************************************************************/37matrix_TYP *voronoi_neighbour(A, X, Amin, lc, rc)38matrix_TYP *A, *X;39int Amin, *lc, *rc;40{41int i,j,n;42matrix_TYP *SV, *N;43int lo,ro, lu, ru;44int lm, rm;45int anz, found;46int merk, Xy, Ay;474849j = definite_test(X);50if(j>= 0)51return(NULL);52n = A->rows;53N = init_mat(n,n,"");54N->flags.Integral = N->flags.Symmetric = TRUE;55N->flags.Diagonal = FALSE;56/************************************************************************\57| First calculate Form N = lm * A + rm * X, with N positiv definite58| and min(N) < lm * min(A)59\************************************************************************/60lu = 1; ru = 0;61lo = 0; ro = 1;62found = FALSE;63while(found == FALSE)64{65lm = lu + lo;66rm = ru + ro;67for(i=0;i<n;i++)68for(j=0;j<=i;j++)69N->array.SZ[i][j] = lm * A->array.SZ[i][j] + rm * X->array.SZ[i][j];70for(i=0;i<n;i++)71for(j=0;j<i;j++)72N->array.SZ[j][i] = N->array.SZ[i][j];73j = definite_test(N);74if(j == 2)75{76SV = short_vectors(N, (lm * Amin -1), 0, 1, 0, &anz);77if(anz > 0)78found = TRUE;79else80{ lu = lm; ru = rm; free_mat(SV);}81}82else83{ lo = lm; ro = rm;}84}8586/************************************************************************\87| The 1st row of SV containes an vector y with88| lm * min(A) > yNy^{tr} = lm * yAy^{tr} + rm * yXy^{tr}89| Now yAy^{tr} > min(A) and yXy^{tr} < 0.90| Calculate the rational number p/q = (Amin - yAy^{tr}) / (yXy^{tr}) >= 0.91| Then y (q * A + p * X) y^{tr} = q * Amin92| Replace N by q * A + p X.93| If min(N) = q * min(A) we are done, otherwise caluclate vector y'94| with y'Ny'^{tr} < q * min(A) and repeat.95\************************************************************************/96found = FALSE;97while(found == FALSE)98{99/************************************************************************\100| calculate Ay = y A y^{tr}101\************************************************************************/102Ay = 0;103for(i=0;i<n;i++)104{105merk = 0;106for(j=0;j<n;j++)107merk += A->array.SZ[i][j] * SV->array.SZ[0][j];108Ay += SV->array.SZ[0][i] * merk;109}110/************************************************************************\111| calculate Xy = y X y^{tr}112\************************************************************************/113Xy = 0;114for(i=0;i<n;i++)115{116merk = 0;117for(j=0;j<n;j++)118merk += X->array.SZ[i][j] * SV->array.SZ[0][j];119Xy += SV->array.SZ[0][i] * merk;120}121/************************************************************************\122| calculate the new N123\************************************************************************/124Ay -= Amin;125Xy = -Xy;126merk = GGT(Ay, Xy);127if(merk != 1)128{129Ay /= merk;130Xy /= merk;131}132for(i=0;i<n;i++)133for(j=0;j<=i;j++)134{135N->array.SZ[i][j] = Xy * A->array.SZ[i][j] + Ay * X->array.SZ[i][j];136N->array.SZ[j][i] = N->array.SZ[i][j];137}138free_mat(SV);139SV = short_vectors(N, (Xy * Amin - 1), 0, 1, 0, &anz);140if(anz == 0)141{ free_mat(SV); found = TRUE; *lc = Xy; *rc = Ay;}142}143144/* canceled these lines on 16/2/97 because they don't fit145to specification and cause problems: tilman146********************************************************************\147| calculate the gcd of the entries of N and divide N by it148\********************************************************************149g = N->array.SZ[0][0];150for(i=1;i<n;i++)151for(j=0;j<=i;j++)152g = GGT(g, N->array.SZ[i][j]);153if(g < 0)154g = -g;155if(g != 1)156{157for(i=0;i<n;i++)158for(j=0;j<n;j++)159N->array.SZ[i][j] /= g;160}161162printf("in vor_nei g %d\n",g);163*/164165return(N);166}167168169