GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#include "typedef.h"1#include "tools.h"23/**************************************************************************\4@---------------------------------------------------------------------------5@---------------------------------------------------------------------------6@ FILE: p_lse_solve.c7@---------------------------------------------------------------------------8@---------------------------------------------------------------------------9@10\**************************************************************************/11/********************************************************************\12@ The function 'matrix_TYP **p_lse_solve(A, B, anz, p)'13@ calculates for given matrices A and B the solutions of14@ A * X = B (modulo p)15@ where A is a (n x m)- matrix and B a (n x r) matrix with integral16@ entries (treated as elements of the field with p elements).17@ The number of the returned matrices is given back by the pointer 'anz'.18@19@ If no solution exists a NULL-pointer is returned, and 'anz' is20@ set to 0.21@22@ If a solution of the inhomogenous equation exists, it is23@ returned via the (m x r)-matrix X[0] ( X is the matrix_TYP ** returned by24@ the functions.25@ The (1 x m)-matrices X[1],...,X[anz-1] form a basis of the solutions of26@ the transposed homogenous equation X * A^{tr} = 0.27@28\********************************************************************/29matrix_TYP **p_lse_solve(A, B, anz, p)30matrix_TYP *A, *B;31int *anz, p;32{33matrix_TYP **X;34int **C, **D;35int i,j,k,step, cpos, f;36int m,n,r;3738int inhomo,39found,40rang = 0, /* inserted tilman 21/07/97: if the matrix is zero mod p,41a different setting causes trouble */42Xsize;4344int *tmp, *pos;45int phalbe, mphalbe;4647extern matrix_TYP *init_mat();4849phalbe = p/2;50mphalbe = -phalbe;51if(p == 2)52mphalbe = 0;53n = A->rows, m = A->cols;54if( (C = (int **)malloc(n *sizeof(int *))) == 0)55{56printf("malloc of C in 'p_lse_solve' failed\n");57exit(2);58}59for(i=0;i<n;i++)60{61if( (C[i] = (int *)malloc(m *sizeof(int))) == 0)62{63printf("malloc of C[%d] in 'p_lse_solve' failed\n", i);64exit(2);65}66for(j=0;j<m;j++)67C[i][j] = A->array.SZ[i][j];68}69if(B == NULL)70inhomo = FALSE;71else72{73inhomo = TRUE;74r = B->cols;75if( (D = (int **)malloc(n *sizeof(int *))) == 0)76{77printf("malloc of D in 'p_lse_solve' failed\n");78exit(2);79}80for(i=0;i<n;i++)81{82if( (D[i] = (int *)malloc(r *sizeof(int))) == 0)83{84printf("malloc of D[%d] in 'p_lse_solve' failed\n", i);85exit(2);86}87for(j=0;j<r;j++)88D[i][j] = B->array.SZ[i][j];89}90}91if(inhomo && n != B->rows)92{93printf("You tried to solve A * X = B, where A has %d rows and B has %d rows\n", A->rows, B->rows);94printf("exit in 'p_lse_solve':\n");95exit(3);96}9798/*************************************************************************\99| reduce the entries in C and D modulo p100\*************************************************************************/101for(i=0;i<n;i++)102for(j=0;j<m;j++)103{104C[i][j] %= p;105if(C[i][j] > phalbe)106C[i][j] -= p;107if(C[i][j] < mphalbe)108C[i][j] += p;109}110if(inhomo)111{112for(i=0;i<n;i++)113for(j=0;j<r;j++)114{115D[i][j] %= p;116if(D[i][j] > phalbe)117D[i][j] -= p;118if(D[i][j] < mphalbe)119D[i][j] += p;120}121}122123/*************************************************************************\124| Make a row-gauss-algorithm on C and do simultanous row operations on D.125\*************************************************************************/126cpos = 0;127for(step = 0; step < n; step++)128{129/**************************************************************\130| search first column 'cpos' in C with nonzero entry C[i][cpos]131| and permute the rows 'step' and 'i'132\**************************************************************/133found = FALSE;134while(cpos < m && found == FALSE)135{136for(i=step; i<n && C[i][cpos] == 0;i++);137if(i == n)138cpos++;139else140found = TRUE;141}142if(found == TRUE)143{144rang = step+1;145if(i!= step)146{147tmp = C[i]; C[i] = C[step]; C[step] = tmp; tmp = NULL;148if(inhomo)149{ tmp = D[i]; D[i] = D[step]; D[step] = tmp; tmp = NULL;}150}151/******************************************************************\152| Clear the entries C[step+1][cpos],....,C[n][cpos]153\******************************************************************/154f = p_inv(C[step][cpos], p);155if(f > phalbe) f -= p;156if(f < mphalbe) f += p;157if(f != 1)158{159C[step][cpos] = 1;160for(i=cpos+1;i<m; i++)161{162C[step][i] = (C[step][i] * f)%p;163if(C[step][i] > phalbe) C[step][i] -=p;164if(C[step][i] < mphalbe) C[step][i] +=p;165}166C[step][cpos] = 1;167if(inhomo)168{169for(i=0;i<r;i++)170{171D[step][i] = (D[step][i] * f)%p;172if(D[step][i] > phalbe) D[step][i] -=p;173if(D[step][i] < mphalbe) D[step][i] +=p;174}175}176}177for(i=step+1;i<n;i++)178{179if(C[i][cpos] != 0)180{181f = C[i][cpos];182C[i][cpos] = 0;183for(j=cpos+1; j<m;j++)184{185C[i][j] = ( C[i][j] - f * C[step][j])%p;186if(C[i][j] > phalbe) C[i][j] -=p;187if(C[i][j] < mphalbe) C[i][j] +=p;188}189if(inhomo)190{191for(j=0;j<r;j++)192{193D[i][j] = ( D[i][j] - f * D[step][j])%p;194if(D[i][j] > phalbe) D[i][j] -=p;195if(D[i][j] < mphalbe) D[i][j] +=p;196}197}198}199}200}201}202203/********************************************************************\204| Now C is an upper triangular matrix and the number of nonzero rows205| is given by the variable 'rang'.206| If A[i][j] is the first non-zero entry in the i-th row (which has been207| made equal to 1),208| all the entries A[k][j] with k<i are made zero.209\********************************************************************/210for(i = rang-1; i >= 0; i--)211{212for(j=0; j<m && C[i][j] == 0; j++);213cpos = j;214for(j=0; j<i;j++)215{216f = C[j][cpos];217for(k=cpos+1;k<m;k++)218{219C[j][k] = (C[j][k] - f*C[i][k])%p;220if(C[j][k] > phalbe) C[j][k] -= p;221if(C[j][k] < mphalbe) C[j][k] += p;222}223C[j][cpos] = 0;224if(inhomo)225{226for(k=0;k<r;k++)227{228D[j][k] = (D[j][k] - f*D[i][k])%p;229if(D[j][k] > phalbe) D[j][k] -= p;230if(D[j][k] < mphalbe) D[j][k] += p;231}232}233}234}235/********************************************************************\236| Calculate a solution of the inhomogenous equation237\********************************************************************/238if(inhomo)239{240/********************************************************************\241| Check, whether a solution of the inhomogenous equation exists.242| If not return NULL-pointer243\********************************************************************/244found = FALSE;245for(i=rang;i<n && found == FALSE;i++)246for(j=0;j<r && found == FALSE; j++)247{248if(D[i][j] != 0) found = TRUE;249}250if(found == TRUE)251{252for(i=0;i<n;i++)253{ free(D[i]); free(C[i]);}254free(C); free(D);255*anz = 0;256return(NULL);257}258}259Xsize = m-rang+1;260*anz = Xsize;261if((X = (matrix_TYP **)malloc(Xsize *sizeof(matrix_TYP *))) == 0)262{263printf("malloc of X in 'p_lse_solve' failed\n");264exit(2);265}266267/*******************************************************************\268| pos[i] is the index j such that C[i][j] is the first nonzero269| entry in the i-th row of C270\*******************************************************************/271pos = NULL;272if((pos = (int *)malloc((rang+2) *sizeof(int))) == 0)273{274printf("malloc of 'pos' in 'p_lse_solve' failed\n");275exit(2);276}277278/* inserted tilman 11/4/97 */279pos++; pos[-1] = -1;280281for(i=0;i<rang;i++)282{283for(j=0;j<m && C[i][j] == 0; j++);284pos[i] = j;285}286pos[rang] = m;287if(inhomo)288{289/****************************************************************\290| Find a solution of the inhomogenous equation291\****************************************************************/292X[0] = init_mat(m, r, "");293for(i=0;i<r;i++)294for(j=0;j<rang;j++)295X[0]->array.SZ[pos[j]][i] = D[j][i];296for(i=0;i<n;i++)297free(D[i]);298free(D);299}300else301X[0] = NULL;302/****************************************************************\303| Find the solutions of the homogenous equation304\****************************************************************/305step=1;306307/* changed 11/4/97 tilman from308for(i=rang-1; i>= 0; i--) to */309for(i=rang-1; i>= (-1); i--)310{311for(j=pos[i]+1; j< pos[i+1]; j++)312{313X[step] = init_mat(1, m, "");314tmp = X[step]->array.SZ[0];315step++;316tmp[j] = -1;317for(k=0;k<=i;k++)318tmp[pos[k]] = C[k][j];319}320}321for(i=0;i<n;i++)322free(C[i]);323free(C);324325/* inserted tilman 11/4/97 */326free(--pos);327return(X);328}329330331