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

563680 views
1
#include "typedef.h"
2
#include "tools.h"
3
/**************************************************************************\
4
@---------------------------------------------------------------------------
5
@---------------------------------------------------------------------------
6
@ FILE: tools.c
7
@ containes some general small tools.
8
@---------------------------------------------------------------------------
9
@---------------------------------------------------------------------------
10
@
11
@
12
@ Exports the globale variables Zero and One.
13
@ rational Zero= { 0,1 };
14
@ rational One = { 1,1 };
15
@
16
@ int GGT( int a, int b );
17
@ calculates the greatest common divisor of a and b.
18
@ The result is always > 0
19
@
20
@ int KGV( int a, int b );
21
@ calculates the least commom multiple of a and b.
22
@ The result is always > 0
23
@
24
@ void Normal ( rational *a );
25
@ divides the numerator and the denominator of a rational number
26
@ by their greatest common divisor
27
@
28
@ void Normal2 ( int *z, *n );
29
@ divides z and n by their greatest common divisor.
30
@ Caution: z and n are changed in Normal2
31
@
32
@ void rat_add ( int *az, int *an, int bz, int bn);
33
@ cz az bz
34
@ calculates -- := -- + --
35
@ cn an bn
36
@ The result is stored in az and an.
37
@
38
@ int *factorize_new( int zahl,int *erg);
39
@
40
@ int *factorize ( int zahl );
41
@ The integer 'zahl' is factorized. If for example
42
@ zahl = p1^a1 *p2^a2,
43
@ erg[p1] is set to a1 and erg[p2] is set to a2,
44
@ all other entries of erg are 0.
45
@ Caution: the result is a pointer to an integer of length 100.
46
@ So factorize works only for intergers that
47
@ have prime factors smaller then 100.
48
@
49
@ void gcd_darstell( int a1, int a2, int *v1, int *v2, int *gcd);
50
@ calculates a presentation of the greatest commom divisor of a1 and a2:
51
@ gcd = v1*a1 + v2*a2
52
@
53
@ int p_inv(int a, int p)
54
@ calculates number ai such that a * ai is kongruent 1 modulo p (if exists)
55
@
56
@-------------------------------------------------------------------------
57
\**************************************************************************/
58
59
/**********************************************************************\
60
|
61
| tools.c -- allgemeine kleinere tools:
62
|
63
| int GGT( int a, int b );
64
| int KGV( int a, int b );
65
| void Normal ( rational *a );
66
| void Normal2 ( int *z, *n );
67
| void rat_add ( int *az, int *an, int bz, int bn);
68
| int *factorize_new( int zahl,int *erg);
69
| int *factorize ( int zahl );
70
| void gcd_darstell( int a1, int a2, int *v1, int *v2, int *gcd);
71
| int p_inv(int a, int p);
72
| int signum(int a);
73
|
74
| exportiert die globale Variable Zero. Eine Moeglichkeit, alles zum
75
| Absturz zu bringen, ist also z.B. die Anweisung Zero.n = 0 ... :(
76
|
77
\**********************************************************************/
78
79
rational Zero= { 0,1 };
80
rational One = { 1,1 };
81
82
/*{{{}}}*/
83
/*{{{ GGT*/
84
int GGT (int _a, int _b)
85
{
86
register int a= _a;
87
register int b= _b;
88
register int c;
89
90
if ( b == 0 ) {
91
return abs(a);
92
} else if ( b == 1 || a == 1 ) {
93
return 1;
94
} else {
95
while ( (c = a%b) != 0 ) {
96
a = b;
97
b = c;
98
}
99
}
100
return abs(b);
101
}
102
103
/*}}} */
104
/*{{{ KGV*/
105
/*
106
|
107
| int KGV( int a, int b);
108
|
109
| berechnet das kgv von a und b. Das Ergebnis ist immer >= 0!
110
|
111
*/
112
int KGV( a, b )
113
int a, b;
114
{
115
int kgv, ggt;
116
117
a = abs(a);
118
b = abs(b);
119
ggt= GGT( a, b );
120
if ( ggt != 0 )
121
{
122
if ( a > b )
123
kgv = (a / ggt) * b; /* die Reihenfolge ist wesentlich! */
124
/* (a*b)/ggt waere grosser Bloedsinn! */
125
else
126
kgv = (b / ggt) * a; /* die Reihenfolge ist wesentlich! */
127
}
128
else
129
kgv = 0;
130
return kgv;
131
}
132
133
/*}}} */
134
/*{{{ Normal*/
135
136
137
void Normal (a)
138
rational *a;
139
{
140
register int g;
141
register int n= a->n;
142
register int z= a->z;
143
144
if ( n == 0 ) {
145
printf ("Normal: Error: divide by zero\n");
146
exit (3);
147
}
148
if ( z == 0 ) {
149
a->n= 1;
150
} else {
151
g = GGT ( z, n);
152
if ( g != 1 ) {
153
z /= g;
154
n /= g;
155
}
156
if ( n < 0 ) {
157
a->z = -z;
158
a->n = -n;
159
} else {
160
a->z = z;
161
a->n = n;
162
}
163
}
164
}
165
166
/*}}} */
167
/*{{{ Normal2*/
168
void Normal2 ( _z, _n )
169
int *_z, *_n;
170
{
171
register int z = *_z;
172
register int n = *_n;
173
register int g;
174
175
if ( n == 0 ) {
176
printf ("Normal2: Error: divide by zero\n");
177
exit (3);
178
}
179
if ( z == 0 ) {
180
*_n = 1;
181
} else {
182
g = GGT ( z, n);
183
if ( g != 1 ) {
184
z /= g;
185
n /= g;
186
}
187
if ( n < 0) {
188
*_z = -z;
189
*_n = -n;
190
} else {
191
*_z = z;
192
*_n = n;
193
}
194
}
195
}
196
197
/*}}} */
198
/*{{{ rat_add*/
199
/*
200
|
201
| rat_add( &a.z, &a.n, b.z, b.n );
202
|
203
| rational a, rational b: addition of a and b, result is stored in a.
204
|
205
*/
206
void rat_add( az, an, bz, bn )
207
int *az, *an, bz, bn;
208
{
209
register int temp_ggt;
210
211
/*
212
* Normal tests also for divide by zero
213
*/
214
Normal2( az, an );
215
Normal2( &bz, &bn );
216
temp_ggt = GGT( *an, bn );
217
*az = (*az) * bn/temp_ggt + bz * (*an)/temp_ggt;
218
if ( *an > bn ) {
219
*an = (*an/temp_ggt) * bn;
220
} else {
221
*an *= (bn/temp_ggt);
222
}
223
Normal2( az, an );
224
}
225
226
/*}}} */
227
/*{{{ factorize_new*/
228
int *factorize_new( zahl, erg)
229
int zahl;
230
int *erg;
231
{
232
int i;
233
234
if ( erg != NULL )
235
{
236
for(i=0; i<100; i++)
237
erg[i] = 0;
238
for(i=2; i<100; i++)
239
{
240
while((zahl%i) == 0)
241
{
242
zahl = zahl/i;
243
erg[i]++;
244
}
245
}
246
if(zahl != 1)
247
erg[0] = 1;
248
}
249
return( erg );
250
}
251
252
/*}}} */
253
/*{{{ factorize*/
254
int *factorize(zahl)
255
int zahl;
256
{
257
int i;
258
int *erg;
259
260
erg = (int *) malloc(100 *sizeof(int));
261
factorize_new( zahl, erg );
262
return(erg);
263
}
264
265
/*}}} */
266
/*{{{ gcd_darstell*/
267
/*-----------------------------------------------------------------------*\
268
| gibt darstellung des ggt: gcd = v1*a1 + v2*a2 |
269
\*-----------------------------------------------------------------------*/
270
void gcd_darstell(a1, a2, v1, v2, gcd)
271
int a1, a2;
272
int *v1, *v2, *gcd;
273
{
274
int bn,bn1,bn2,rn,rn1,rn2,q, an, an1, an2;
275
rn2=a2; rn1=a1; bn2=0; bn1=1;
276
an2 = 1; an1 = 0;
277
278
if(a1 == 0 && a2 == 0)
279
{
280
*gcd = 0; *v1 = 0; *v2 = 0;
281
}
282
if(a1 == 0 && a2 != 0)
283
{
284
*gcd = a2; *v1 = 0; *v2 = 1;
285
}
286
if(a1 != 0 && a2 == 0)
287
{
288
*gcd = a1; *v1 = 1; *v2 = 0;
289
}
290
if(a1 != 0 && a2 != 0)
291
{
292
do
293
{
294
rn=rn2%rn1;
295
q=(rn2-rn)/rn1;
296
bn=bn2-q*bn1;
297
an=an2-q*an1;
298
if(rn != 0)
299
{
300
bn2=bn1; bn1=bn; rn2=rn1; rn1=rn; an2=an1; an1 = an;
301
}
302
}
303
while(rn!=0);
304
if(rn1 < 0)
305
{
306
*gcd = -rn1; *v1 = -bn1; *v2 = -an1;
307
}
308
if(rn1 > 0)
309
{
310
*gcd = rn1; *v1 = bn1; *v2 = an1;
311
}
312
}
313
}
314
/*}}} */
315
316
/*-----------------------------------------------------------------------*\
317
| calculates number i such that a * i is kongruent 1 modulo p (if exists)
318
\*-----------------------------------------------------------------------*/
319
int p_inv(a, p)
320
int a,p;
321
{
322
int an, an1, an2, rn, rn1, rn2, q;
323
rn1 = a %p;
324
if(rn1 == 0)
325
{
326
printf("%d is not invertible modulo %d\n", a, p);
327
exit(3);
328
}
329
if(rn1 == 1 || rn1 == -1)
330
return(rn1);
331
rn2 = p; an2 = 0; an1 = 1;
332
do
333
{
334
rn=rn2%rn1;
335
q=(rn2-rn)/rn1;
336
an=an2-q*an1;
337
if(rn != 0)
338
{
339
rn2=rn1; rn1=rn; an2=an1; an1 = an;
340
}
341
}
342
while(rn!=0);
343
if(rn1 == -1)
344
return( -an1);
345
if(rn1 == 1)
346
return( an1);
347
else
348
{
349
printf("%d is not invertible modulo %d\n", a, p);
350
exit(3);
351
}
352
}
353
354
355
int signum(a)
356
int a;
357
{
358
if(a>0)
359
return(1);
360
if(a<0)
361
return(-1);
362
return(0);
363
}
364
365