GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#include "typedef.h"1#include "tools.h"2#include "matrix.h"34/**************************************************************************\5@---------------------------------------------------------------------------6@---------------------------------------------------------------------------7@ FILE: p_solve.c8@---------------------------------------------------------------------------9@---------------------------------------------------------------------------10@11\**************************************************************************/1213/**************************************************************************\14@---------------------------------------------------------------------------15@ matrix_TYP **p_solve (anz, L_mat, R_mat, option)16@ int *anz;17@ matrix_TYP **L_mat, **R_mat ;18@ int option;19@20@ Solves L_mat[i] * X = X * R_mat[i] modulo act_prime simultaneous21@ for 0 <= i<= anz.22@ The return is a basis of the space of solution.23@ the dimension of this space is returned by the pointer anz.24@25@---------------------------------------------------------------------------26@27\**************************************************************************/2829/*{{{}}}*/30/*{{{ p_solve*/31matrix_TYP **p_solve (anz, L_mat, R_mat, option)32int *anz;33matrix_TYP **L_mat, **R_mat ;34int option;35{36/*{{{ variables*/37int **M, **N, *v, f, help, flag ;38int *M_j, *M_act, numax;39matrix_TYP **E;40boolean L_null, R_null ;41int *ss, *nuin;42int i, j, jj, k, kk, l, cR, cL, cM, rR, rL, rM, rN, rg = 0, act, p;43int **TS;4445/*}}} */46/*{{{ var init & error-check*/4748p = act_prime;49L_null = (L_mat == NULL);50R_null = (R_mat == NULL);5152cL = L_null ? 1 : L_mat[0]->cols;53rL = L_null ? 1 : L_mat[0]->rows;54rR = R_null ? 1 : R_mat[0]->rows;55cR = R_null ? 1 : R_mat[0]->cols;5657if(!(L_null || R_null)) {58if((cL != rL) || (rR != cR)) {59fprintf(stderr,"Error in input: Matrizes of wrong dimension\n");60exit(3);61}62}6364cM = cL * rR;65rM = *anz*rL*cR;66rN = rL * cR;67rg = *anz*cR;6869/*}}} */70/*{{{ alloc memory*/71N = (int **)malloc(rN*sizeof(int *));72M = (int **)malloc(rM*sizeof(int *));73nuin = (int *) malloc((cM+1)*sizeof(int));74ss = (int *) malloc(cM*sizeof(int));7576/*}}} */7778for ( i = 0 ; i < *anz; i++) {79/*{{{ */80if ( !L_null ) {81if ( (L_mat[i]->cols != cL) || (L_mat[i]->rows != rL)) {82fprintf (stderr, "Error in input\n");83exit (3);84}85}86if ( !R_null ) {87if (( R_mat[i]->rows != rR ) || ( R_mat[i]->cols != cR )) {88fprintf (stderr, "Error in input\n");89exit (3);90}91}9293for ( j = 0; j < rN; j++ ) {94N[j] = (int *)calloc(cM,sizeof(int));95}9697if ( !L_null ) {98/*{{{ */99flag = L_mat[i]->prime != 0;100TS = L_mat[i]->array.SZ;101for ( j = 0, jj = 0; j < rL; j++, jj += rR) {102for ( k = 0, kk = 0; k < cL; k++, jj -= rR) {103if(flag) {104help = TS[j][k];105} else if ((help = TS[j][k] % p) < 0) {106help += p;107}108if(help) {109for( l = 0; l < rR; l++,jj++, kk++) {110N[jj][kk] = help;111}112} else {113jj += rR;114kk += rR;115}116}117}118/*}}} */119}120if ( !R_null ) {121/*{{{ */122flag = R_mat[i]->prime != 0;123TS = R_mat[i]->array.SZ;124for ( j = 0; j < cR; j++) {125for ( k = 0; k < rR; k++) {126if(flag) {127help = TS[k][j];128} else if ((help = TS[k][j] % p) < 0) {129help += p;130}131if(help) {132for(l=0,jj=j, kk=k; l<cL; l++, jj+=cR, kk+=rR) {133N[jj][kk] = S(N[jj][kk],-help);134}135}136}137}138/*}}} */139}140141/* permutierte Eingabe in Liste */142for(j = 0; j < rL; j++) {143for(k = 0; k < cR; k++) {144M[j*rg+i*cR+k] = N[(rL-1-j)*cR+k];145}146}147/*}}} */148}149free(N);150rg = 0;151/*------------------------------------------------------------*\152| Gauss Algorithm |153\*------------------------------------------------------------*/154for ( i = 0; i < cM; i++ ) {155#if 0156/*{{{ auskommentiert*/157for(pri = 0; pri < rM; pri++) {158for(prj = 0; prj < cM; prj++)159if(M[pri][prj] != 0)160printf("%d ",M[pri][prj]);161else162printf(" ");163printf("\n");164}165printf(" i = %d \n", i);166/* ende der Einfuegung */167/*}}} */168#endif169ss[i] = -1;170/*---------------------------------------------------------*\171| Find the row with non-zero entry in i-th column |172\*---------------------------------------------------------*/173for ( j = rg; (j < rM) && (M[j][i] == 0); j++);174if ( j == rM ) {175continue;176}177act = j;178/*---------------------------------------------------------*\179| Normalize act-th row and mark the non-zero entries |180\*---------------------------------------------------------*/181nuin[0] = 1;182f = P(1,-M[j][i]);183for ( k = i ; k < cM; k++ ) {184if((help = M[act][k])) {185M[act][k] = P(help,f);186nuin[nuin[0]++] = k;187}188}189/*---------------------------------------------------------*\190| Swap act-th row and rg-th row |191\*---------------------------------------------------------*/192v = M[rg];193M[rg] = M[act];194M[act] = v;195ss[rg] = i;196act = rg ++;197/*---------------------------------------------------------*\198| Clear i-th column downwards |199\*---------------------------------------------------------*/200M_act = M[act];201for ( j = act+1; j < rM; j++) {202if ( (f = S(0,-M[j][i])) != 0 ) {203M_j = M[j];204M_j[i] = 0;205numax = nuin[0];206if( f == 1) {207for(k=2; k < numax; ++k ) {208kk = nuin[k];209M_j[kk] = S(M_j[kk],M_act[kk]);210}211} else {212for(k=2; k < numax; ++k ) {213kk = nuin[k];214M_j[kk] = S(M_j[kk],P(M_act[kk],f));215}216}217}218}219}220221if ( (*anz = cM - rg) != 0 ) {222/*{{{ */223/*========================================================*\224|| Matrix has not full rank: clear it upwards ||225\*=========================================================*/226for (i = rg-1; i > 0; i--) {227/*{{{ */228nuin[0] = 2;229nuin[1] = ss[i];230M_act = M[i];231for(j = ss[i]+1; j < cM; j++) {232if(M_act[j]) {233nuin[nuin[0]++] = j;234}235}236if(nuin[0] == 2) {237j = ss[i];238for (k = i-1; k > 0; k--) {239M[k][j] = 0;240}241} else {242for ( j = i-1; j >= 0; j--) {243if ( (f = S(0,-M[j][ss[i]])) != 0 ) {244M_j = M[j];245M_j[ss[i]] = 0;246numax = nuin[0];247if( f == 1) {248for(k=2; k < numax; ++k ) {249kk = nuin[k];250M_j[kk] = S(M_j[kk],M_act[kk]);251}252} else {253for(k=2; k < numax; ++k ) {254kk = nuin[k];255M_j[kk] = S(M_j[kk],P(M_act[kk],f));256}257}258}259}260}261/*}}} */262}263if((option & 2) || (!L_null && !R_null) ) {264/*{{{ */265E = (matrix_TYP **)malloc(*anz*sizeof(matrix_TYP *));266for ( i = 0 , k = 0, l = 0; i < cM; i++ ) {267if ( i == ss[k] ) {268k ++;269continue;270}271E[l] = init_mat(cL, rR, "ip");272E[l]->prime = act_prime;273N = E[l]->array.SZ;274for ( j = 0; j < k; j ++) {275if ( M[j][i] != 0 ) {276N[ss[j]/rR][ss[j]%rR] = p-M[j][i];277}278}279N[i/rR][i%rR] = 1;280l ++;281}282/*}}} */283} else {284/*{{{ */285E = (matrix_TYP **)malloc(1*sizeof(matrix_TYP *));286E[0] = init_mat(*anz, cM,"ip");287E[0]->prime = act_prime;288N = E[0]->array.SZ;289for ( i = 0 , k = 0, l = 0; i < cM; i++ ) {290if ( i == ss[k] ) {291k ++;292continue;293}294for ( j = 0; j < k; j ++) {295if ( M[j][i] != 0 ) {296N[l][ss[j]] = p-M[j][i];297}298}299N[l][i] = 1;300l ++;301}302*anz = 1;303/*}}} */304}305/*}}} */306} else {307E = NULL;308}309310/*{{{ free memory*/311for (i = 0; i < rM; i++ ) {312free(M[i]);313}314free(M);315free(ss);316free(nuin);317/*}}} */318319return (E);320}321/*}}} */322323324