GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#include"typedef.h"1/**************************************************************************\2@---------------------------------------------------------------------------3@---------------------------------------------------------------------------4@ FILE: shortest.c5@---------------------------------------------------------------------------6@---------------------------------------------------------------------------7@8\**************************************************************************/910#define EPS 0.0011112static int n, max, *vec, anzahl, con;13static int **grn; /* Gram matrix */14static int **ba; /* basis transformation matrix */15static double **mo, *ge;16static matrix_TYP *SV;17static int SV_size, SV_ext;181920static double scapr(i, j)21int i, j;22{23double r, *moi, *moj;24int l;2526r = grn[i][j];27moi = mo[i];28moj = mo[j];29for (l = 0; l <= j-1; ++l)30r -= ge[l] * moi[l] * moj[l];31if (ge[j] == 0)32{33printf("Error: found norm 0 vector\n");34exit(3);35}36r = r / ge[j];37return r;38}3940static double orth(i)41int i;42{43double r, *moi;44int l;4546r = grn[i][i];47moi = mo[i];48for (l = 0; l <= i-1; ++l)49r -= ge[l] * moi[l] * moi[l];50return r;51}5253/*---------------------------------------------------------*\54| makes model of the lattice (with same scalarproducts)55\*__________________________________________________________*/5657static void modellmachen(a, e)58int a, e;59{60int i, j;6162if (a == 0)63{64ge[0] = grn[0][0];65i = 1;66}67else68i = a;69while (i <= e)70{71for (j = 0; j < i; ++j)72mo[i][j] = scapr(i, j);73ge[i] = orth(i);74++i;75}76}7778static int iround(r)79double r;80{81int i;8283if (r >= 0)84i = (int)(2*r + 1) / 2;85else86i = -(int)(2*(-r) + 1) / 2;87return i;88}8990static void red(k, l)91int k, l;92{93double r, *mok, *mol;94int i, ir, *bak, *bal, *grnk, *grnl;9596r = mo[k][l];97if (2*r > 1.0 || 2*r < -1.0)98{99ir = iround(r);100mok = mo[k];101bak = ba[k];102grnk = grn[k];103mol = mo[l];104bal = ba[l];105grnl = grn[l];106for (i = 0; i < n; ++i)107{108mok[i] -= ir * mol[i];109bak[i] -= ir * bal[i];110grnk[i] -= ir * grnl[i];111}112for (i = 0; i < n; ++i)113grn[i][k] -= ir * grn[i][l];114}115}116117static int interchange(k)118int k;119{120int i, z, *zp;121122zp = ba[k];123ba[k] = ba[k-1];124ba[k-1] = zp;125126zp = grn[k];127grn[k] = grn[k-1];128grn[k-1] = zp;129130for (i = 0; i < n; ++i)131{132z = grn[i][k];133grn[i][k] = grn[i][k-1];134grn[i][k-1] = z;135}136if (k > 1)137return k-1;138else139return k;140}141142static void reduzieren(k)143int k;144{145int l;146147for (l = k-2; l >= 0; --l)148red(k, l);149}150151152/* prints the vector corresponding to vec */153/* in the model and its length */154155static void vecschr(m, d)156int m;157double d;158{159int i, j, entry;160int l;161int *v;162163l = iround(d);164if(l<max)165{166max = l;167for(i=0;i<SV->rows;i++)168free(SV->array.SZ[i]);169SV_size = SV_ext;170SV->rows = 0;171if((SV->array.SZ = (int **)realloc(SV->array.SZ, SV_size *sizeof(int *))) == 0)172exit(2);173anzahl = 0;174}175anzahl++;176if(SV->rows == SV_size)177{178SV_size += SV_ext;179if((SV->array.SZ = (int **)realloc(SV->array.SZ, SV_size *sizeof(int *))) == 0)180exit(2);181}182if((v = (int *)malloc((n+1) *sizeof(int))) == 0)183exit(2);184for (i = 0; i < m; ++i)185{186v[i] = 0;187for (j = 0; j < m; ++j)188v[i] += vec[j] * ba[j][i];189}190v[m] = l;191SV->array.SZ[SV->rows] = v;192SV->rows++;193}194195196/* recursion for finding shortest vectors */197198static void shrt(c, damage)199int c;200double damage;201{202double x, gec;203int i, j;204205if (c == -1)206{207for (i = 0; i < n && vec[i] == 0; ++i);208if (i == n)209con = 1;210else211{212vecschr(n, damage);213}214}215else216{217x = 0.0;218for (j = c+1; j < n; ++j)219x += vec[j] * mo[j][c];220i = -iround(x);221gec = ge[c];222if (gec*(x+i)*(x+i) + damage < max + EPS)223{224while ((gec*(x+i)*(x+i) + damage <= max + EPS) ||225(x + i <= 0))226++i;227--i;228while ((gec*(x+i)*(x+i) + damage < max + EPS) &&229con == 0)230{231vec[c] = i;232shrt(c-1, gec*(x+i)*(x+i) + damage);233--i;234}235}236}237}238239240241242/**************************************************************************\243@---------------------------------------------------------------------------244@ matrix_TYP *shortest(mat, min_norm)245@ matrix_TYP *mat;246@ int *min_norm;247@248@ The function callulates the shortest vectors of the integral, symmetric,249@ positiv definite matrix 'mat'.250@ The minmum251@252@ m(mat) := min{ v * mat *v^{tr} | v in Z^n and v not 0}253@254@ is returned in the pointer 'min_norm'. The shortest vectors are the vectors255@ with n(x) = min(x).256@ They are stored as rows in the returned matrix called 'SV' in the following.257@ For 'SV' n+1 columns are allocated. The last column contains the norm n(x).258@ Although n+1 columns are allocated, SV->cols = n.259@260@ Warning: if 'mat' is not positiv definite, the function runs into an261@ infinite loop.262@---------------------------------------------------------------------------263@264\**************************************************************************/265matrix_TYP *shortest(mat, min_norm)266matrix_TYP *mat;267int *min_norm;268{269int i, j, ak, bk;270double de, cst = 0.75;271char c;272matrix_TYP *erg;273274extern matrix_TYP *init_mat();275276anzahl = 0;277con = 0;278n = mat->rows;279SV_ext = n * (n+1)/2;280SV = init_mat(1, n+1, "");281SV->cols--;282SV->rows = 0;283free(SV->array.SZ[0]);284/* inserted the next line 15/1/97 tilman */285free(SV->array.SZ);286287if((SV->array.SZ = (int **)malloc(SV_ext *sizeof(int *))) == 0)288exit(2);289SV_size = SV_ext;290if ((grn = (int**)malloc(n * sizeof(int*))) == 0)291exit (2);292if ((ba = (int**)malloc(n * sizeof(int*))) == 0)293exit (2);294if ((mo = (double**)malloc(n * sizeof(double*))) == 0)295exit (2);296if ((ge = (double*)malloc(n * sizeof(double))) == 0)297exit (2);298if ((vec = (int*)malloc(n * sizeof(int))) == 0)299exit (2);300for (i = 0; i < n; ++i)301{302vec[i] = 0;303if ((grn[i] = (int*)malloc(n * sizeof(int))) == 0)304exit (2);305if ((ba[i] = (int*)malloc(n * sizeof(int))) == 0)306exit (2);307if ((mo[i] = (double*)malloc(n * sizeof(double))) == 0)308exit (2);309for (j = 0; j < n; ++j)310{311ba[i][j] = 0;312mo[i][j] = 0.0;313}314ba[i][i] = 1;315mo[i][i] = 1.0;316317/* read the Gram matrix (can be square or lower triangular) */318for (j = 0; j <= i; ++j)319{320grn[i][j] = mat->array.SZ[i][j];321grn[j][i] = grn[i][j];322}323}324max = mat->array.SZ[0][0];325for(i=1;i<n;i++)326{327if(mat->array.SZ[i][i] < max)328max = mat->array.SZ[i][i];329}330331bk = 1;332while (bk < n)333{334ak = bk - 1;335modellmachen(ak, bk);336red(bk, bk-1);337if (ge[bk] < ((cst - mo[bk][bk-1]*mo[bk][bk-1]) * ge[bk-1]))338{339bk = interchange(bk);340modellmachen(bk-1, bk);341if (bk > 1)342--bk;343}344else345{346if (bk > 1)347reduzieren(bk);348++bk;349}350}351352shrt(n-1, 0.0); /* recursively calculate the vectors up to length max */353354for(i=0;i<n;i++)355{356free(grn[i]);357free(ba[i]);358free(mo[i]);359}360free(grn); free(ba); free(mo); free(ge); free(vec);361362erg = SV;363SV = NULL;364*min_norm = max;365366return(erg);367}368369370