GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
/* author: Oliver Heidbuechel */1/* last change: 23.11.2000 by author */23#include<typedef.h>4#include<datei.h>5#include<getput.h>6#include<matrix.h>7#include<longtools.h>8#include<tools.h>9#include"zass.h"10#include <bravais.h>11#include <presentation.h>12#include <graph.h>13141516/* --------------------------------------------------------------- */17/* constructs a matrix and writes M no-times on the diagonal */18/* --------------------------------------------------------------- */19static matrix_TYP *to_diag(matrix_TYP *M,20int dim,21int no)22{23int i, j, k;2425matrix_TYP *D;262728D = init_mat(M->rows, M->cols * no, "");2930for (i = 0; i < no; i++){31for (j = 0; j < dim; j++){32for (k = 0; k < dim; k++){33D->array.SZ[i * dim + j][i * dim + k] = M->array.SZ[i * dim + j][k];34}35}36}3738return(D);39}404142/* --------------------------------------------------------------- */43/* transl_aff_normal */44/* calculate a generating set of the linear part of */45/* N_(Aff(R^n))(R(G,0)) with tranlations in Q^n/Z^n */46/* returns the set {((G->gen[i] - I) * Translation_j)_i | j = ...} */47/* --------------------------------------------------------------- */48/* erzeuger: generators of the point group G */49/* erzanz : number of matrices in "erzeuger" */50/* anzahl : the number of the translations will be saved here */51/* --------------------------------------------------------------- */52matrix_TYP **transl_aff_normal(matrix_TYP **erzeuger,53int erzanz,54int *anzahl)55{56matrix_TYP *B, *B_diag,57*translation,58**tmp,59**transl;6061int k, j, i, dim, zahl;626364dim = erzeuger[0]->rows;6566/* create the matrix (g_1 - I, g_2 - I, ...)^tr */67B = calc_B(erzeuger,erzanz);6869/* solve (g_j-I)s = 0 (Z^n) for all j */70tmp = cong_solve(B);7172/* create matrices */73for (anzahl[0] = 0;74anzahl[0] < tmp[3]->cols && tmp[3]->array.SZ[anzahl[0]][anzahl[0]] != 0;75anzahl[0]++);7677if (anzahl[0] != 0){78/* create matrix diag (g_1 - I, g_2 - I, ...) */79B_diag = to_diag(B, dim, erzanz);80transl = (matrix_TYP **)calloc(anzahl[0], sizeof(matrix_TYP *));81for (j = 0; j < anzahl[0]; j++){82translation = init_mat(dim * erzanz, 1,"");83for (i = 0; i < dim; i++){84zahl = tmp[2]->array.SZ[i][j];85for (k = 0; k < erzanz; k++){86translation->array.SZ[i + k * dim][0] = zahl;87}88}89translation->kgv = tmp[3]->array.SZ[j][j];90translation->flags.Integral = FALSE;91Check_mat(translation);92transl[j] = mat_mul(B_diag, translation);93Check_mat(transl[j]);94if (transl[j]->kgv != 1){ /* paranoia test */95fprintf(stderr, "ERROR in transl_aff_normal\n");96exit(7);97}98free_mat(translation);99}100free_mat(B_diag);101}102else{103transl = NULL;104}105106/* cleaning up */107for (j = 0; j < 4; j++){108if (tmp[j] != NULL)109free_mat(tmp[j]);110}111free(tmp);112free_mat(B);113114return(transl);115}116117118119/* ---------------------------------------------------------------- */120/* cong_solve_part */121/* Calculates one solution of A*s = c (Z^m) */122/* If there is no solution, the function returns NULL. */123/* ---------------------------------------------------------------- */124/* A and c are matrices with A in Z^(nxm) and c in Q^(nx1) */125/* ---------------------------------------------------------------- */126static matrix_TYP *cong_solve_part(matrix_TYP *A,127matrix_TYP *c)128{129matrix_TYP *R,130*L,131*D,132*r,133*hilfsloesung,134*loesung;135136int i, last;137138139/* trivial case */140if (equal_zero(A) == 1 && equal_zero(c) == 1){141loesung = init_mat(A->cols, 1, "");142return(loesung);143}144145146L = init_mat(A->rows,A->rows,"1");147R = init_mat(A->cols,A->cols,"1");148hilfsloesung = init_mat(A->cols,1,"");149150/* find matrices D,L,R with LAR = D and D is the elemantary divisor matrix151and L in Gl_n(Z) and R in Gl_m(Z) */152D = long_elt_mat(L, A, R);153for (last = 0; last<D->cols && D->array.SZ[last][last] != 0; last++);154r = mat_mul(L,c);155156/* change the entries in r such that 0 <= r->array.SZ[i][0] < r->kgv157(example: -5/3 will be changed to 1/3) */158for (i=0; i<r->rows; i++){159r->array.SZ[i][0] %= r->kgv;160if (r->array.SZ[i][0] < 0)161r->array.SZ[i][0] += r->kgv;162}163164/* Find one solution of D*t = r (Z^m) */165hilfsloesung->kgv = r->kgv * D->array.SZ[last-1][last-1];166for (i=0; i<last; i++){167if (r->array.SZ[i][0] == 0)168hilfsloesung->array.SZ[i][0] = 0;169else{170hilfsloesung->array.SZ[i][0] = r->array.SZ[i][0]171* D->array.SZ[last-1][last-1] / D->array.SZ[i][i];172}173}174for (i=last; i<D->cols; i++){175if (r->array.SZ[i][0] != 0){176loesung = NULL;177}178}179180/* calculate one solution of A*s = c (Z^m) */181loesung = mat_mul(R,hilfsloesung);182183/* cleaning up */184free_mat(L);185free_mat(R);186free_mat(D);187free_mat(r);188free_mat(hilfsloesung);189190Check_mat(loesung);191return(loesung);192}193194195196/* --------------------------------------------------------------------- */197/* Let R be a spacegroup, P = P(R), coz = cocycle of R */198/* returns one element in the affine normalizer of R with linear part */199/* given by 'lin' (has to be possible) */200/* --------------------------------------------------------------------- */201matrix_TYP *to_aff_normal_element(matrix_TYP *lin,202matrix_TYP *coz,203int flag,204bravais_TYP *P,205bravais_TYP *R)206{207matrix_TYP *N, *cozl, *DIAG, *cozr, *ccc, *B, *lin_inv, *part;208209bravais_TYP *conj;210211int d, j, k;212213rational eins, minuseins;214215216217/* prepare */218eins.z = eins.n = minuseins.n = 1;219minuseins.z = -1;220d = lin->rows;221N = copy_mat(lin);222real_mat(N, d + 1, d + 1);223N->array.SZ[d][d] = 1;224225if (flag != 1){226conj = init_bravais(P->dim);227conj->gen_no = P->gen_no;228conj->gen = (matrix_TYP **)calloc(P->gen_no, sizeof(matrix_TYP *));229lin_inv = mat_inv(lin);230for (j = 0; j < P->gen_no; j++){231conj->gen[j] = mat_kon(lin, P->gen[j], lin_inv);232}233free_mat(lin_inv);234cozl = sg(R, conj);235236DIAG = matrix_on_diagonal(lin, P->gen_no);237cozr = mat_mul(DIAG,coz);238free_mat(DIAG);239ccc = mat_add(cozl,cozr,minuseins,eins);240free_mat(cozl);241free_mat(cozr);242Check_mat(ccc);243B = calc_B(conj->gen, conj->gen_no);244part = cong_solve_part(B,ccc);245if (part == NULL){246printf("ERROR in aff_normalisator! cong_solve_part returns NULL!\n");247exit(23);248}249free_mat(ccc);250free_mat(B);251free_bravais(conj);252}253else{254/* one solution is zero if the spacegroup splits */255part = init_mat(d, 1, "");256}257258/* construct the matrix */259if (part->kgv != 1){260for (j = 0; j < d; j++)261for (k = 0; k < d; k++)262N->array.SZ[j][k] *= part->kgv;263N->array.SZ[d][d] = part->kgv;264N->kgv = part->kgv;265}266for (j = 0; j < d; j++)267N->array.SZ[j][d] = part->array.SZ[j][0];268269Check_mat(N);270free_mat(part);271272return(N);273}274275276277278