GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#include"typedef.h"1/**************************************************************************\2@---------------------------------------------------------------------------3@---------------------------------------------------------------------------4@ FILE: dsylv.c5@---------------------------------------------------------------------------6@---------------------------------------------------------------------------7@8\**************************************************************************/910/* changed tilman 2/09/97 because this is far higher than the precision11of modern machines (and causes trouble)12static double eps = 0.000001; */13static double eps = 0.00000000001;1415static double **mat_to_double(M)16matrix_TYP *M;17{18int i,j;19double **D;20if((D = (double **)malloc(M->rows *sizeof(double *))) == 0)21{22printf("malloc failed in mat_to_double\n");23exit(2);24}25for(i=0;i<M->rows;i++)26{27if((D[i] = (double *)malloc((i+1) *sizeof(double))) == 0)28{29printf("malloc failed in mat_to_double\n");30exit(2);31}32}33for(i=0;i<M->rows;i++)34for(j=0;j<=i;j++)35D[i][j] = ((double) M->array.SZ[i][j]);36return(D);37}383940static int pivot(A, step, n)41double **A;42int step, n;43{44int i,j,k, found;45double max;46int ipos, jpos;47double tmp;4849/*****************************************************************************\50| search for a nonzero diagonal entry51\*****************************************************************************/52max = fabs(A[step][step]);53if (max < eps){54max = A[step][step] = 0.0;55}56ipos = step;57for(i=step+1;i<n;i++)58{5960/* inserted tilman 02/09/97, accuracy errors may occur intermediate */61if((fabs(A[i][i]) < eps))62A[i][i] = 0.0;63if((fabs(A[i][i]) > max))64{65max = fabs(A[i][i]);66ipos = i;67}68}69/*****************************************************************************\70| if there is a nonzero diagonal entry, swap colum 'step' und colmn 'ipos'71| and swap row 'step' and row 'ipos', where A[ipos][ipos] has the maximal72| absulute value.73\*****************************************************************************/74if(max != 0.0)75{76if (ipos == step)77return(1);78tmp = A[step][step];79A[step][step] = A[ipos][ipos];80A[ipos][ipos] = tmp;81for(i=step+1;i<ipos;i++)82{ tmp = A[i][step]; A[i][step] = A[ipos][i]; A[ipos][i] = tmp;}83for(i= ipos+1;i<n;i++)84{ tmp = A[i][step]; A[i][step] = A[i][ipos]; A[i][ipos] = tmp;}85return(1);86}8788/*****************************************************************************\89| if all diagonal entries are zero, find an nonzero entry A[ipos][jpos]90| if all entries are zero return(0)91\*****************************************************************************/92ipos = step+1;93jpos = step;94found = FALSE;95for(i=step+1;i<n && found == FALSE;i++)96for(j=step;j<i && found == FALSE;j++)97{98if(A[i][j] != 0.0)99{ipos = i; jpos = j; found = TRUE;}100}101if(found == FALSE)102return(0);103104/*****************************************************************************\105| swap colum 'step' and column 'jpos' and swap row 'step' and row 'jpos'106| Then A[ipos][step] is nonzero.107\*****************************************************************************/108for(i=step+1;i<jpos;i++)109{ tmp = A[i][step]; A[i][step] = A[jpos][i]; A[jpos][i] = tmp;}110for(i= jpos+1;i<n;i++)111{ tmp = A[i][step]; A[i][step] = A[i][jpos]; A[i][jpos] = tmp;}112/*****************************************************************************\113| add column 'ipos' to column 'step' and add row 'ipos' to row 'step'114| Then A[step][step] is nonzero115\*****************************************************************************/116A[step][step] = A[ipos][step] * 2.0;117for(i=step+1;i<ipos;i++)118A[i][step] += A[ipos][i];119for(i=ipos+1;i<n;i++)120A[i][step] += A[i][ipos];121return(1);122}123124125static void col_clear(A, step, n)126double **A;127int step, n;128{129int i,j;130double f;131for(i=step+1; i<n; i++)132{133/* changed this to a numerically more stable version:134if(fabs(A[i][step]) > eps)135{136f = A[i][step]/A[step][step];137for(j=step+1;j<=i;j++)138A[i][j] -= A[j][step] * f;139for(j=i+1;j<n;j++)140A[j][i] -= A[j][step] * f;141A[i][step] = 0.0;142}143else144{145A[i][step] = 0.0;146} */147148for(j=step+1;j<=i;j++)149A[i][j] -= (A[j][step] * A[i][step])/A[step][step];150for(j=i+1;j<n;j++)151A[j][i] -= (A[j][step] * A[i][step])/A[step][step];152A[i][step] = 0.0;153154}155}156157static void double_symmat_put(D,n)158double **D;159int n;160{161int i,j;162for(i=0;i<n;i++)163{164for(j=0;j<=i;j++)165printf("%e ", D[i][j]);166printf("\n");167}168}169170171static int diag_definite_test(D, n)172double **D;173int n;174{175int i;176int o,u,z;177178o = u = z = 0;179for(i=0;i<n;i++)180{181if(fabs(D[i][i]) > eps)182{183if(D[i][i] > eps)184o = 1;185else186u = 1;187}188else189z = 1;190}191if(u == 0)192{193if(o == 0)194return(0);195if(z == 0)196return(2);197return(1);198}199if(o == 1)200return(-3);201if(z == 0)202return(-2);203return(-1);204}205206207208/**************************************************************************\209@---------------------------------------------------------------------------210@ matrix_TYP *dsylv(M)211@ matrix_TYP *M;212@213@ The return of 'dsylv' is a diagonal matrix D with diaogonal elements214@ D[i][i] in {-1,1,0}.215@ The function diagonalizes the symmetric matrix 'M' by simultanous row216@ and col-operations.217@ If the entry in the diagonalised matrix is positiv it is replaced218@ by 1, if negativ by -1, if zero by 0.219@ This is done with floating-point arithmetic.220@ So rounding errows may occur.221@ Therefore a diaogonal entry it is assumed to be zero222@ if its absolute value is less then eps.223@224@---------------------------------------------------------------------------225@226\**************************************************************************/227matrix_TYP *dsylv(M)228matrix_TYP *M;229{230int i,n,step, nonzero;231double **D;232double eps_new;233matrix_TYP *A;234int pos, neg;235236extern matrix_TYP *init_mat();237238D = mat_to_double(M);239n = M->cols;240nonzero = pivot(D, 0, n);241for(step = 0;step<n-1 && nonzero == TRUE ;step++)242{243col_clear(D, step, n);244245if(step+1 != n)246nonzero = pivot(D, step+1, n);247}248pos = neg = 0;249for(i=0;i<n;i++)250{251if(fabs(D[i][i]) > eps)252{253if(D[i][i] > eps)254pos++;255else256neg++;257}258}259A = init_mat(n,n,"");260A->flags.Symmetric = A->flags.Diagonal = TRUE;261for(i=0;i<pos;i++)262A->array.SZ[i][i] = 1;263for(i=pos; i<pos+neg;i++)264A->array.SZ[i][i] = -1;265for(i=0;i<n;i++)266free(D[i]);267free(D);268return(A);269}270271272273274/**************************************************************************\275@---------------------------------------------------------------------------276@ int definite_test(M)277@ matrix_TYP *M;278@279@ Does the same as 'dsolve' but testes during the Diagonalisation280@ if the matrix is indefinite.281@ The return is282@283@ 0: if M is zero284@ 1: if M is positiv semidefinite, but not positiv definite.285@ 2: if M is positiv definite.286@ -1: if M is negativ semidefinite, but not negativ definite.287@ -2: if M is negativ definite.288@ -3: if M is indefinite.289@290@---------------------------------------------------------------------------291@292\**************************************************************************/293294int definite_test(M)295matrix_TYP *M;296{297int i,n,step, nonzero;298double **D;299int test;300301302D = mat_to_double(M);303n = M->cols;304test = diag_definite_test(D, n);305if(test == -3)306{307for(i=0;i<n;i++)308free(D[i]);309310/* inserted the next line 15/1/97 tilman */311free(D);312313return(-3);314}315nonzero = pivot(D, 0, n);316for(step = 0;step<n-1 && nonzero == TRUE ;step++)317{318col_clear(D, step, n);319test = diag_definite_test(D, n);320if(test == -3)321{322for(i=0;i<n;i++)323free(D[i]);324325/* inserted the next line 15/1/97 tilman */326free(D);327328return(-3);329}330if(step+1 != n)331nonzero = pivot(D, step+1, n);332}333for(i=0;i<n;i++)334free(D[i]);335336/* inserted the next line 15/1/97 tilman */337free(D);338339return(test);340}341342343