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: add_mat.c8@---------------------------------------------------------------------------9@---------------------------------------------------------------------------10@11\**************************************************************************/1213/**************************************************************************\14@---------------------------------------------------------------------------15@ matrix_TYP *imat_add (L_mat, R_mat, Lc, Rc)16@ matrix_TYP *L_mat, *R_mat ;17@ int Lc, Rc;18@19@ calculates Lc * L_mat + Rc * R_mat20@---------------------------------------------------------------------------21@22\**************************************************************************/23/*{{{}}}*/24/*{{{ imat_add, exported*/25matrix_TYP *imat_add (L_mat, R_mat, Lc, Rc)26matrix_TYP *L_mat, *R_mat ;27int Lc, Rc;28{29matrix_TYP *S_mat;30int **L, **R, **S, rS, cS;31int i, j;3233rS = L_mat->rows;34cS = L_mat->cols;35S_mat = init_mat(rS,cS,"");3637S_mat->flags.Symmetric=(R_mat->flags.Symmetric&&L_mat->flags.Symmetric);38S_mat->flags.Diagonal =(R_mat->flags.Diagonal && L_mat->flags.Diagonal);39S_mat->flags.Scalar =(R_mat->flags.Scalar && L_mat->flags.Scalar);40S_mat->flags.Integral =(R_mat->flags.Integral && L_mat->flags.Integral);4142/*43* ovfl_mul() is an expensive routine defined in ../tools/ovfl_mul.c44* It checks an integer-overflow using a division :(.45* But as the kgv should tend to grow fast, this seems to be saver46*/47if(L_mat->kgv != 1) {48Rc = ovfl_mul( Rc, L_mat->kgv );49}50if(R_mat->kgv != 1) {51Lc = ovfl_mul( Lc, R_mat->kgv );52}53S_mat->kgv = ovfl_mul( L_mat->kgv , R_mat->kgv );5455S = S_mat->array.SZ;56R = R_mat->array.SZ;57L = L_mat->array.SZ;58#ifdef TEST_OVFL59for ( i = 0 ; i < rS; i++) {60if(S_mat->flags.Diagonal) {61S[i][i] = ovfl_mul( Lc , L[i][i] ) + ovfl_mul( Rc , R[i][i] );62} else {63for ( j = 0 ; j < cS ; j ++ ) {64S[i][j] = ovfl_mul( Lc , L[i][j] ) + ovfl_mul( Rc , R[i][j] );65}66}67}68#else69for ( i = 0 ; i < rS; i++) {70if(S_mat->flags.Diagonal) {71S[i][i] = Lc * L[i][i] + Rc * R[i][i];72} else {73for ( j = 0 ; j < cS ; j ++ ) {74S[i][j] = Lc * L[i][j] + Rc * R[i][j];75}76}77}78#endif79Check_mat(S_mat);80return(S_mat);81}8283/*}}} */84/*{{{ imat_addeq, exported*/8586/**************************************************************************\87@---------------------------------------------------------------------------88@ matrix_TYP *imat_addeq (L_mat, R_mat, Lc, Rc)89@ matrix_TYP *L_mat, *R_mat ;90@ int Lc, Rc;91@92@ calculates L_mat = Lc*L_mat + Rc*R_mat93@94@---------------------------------------------------------------------------95@96\**************************************************************************/97matrix_TYP *imat_addeq (L_mat, R_mat, Lc, Rc)98matrix_TYP *L_mat, *R_mat ;99int Lc, Rc;100{101102int **L, **R, rS, cS;103int i, j;104105rS = L_mat->rows;106cS = L_mat->cols;107108L_mat->flags.Symmetric=(R_mat->flags.Symmetric&&L_mat->flags.Symmetric);109L_mat->flags.Diagonal =(R_mat->flags.Diagonal && L_mat->flags.Diagonal);110L_mat->flags.Scalar =(R_mat->flags.Scalar && L_mat->flags.Scalar);111L_mat->flags.Integral =(R_mat->flags.Integral && L_mat->flags.Integral);112113/*114* ovfl_mul() is an expensive routine defined in ../tools/ovfl_mul.c115* It checks an integer-overflow using a division :(.116* But as the kgv should tend to grow fast, this seems to be saver117*/118if(L_mat->kgv != 1) {119Rc = ovfl_mul( Rc, L_mat->kgv );120}121if(R_mat->kgv != 1) {122Lc = ovfl_mul( Lc, R_mat->kgv );123}124L_mat->kgv = ovfl_mul( L_mat->kgv , R_mat->kgv );125126R = R_mat->array.SZ;127L = L_mat->array.SZ;128#ifdef TEST_OVFL129for ( i = 0 ; i < rS; i++) {130if(L_mat->flags.Diagonal) {131L[i][i] = ovfl_mul( Lc , L[i][i] ) + ovfl_mul( Rc , R[i][i] );132} else {133for ( j = 0 ; j < cS ; j ++ ) {134L[i][j] = ovfl_mul( Lc , L[i][j] ) + ovfl_mul( Rc , R[i][j] );135}136}137}138#else139for ( i = 0 ; i < rS; i++) {140if(L_mat->flags.Diagonal) {141L[i][i] = Lc * L[i][i] + Rc * R[i][i];142} else {143for ( j = 0 ; j < cS ; j ++ ) {144L[i][j] = Lc * L[i][j] + Rc * R[i][j];145}146}147}148#endif149Check_mat(L_mat);150return(L_mat);151}152153154/**************************************************************************\155@---------------------------------------------------------------------------156@ matrix_TYP *rmat_add (L_mat, R_mat, L_coeff, R_coeff)157@ matrix_TYP *L_mat, *R_mat ;158@ rational L_coeff, R_coeff;159@160@ calculates L_coeff * L_mat + R_coeff * R_mat161@---------------------------------------------------------------------------162@163\**************************************************************************/164/*}}} */165/*{{{ rmat_add, exported*/166matrix_TYP *rmat_add (L_mat, R_mat, L_coeff, R_coeff)167matrix_TYP *L_mat, *R_mat ;168rational L_coeff, R_coeff;169{170matrix_TYP *S_mat;171int **S, rS, cS , temp1, temp2;172int i, j;173rational Lc, Rc;174175temp1 = temp2 = 0;176Lc.z = L_coeff.z;177Lc.n = L_coeff.n;178Rc.z = R_coeff.z;179Rc.n = R_coeff.n;180Normal( &Lc );181Normal( &Rc );182183rS = L_mat->rows;184cS = L_mat->cols;185S_mat = init_mat(rS,cS,"il");186187S_mat->flags.Symmetric=(R_mat->flags.Symmetric && L_mat->flags.Symmetric);188S_mat->flags.Diagonal =(R_mat->flags.Diagonal && L_mat->flags.Diagonal);189S_mat->flags.Scalar =(R_mat->flags.Scalar && L_mat->flags.Scalar);190S_mat->flags.Integral =(R_mat->flags.Integral && L_mat->flags.Integral);191if(!(S_mat->flags.Integral)) {192temp1= GGT(Lc.z, L_mat->kgv);193temp2= GGT(Rc.z, R_mat->kgv);194Lc.z = Lc.z / temp1 * R_mat->kgv / temp2 * Rc.n;195Normal(&Lc);196Rc.z = Rc.z / temp2 * L_mat->kgv / temp1 * Lc.n;197Normal(&Rc);198199S_mat->kgv = L_mat->kgv * R_mat->kgv * Lc.n * Rc.n;200S_mat->kgv /= temp1;201S_mat->kgv /= temp2;202if (S_mat->kgv == 1) {203S_mat->flags.Integral = TRUE;204}205}206else {207if((Lc.n == 1) && (Rc.n == 1)) {208S_mat->kgv = 1;209} else {210S_mat->kgv = Lc.n * Rc.n ;211S_mat->flags.Integral = FALSE;212Lc.z *= Rc.n;213Rc.z *= Lc.n;214}215}216S= S_mat->array.SZ;217for ( i = 0 ; i < rS; i++) {218if(S_mat->flags.Diagonal) {219S[i][i] = Lc.z * L_mat->array.SZ[i][i] + Rc.z * R_mat->array.SZ[i][i];220} else {221for ( j = 0 ; j < cS ; j ++ ) {222S[i][j] = Lc.z * L_mat->array.SZ[i][j] + Rc.z * R_mat->array.SZ[i][j];223}224}225}226227Check_mat(S_mat);228return(S_mat);229}230231/**************************************************************************\232@---------------------------------------------------------------------------233@ matrix_TYP *rmat_addeq(L_mat, R_mat, L_coeff, R_coeff)234@ matrix_TYP *L_mat, *R_mat ;235@ rational L_coeff, R_coeff;236@237@ calculates L_coeff = L_coeff * L_mat + R_coeff * R_mat238@---------------------------------------------------------------------------239@240\**************************************************************************/241/*}}} */242/*{{{ rmat_addeq, exported*/243matrix_TYP *rmat_addeq (L_mat, R_mat, L_coeff, R_coeff)244matrix_TYP *L_mat, *R_mat ;245rational L_coeff, R_coeff;246{247int **L, **R, rS, cS , temp1, Rk;248int i, j;249rational Rc, Lc;250251Rk =252temp1 = 0;253rS = L_mat->rows;254cS = L_mat->cols;255Lc.z= L_coeff.z;256Lc.n= L_coeff.n;257Rc.z= R_coeff.z;258Rc.n= R_coeff.n;259Normal( &Lc );260Normal( &Rc );261262L_mat->flags.Symmetric=(R_mat->flags.Symmetric && L_mat->flags.Symmetric);263L_mat->flags.Diagonal =(R_mat->flags.Diagonal && L_mat->flags.Diagonal);264L_mat->flags.Scalar =(R_mat->flags.Scalar && L_mat->flags.Scalar);265L_mat->flags.Integral =(R_mat->flags.Integral && L_mat->flags.Integral);266if(!(L_mat->flags.Integral)) {267Lc.n= L_coeff.n * L_mat->kgv;268Normal(&Lc);269Rc.n= R_coeff.n * R_mat->kgv;270Normal(&Rc);271temp1= GGT( Lc.n, Rc.n);272Lc.z= Lc.z * Rc.n / temp1;273Rc.z= Rc.z * Lc.n / temp1;274L_mat->kgv= Lc.n * Rc.n / temp1;275if (L_mat->kgv == 1) {276L_mat->flags.Integral = TRUE;277}278} else {279if((L_coeff.n == 1) && (R_coeff.n == 1)) {280L_mat->kgv = 1;281} else {282temp1= GGT(Lc.n,Rc.n);283L_mat->kgv = Lc.n * Rc.n / temp1;284L_mat->flags.Integral = FALSE;285Lc.z = Lc.z * Rc.n / temp1;286Rc.z = Rc.z * Lc.n /temp1;287}288}289L = L_mat->array.SZ;290R = R_mat->array.SZ;291for ( i = 0 ; i < rS; i++) {292if(L_mat->flags.Diagonal) {293L[i][i] = L[i][i] * Lc.z + Rc.z * R[i][i];294} else {295for ( j = 0 ; j < cS ; j ++ ) {296L[i][j] = L[i][j] * Lc.z + Rc.z*R[i][j];297}298}299}300Check_mat(L_mat);301return(L_mat);302}303304/*}}} */305/*{{{ pmat_add, exported*/306307/**************************************************************************\308@---------------------------------------------------------------------------309@ matrix_TYP *pmat_add (L_mat, R_mat, L_coeff, R_coeff)310@ matrix_TYP *L_mat, *R_mat ;311@ int L_coeff, R_coeff;312@313@ calculates L_coeff * L_mat + R_coeff * R_mat modulo L_mat->prime314@---------------------------------------------------------------------------315@316\**************************************************************************/317matrix_TYP *pmat_add (L_mat, R_mat, L_coeff, R_coeff)318matrix_TYP *L_mat, *R_mat ;319int L_coeff, R_coeff;320{321matrix_TYP *S_mat;322int **L, **R, **A, rS, cS ;323int i, j;324325rS = L_mat->rows;326cS = L_mat->cols;327S_mat = init_mat(rS,cS,"p");328S_mat->prime = L_mat->prime;329S_mat->flags.Symmetric = (R_mat->flags.Symmetric&&L_mat->flags.Symmetric);330S_mat->flags.Diagonal = (R_mat->flags.Diagonal && L_mat->flags.Diagonal);331S_mat->flags.Scalar = (R_mat->flags.Scalar && L_mat->flags.Scalar);332A= S_mat->array.SZ;333L= L_mat->array.SZ;334R= R_mat->array.SZ;335for ( i = 0 ; i < rS; i++) {336if(S_mat->flags.Diagonal) {337A[i][i] = S(P(L_coeff,L[i][i]), P(R_coeff,R[i][i]));338} else {339for ( j = 0 ; j < cS ; j ++ ) {340A[i][j] = S(P(L_coeff,L[i][j]), P(R_coeff,R[i][j]));341}342}343}344Check_mat (S_mat);345return(S_mat);346}347348/*}}} */349/*{{{ pmat_addeq, exported*/350/**************************************************************************\351@---------------------------------------------------------------------------352@ matrix_TYP *pmat_addeq (L_mat, R_mat, L_coeff, R_coeff)353@ matrix_TYP *L_mat, *R_mat ;354@ int L_coeff, R_coeff;355@356@ calculates L_mat = L_coeff * L_mat + R_coeff * R_mat modulo L_mat->prime357@---------------------------------------------------------------------------358@359\**************************************************************************/360matrix_TYP *pmat_addeq (L_mat, R_mat, L_coeff, R_coeff)361matrix_TYP *L_mat, *R_mat ;362int L_coeff, R_coeff;363{364int **L, **R, rS, cS ;365int i, j;366367rS = L_mat->rows;368cS = L_mat->cols;369L_mat->flags.Symmetric=(R_mat->flags.Symmetric&&L_mat->flags.Symmetric);370L_mat->flags.Diagonal =(R_mat->flags.Diagonal && L_mat->flags.Diagonal);371L_mat->flags.Scalar =(R_mat->flags.Scalar && L_mat->flags.Scalar);372L= L_mat->array.SZ;373R= R_mat->array.SZ;374for ( i = 0 ; i < rS; i++) {375if(L_mat->flags.Diagonal) {376L[i][i] = S(P(L_coeff,L[i][i]), P(R_coeff,R[i][i]));377} else {378for ( j = 0 ; j < cS ; j ++ ) {379L[i][j] = S(P(L_coeff,L[i][j]), P(R_coeff,R[i][j]));380}381}382}383Check_mat (L_mat);384return(L_mat);385}386387/*}}} */388/*{{{ mat_add, exported*/389390/**************************************************************************\391@---------------------------------------------------------------------------392@ matrix_TYP *mat_add (L_mat, R_mat, L_coeff, R_coeff)393@ matrix_TYP *L_mat, *R_mat ;394@ rational L_coeff, R_coeff;395@396@ calculates L_coeff * L_mat + R_coeff * R_mat397@---------------------------------------------------------------------------398@399\**************************************************************************/400matrix_TYP *mat_add (L_mat, R_mat, L_coeff, R_coeff)401matrix_TYP *L_mat, *R_mat ;402rational L_coeff, R_coeff;403{404int Lc, Rc;405int lp, help;406407help = 0;408Lc = Rc = 1;409if (( L_mat->cols != R_mat->cols) || (L_mat->rows != R_mat->rows )) {410fprintf (stderr, "Can't add %dx%d with %dx%d\n",411L_mat->rows, L_mat->cols, R_mat->rows, R_mat->cols );412exit (3);413}414if( L_mat->prime != 0 ) {415if (L_mat->prime != R_mat->prime) {416fprintf(stderr, "Error: Different primes in mat_add.\n");417exit (3);418}419/*============================================================*\420|| ||421|| The prime-field case: ||422|| Initialize actuell prime and make sure that the ||423|| Coeffizients are element of Fp. ||424|| ||425\*============================================================*/426init_prime(L_mat->prime);427lp = act_prime;428if(L_coeff.n != 1) Lc = P(1,-L_coeff.n%lp);429if(L_coeff.z != 1) Lc = P(Lc,L_coeff.z%lp);430if(R_coeff.n != 1) Rc = P(1,-R_coeff.n%lp);431if(R_coeff.z != 1) Rc = P(Rc,R_coeff.z%lp);432return pmat_add(L_mat,R_mat,Lc,Rc);433} else {434if ( L_mat->array.N != NULL ) {435rat2kgv( L_mat );436}437if ( R_mat->array.N != NULL ) {438rat2kgv( R_mat );439}440return rmat_add(L_mat,R_mat,L_coeff, R_coeff);441}442}443444/*}}} */445/*{{{ mat_addeq, exported*/446/**************************************************************************\447@---------------------------------------------------------------------------448@ matrix_TYP *mat_addeq (L_mat, R_mat, L_coeff, R_coeff)449@ matrix_TYP *L_mat, *R_mat ;450@ rational L_coeff, R_coeff;451@452@ calculates L_mat = L_coeff * L_mat + R_coeff * R_mat453@---------------------------------------------------------------------------454@455\**************************************************************************/456matrix_TYP *mat_addeq (L_mat, R_mat, L_coeff, R_coeff)457matrix_TYP *L_mat, *R_mat ;458rational L_coeff, R_coeff;459{460int Lc, Rc;461int lp, help;462463help = 0;464Lc = Rc = 1;465if (( L_mat->cols != R_mat->cols) || (L_mat->rows != R_mat->rows )) {466fprintf (stderr, "Can't add %dx%d with %dx%d\n",467L_mat->rows, L_mat->cols, R_mat->rows, R_mat->cols );468exit (3);469}470if( L_mat->prime != 0 ) {471if (L_mat->prime != R_mat->prime) {472fprintf(stderr, "Error: Different primes in mat_add.\n");473exit (3);474}475/*============================================================*\476|| ||477|| The prime-field case: ||478|| Initialize actuell prime and make sure that the ||479|| Coeffizients are element of Fp. ||480|| ||481\*============================================================*/482init_prime(L_mat->prime);483lp = act_prime;484if(L_coeff.n != 1) Lc = P(1,-L_coeff.n%lp);485if(L_coeff.z != 1) Lc = P(Lc,L_coeff.z%lp);486if(R_coeff.n != 1) Rc = P(1,-R_coeff.n%lp);487if(R_coeff.z != 1) Rc = P(Rc,R_coeff.z%lp);488return pmat_addeq(L_mat,R_mat,Lc,Rc);489} else {490if ( L_mat->array.N != NULL ) {491rat2kgv( L_mat );492}493if ( R_mat->array.N != NULL ) {494rat2kgv( R_mat );495}496return rmat_addeq(L_mat,R_mat,L_coeff, R_coeff);497}498}499500/*}}} */501502503