Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

563642 views
1
#include "typedef.h"
2
#include "matrix.h"
3
#include "longtools.h"
4
5
extern int INFO_LEVEL;
6
7
/***************************************************************************
8
@
9
@---------------------------------------------------------------------------
10
@---------------------------------------------------------------------------
11
@ FILE: min_pol.c
12
@---------------------------------------------------------------------------
13
@---------------------------------------------------------------------------
14
@
15
****************************************************************************/
16
17
18
/***************************************************************************
19
@
20
@---------------------------------------------------------------------------
21
@
22
@ matrix_TYP *min_pol(matrix_TYP *A)
23
@
24
@ Let A be an integral NON ZERO matrix. Then the function returns an
25
@ integral 1xn matrix B with the property:
26
@ \sum_i=0^n B->array.SZ[0][i] * A^i =0,
27
@ and n is minimal.
28
@
29
@ SIDEEFECTS: the matrix A is checked via Check_mat !!!
30
@---------------------------------------------------------------------------
31
@
32
****************************************************************************/
33
matrix_TYP *min_pol(matrix_TYP *A)
34
{
35
int i,
36
j,
37
k,
38
flag,
39
cols,
40
rank,
41
grad; /* actualy the degree +1 */
42
43
matrix_TYP **potenzen,
44
*erg; /* will hold the result */
45
46
MP_INT **lines,
47
**trf,
48
kgv;
49
50
/* check some trivialities */
51
Check_mat(A);
52
if (A->flags.Integral == FALSE || A->cols != A->rows){
53
fprintf(stderr,"error in min_pol, A should be integral and quadratic\n");
54
exit(3);
55
}
56
57
/* prepare all variables */
58
potenzen = (matrix_TYP **) calloc(1 + A->cols , sizeof(matrix_TYP));
59
potenzen[0] = init_mat(A->cols,A->cols,"1");
60
potenzen[1] = copy_mat(A);
61
lines = init_MP_mat(A->cols+1,A->cols*A->cols);
62
trf = init_MP_mat(A->cols+1,A->cols+1);
63
for (i=0;i<=A->cols;i++) mpz_set_ui(trf[i]+i,1);
64
mpz_init(&kgv);
65
66
/* set the first two lines */
67
for (i=0;i<2;i++)
68
for (j=0;j<A->cols;j++)
69
for (k=0;k<A->cols;k++)
70
mpz_set_si(lines[i]+j*A->cols+k,potenzen[i]->array.SZ[j][k]);
71
72
/* the calculation starts */
73
grad = 2;
74
do{
75
if (INFO_LEVEL & 4){
76
dump_MP_mat(lines,grad,A->cols*A->cols,"lines");
77
}
78
rank = MP_row_gauss_simultaneous(lines,grad,A->cols*A->cols,trf,grad);
79
80
/* avoid getting trouble by big numbers, ie. the powers aren't really
81
powers because of a lack of precision */
82
if (rank > A->cols){
83
fprintf(stderr,"error in min_pol because of a lack of precision\n");
84
exit(3);
85
}
86
87
if (rank == grad){
88
potenzen[grad] = mat_mul(potenzen[grad-1],A);
89
for (j=0;j<A->cols;j++)
90
for (k=0;k<A->cols;k++)
91
mpz_set_si(lines[grad]+j*A->cols+k,
92
potenzen[grad]->array.SZ[j][k]);
93
grad++;
94
flag = FALSE;
95
}
96
else{
97
flag = TRUE;
98
}
99
} while(!flag);
100
101
/* we got the wanted result in trf */
102
erg = init_mat(1,grad,"");
103
for (i=0;i<grad;i++) erg->array.SZ[0][i] = mpz_get_si(&trf[grad-1][i]);
104
105
/* "normalize" polynomial, ie. get the last coeff positive */
106
if (erg->array.SZ[0][grad-1] < 0)
107
for (i=0;i<grad;i++) erg->array.SZ[0][i] *= -1 ;
108
109
/* clean up memory */
110
for (i=0;i<=A->cols;i++) if (potenzen[i] != NULL) free_mat(potenzen[i]);
111
free_MP_mat(trf,A->cols+1,A->cols+1);
112
free(trf);
113
free(potenzen);
114
free_MP_mat(lines,A->cols+1,A->cols*A->cols);
115
free(lines);
116
mpz_clear(&kgv);
117
118
return erg;
119
} /* min_pol(....) */
120
121