1 /****************************************************************************
2 **
3 ** This file is part of GAP, a system for computational discrete algebra.
4 **
5 ** Copyright of GAP belongs to its developers, whose names are too numerous
6 ** to list here. Please refer to the COPYRIGHT file for details.
7 **
8 ** SPDX-License-Identifier: GPL-2.0-or-later
9 **
10 ** This file declares the functions of the arithmetic operations package.
11 */
12
13 #ifndef GAP_ARITHS_H
14 #define GAP_ARITHS_H
15
16 #include "objects.h"
17
18 /****************************************************************************
19 **
20 *T CompaMethod . . . . . . . . . . type of methods for comparison operations
21 **
22 ** 'CompaMethod' is the type of methods for comparison operations, i.e., a
23 ** function accepting two arguments of type 'Obj' and returning an 'Int'.
24 */
25 typedef Int (* CompaMethod) ( Obj opL, Obj opR );
26
27
28 /****************************************************************************
29 **
30 *T ArithMethod1 . . . . . . . . . type of methods for arithmetic operations
31 **
32 ** 'ArithMethod1' is the type of methods for unary arithmetic operations,
33 ** i.e., a function accepting one argument of type 'Obj' and returning an
34 ** 'Obj'.
35 */
36 typedef Obj (* ArithMethod1) ( Obj op );
37
38
39 /****************************************************************************
40 **
41 *T ArithMethod2 . . . . . . . . . type of methods for arithmetic operations
42 **
43 ** 'ArithMethod2' is the type of methods for binary arithmetic operations,
44 ** i.e., a function accepting two arguments of type 'Obj' and returning an
45 ** 'Obj'.
46 */
47 typedef Obj (* ArithMethod2) ( Obj opL, Obj opR );
48
49
50 /****************************************************************************
51 **
52 *F * * * * * * * * * * * unary arithmetic operations * * * * * * * * * * * *
53 */
54
55
56 /****************************************************************************
57 **
58 *V ZeroFuncs[<type>] . . . . . . . . . . . . . . . . . table of zero methods
59 */
60 extern ArithMethod1 ZeroFuncs[LAST_REAL_TNUM + 1];
61
62
63 /****************************************************************************
64 **
65 *F ZERO( <op> ) . . . . . . . . . . . . . . . . . . . . . zero of an object
66 **
67 ** 'ZERO' returns the zero of the object <op>.
68 */
ZERO(Obj op)69 EXPORT_INLINE Obj ZERO(Obj op)
70 {
71 UInt tnum = TNUM_OBJ(op);
72 return (*ZeroFuncs[tnum])(op);
73 }
74
75
76 /****************************************************************************
77 **
78 *V ZeroMutFuncs[<type>] . . . . . . . . . . . . . . . table of zero methods
79 */
80 extern ArithMethod1 ZeroMutFuncs[LAST_REAL_TNUM + 1];
81
82
83 /****************************************************************************
84 **
85 *F ZERO_MUT( <op> ) . . . . . . . . . . . . . . . . . . . zero of an object
86 **
87 ** 'ZERO_MUT' returns the mutable zero of the object <op>.
88 */
ZERO_MUT(Obj op)89 EXPORT_INLINE Obj ZERO_MUT(Obj op)
90 {
91 UInt tnum = TNUM_OBJ(op);
92 return (*ZeroMutFuncs[tnum])(op);
93 }
94
95
96 /****************************************************************************
97 **
98 *V AInvFuncs[<type>] . . . . . . . . . . . table of additive inverse methods
99 */
100 extern ArithMethod1 AInvFuncs[LAST_REAL_TNUM + 1];
101
102
103 /****************************************************************************
104 **
105 *F AINV( <op> ) . . . . . . . . . . . . . . . additive inverse of an object
106 **
107 ** 'AINV' returns the additive inverse of the object <op>.
108 */
AINV(Obj op)109 EXPORT_INLINE Obj AINV(Obj op)
110 {
111 UInt tnum = TNUM_OBJ(op);
112 return (*AInvFuncs[tnum])(op);
113 }
114
115
116 /****************************************************************************
117 **
118 *V AInvMutFuncs[<type>] . . . . . . . . . table of additive inverse methods
119 */
120 extern ArithMethod1 AInvMutFuncs[LAST_REAL_TNUM + 1];
121
122
123 /****************************************************************************
124 **
125 *F AINV_MUT( <op> ) . . . . . . . . . . . . . additive inverse of an object
126 **
127 ** 'AINV_MUT' returns the mutable additive inverse of the object <op>.
128 */
AINV_MUT(Obj op)129 EXPORT_INLINE Obj AINV_MUT(Obj op)
130 {
131 UInt tnum = TNUM_OBJ(op);
132 return (*AInvMutFuncs[tnum])(op);
133 }
134
135
136 /****************************************************************************
137 **
138 *F C_AINV( <val>, <left> ) . . . . . . . . . . . . . . . . . . compute ainv
139 */
140 #define C_AINV(val,left) \
141 val = AINV_MUT( left );
142
143
144 /****************************************************************************
145 **
146 *F C_AINV_FIA( <val>, <left> ) . . . . . . . . . compute ainv, fast integer
147 */
148 #define C_AINV_FIA(val,left) \
149 val = AINV_MUT( left );
150
151
152 /****************************************************************************
153 **
154 *F C_AINV_INTOBJS( <val>, <left> ) . . . . . . . compute ainv of an integer
155 */
156 #define C_AINV_INTOBJS(val,left) \
157 val = AINV_MUT( left );
158
159
160 /****************************************************************************
161 **
162 *V OneFuncs[<type>] . . . . . . . . . . . . . . . . . table of one methods
163 */
164 extern ArithMethod1 OneFuncs[LAST_REAL_TNUM + 1];
165
166
167 /****************************************************************************
168 **
169 *F ONE( <op> ) . . . . . . . . . . . . . . . . . . . . . . one of an object
170 **
171 ** 'ONE' returns the one of the object <op>.
172 */
ONE(Obj op)173 EXPORT_INLINE Obj ONE(Obj op)
174 {
175 UInt tnum = TNUM_OBJ(op);
176 return (*OneFuncs[tnum])(op);
177 }
178
179
180 /****************************************************************************
181 **
182 *V OneMutFuncs[<type>] . . . . . .table of mutability preservingone methods
183 */
184 extern ArithMethod1 OneMutFuncs[LAST_REAL_TNUM + 1];
185
186
187 /****************************************************************************
188 **
189 *F ONE_MUT( <op> ) . . . . . . . . one of an object retaining mutability
190 **
191 ** 'ONE_MUT' returns the one of the object <op> with the same
192 ** mutability level as <op>.
193 */
ONE_MUT(Obj op)194 EXPORT_INLINE Obj ONE_MUT(Obj op)
195 {
196 UInt tnum = TNUM_OBJ(op);
197 return (*OneMutFuncs[tnum])(op);
198 }
199
200
201 /****************************************************************************
202 **
203 *V InvFuncs[<type>] . . . . . . . . . . . . . . table of inverse functions
204 */
205 extern ArithMethod1 InvFuncs[LAST_REAL_TNUM + 1];
206
207
208 /****************************************************************************
209 **
210 *F INV( <op> ) . . . . . . . . . . . . . . . . . . . . inverse of an object
211 **
212 ** 'INV' returns the multiplicative inverse of the object <op>.
213 */
INV(Obj op)214 EXPORT_INLINE Obj INV(Obj op)
215 {
216 UInt tnum = TNUM_OBJ(op);
217 return (*InvFuncs[tnum])(op);
218 }
219
220
221 /****************************************************************************
222 **
223 *V InvMutFuncs[<type>] .. .table of mutability preserving inverse functions
224 */
225 extern ArithMethod1 InvMutFuncs[LAST_REAL_TNUM + 1];
226
227
228 /****************************************************************************
229 **
230 *F INV_MUT( <op> ) . . . . . . . . inverse of an object retaining mutability
231 **
232 ** 'INV_MUT' returns the multiplicative inverse of the object <op>.
233 */
INV_MUT(Obj op)234 EXPORT_INLINE Obj INV_MUT(Obj op)
235 {
236 UInt tnum = TNUM_OBJ(op);
237 return (*InvMutFuncs[tnum])(op);
238 }
239
240
241 /****************************************************************************
242 **
243 *F * * * * * * * * * * * * * comparison operations * * * * * * * * * * * * *
244 */
245
246
247 /****************************************************************************
248 **
249 *V EqFuncs[<typeL>][<typeR>] . . . . . . . . . . table of comparison methods
250 */
251 extern CompaMethod EqFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
252
253
254 /****************************************************************************
255 **
256 *F EQ( <opL>, <opR> ) . . . . . . . . . . . . . . comparison of two objects
257 **
258 ** 'EQ' returns a nonzero value if the object <opL> is equal to the object
259 ** <opR>, and zero otherwise.
260 */
EQ(Obj opL,Obj opR)261 EXPORT_INLINE Int EQ(Obj opL, Obj opR)
262 {
263 if (opL == opR)
264 return 1;
265 if (ARE_INTOBJS(opL, opR))
266 return 0;
267 UInt tnumL = TNUM_OBJ(opL);
268 UInt tnumR = TNUM_OBJ(opR);
269 return (*EqFuncs[tnumL][tnumR])(opL, opR);
270 }
271
272 extern Obj EqOper;
273
274 Int EqObject(Obj opL, Obj opR);
275
276
277 /****************************************************************************
278 **
279 *V LtFuncs[<typeL>][<typeR>] . . . . . . . . . . table of comparison methods
280 */
281 extern CompaMethod LtFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
282
283
284 /****************************************************************************
285 **
286 *F LT( <opL>, <opR> ) . . . . . . . . . . . . . . comparison of two objects
287 **
288 ** 'LT' returns a nonzero value if the object <opL> is less than the object
289 ** <opR>, and zero otherwise.
290 */
LT(Obj opL,Obj opR)291 EXPORT_INLINE Int LT(Obj opL, Obj opR)
292 {
293 if (opL == opR)
294 return 0;
295 if (ARE_INTOBJS(opL, opR))
296 return (Int)(opL) < (Int)(opR);
297 UInt tnumL = TNUM_OBJ(opL);
298 UInt tnumR = TNUM_OBJ(opR);
299 return (*LtFuncs[tnumL][tnumR])(opL, opR);
300 }
301
302 extern Obj LtOper;
303
304
305 /****************************************************************************
306 **
307 *V InFuncs[<typeL>][<typeR>] . . . . . . . . . . table of membership methods
308 */
309 extern CompaMethod InFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
310
311
312 /****************************************************************************
313 **
314 *F IN( <opL>, <opR> ) . . . . . . . . . . . membership test of two objects
315 **
316 ** 'IN' returns a nonzero value if the object <opL> is a member of the
317 ** object <opR>, and zero otherwise.
318 */
IN(Obj opL,Obj opR)319 EXPORT_INLINE Int IN(Obj opL, Obj opR)
320 {
321 UInt tnumL = TNUM_OBJ(opL);
322 UInt tnumR = TNUM_OBJ(opR);
323 return (*InFuncs[tnumL][tnumR])(opL, opR);
324 }
325
326
327 /****************************************************************************
328 **
329 *F * * * * * * * * * * * binary arithmetic operations * * * * * * * * * * * *
330 */
331
332 /****************************************************************************
333 **
334 *V SumFuncs[<typeL>][<typeR>] . . . . . . . . . . . . table of sum methods
335 */
336 extern ArithMethod2 SumFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
337
338
339 /****************************************************************************
340 **
341 *F SUM( <opL>, <opR> ) . . . . . . . . . . . . . . . . . sum of two objects
342 **
343 ** 'SUM' returns the sum of the two objects <opL> and <opR>.
344 **
345 ** At places where performance matters one should use the following code
346 **
347 ** if ( ! ARE_INTOBJS( <opL>, <opR> )
348 ** || ! SUM_INTOBJS( <res>, <opL>, <opR> ) )
349 ** <res> = SUM( <opL>, <opR> );
350 */
SUM(Obj opL,Obj opR)351 EXPORT_INLINE Obj SUM(Obj opL, Obj opR)
352 {
353 UInt tnumL = TNUM_OBJ(opL);
354 UInt tnumR = TNUM_OBJ(opR);
355 return (*SumFuncs[tnumL][tnumR])(opL, opR);
356 }
357
358
359 extern Obj SumOper;
360
361
362 /****************************************************************************
363 **
364 *F C_SUM( <val>, <left>, <right> ) . . . . . . . . . . . . . . . compute sum
365 */
366 #define C_SUM(val,left,right) \
367 val = SUM( left, right );
368
369
370 /****************************************************************************
371 **
372 *F C_SUM_FIA( <val>, <left>, <right> ) . . . . . compute sum, fast integers
373 */
374 #define C_SUM_FIA(val,left,right) \
375 if ( ! ARE_INTOBJS(left,right) || ! SUM_INTOBJS(val,left,right) ) { \
376 val = SUM( left, right ); \
377 }
378
379
380 /****************************************************************************
381 **
382 *F C_SUM_INTOBJS( <val>, <left>, <right> ) . . . compute sum of two integers
383 */
384 #define C_SUM_INTOBJS(val,left,right) \
385 if ( ! SUM_INTOBJS(val,left,right) ) { \
386 val = SUM( left, right ); \
387 }
388
389
390 /****************************************************************************
391 **
392 *V DiffFuncs[<typeL>][<typeR>] . . . . . . . . . table of difference methods
393 */
394 extern ArithMethod2 DiffFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
395
396
397 /****************************************************************************
398 **
399 *F DIFF( <opL>, <opR> ) . . . . . . . . . . . . . difference of two objects
400 **
401 ** 'DIFF' returns the difference of the two objects <opL> and <opR>.
402 **
403 ** At places where performance matters one should use the following code
404 **
405 ** if ( ! ARE_INTOBJS( <opL>, <opR> )
406 ** || ! DIFF_INTOBJS( <res>, <opL>, <opR> ) )
407 ** <res> = DIFF( <opL>, <opR> );
408 */
DIFF(Obj opL,Obj opR)409 EXPORT_INLINE Obj DIFF(Obj opL, Obj opR)
410 {
411 UInt tnumL = TNUM_OBJ(opL);
412 UInt tnumR = TNUM_OBJ(opR);
413 return (*DiffFuncs[tnumL][tnumR])(opL, opR);
414 }
415
416
417 /****************************************************************************
418 **
419 *F C_DIFF( <val>, <left>, <right> ) . . . . . . . . . . . . . compute diff
420 */
421 #define C_DIFF(val,left,right) \
422 val = DIFF( left, right );
423
424
425 /****************************************************************************
426 **
427 *F C_DIFF_FIA( <val>, <left>, <right> ) . . . . compute diff, fast integers
428 */
429 #define C_DIFF_FIA(val,left,right) \
430 if ( ! ARE_INTOBJS(left,right) || ! DIFF_INTOBJS(val,left,right) ) { \
431 val = DIFF( left, right ); \
432 }
433
434
435 /****************************************************************************
436 **
437 *F C_DIFF_INTOBJS( <val>, <left>, <right> ) . compute diff of two integers
438 */
439 #define C_DIFF_INTOBJS(val,left,right) \
440 if ( ! DIFF_INTOBJS(val,left,right) ) { \
441 val = DIFF( left, right ); \
442 }
443
444
445 /****************************************************************************
446 **
447 *V ProdFuncs[<typeL>][<typeR>] . . . . . . . . . . table of product methods
448 */
449 extern ArithMethod2 ProdFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
450
451
452 /****************************************************************************
453 **
454 *F PROD( <opL>, <opR> ) . . . . . . . . . . . . . . product of two objects
455 **
456 ** 'PROD' returns the product of the two objects <opL> and <opR>.
457 **
458 ** At places where performance matters one should use the following code
459 **
460 ** if ( ! ARE_INTOBJS( <opL>, <opR> )
461 ** || ! PROD_INTOBJS( <res>, <opL>, <opR> ) )
462 ** <res> = PROD( <opL>, <opR> );
463 */
PROD(Obj opL,Obj opR)464 EXPORT_INLINE Obj PROD(Obj opL, Obj opR)
465 {
466 UInt tnumL = TNUM_OBJ(opL);
467 UInt tnumR = TNUM_OBJ(opR);
468 return (*ProdFuncs[tnumL][tnumR])(opL, opR);
469 }
470
471
472 /****************************************************************************
473 **
474 *F C_PROD( <val>, <left>, <right> ) . . . . . . . . . . . . compute product
475 */
476 #define C_PROD(val,left,right) \
477 val = PROD( left, right );
478
479
480 /****************************************************************************
481 **
482 *F C_PROD_FIA( <val>, <left>, <right> ) . . compute product, fast integers
483 */
484 #define C_PROD_FIA(val,left,right) \
485 if ( ! ARE_INTOBJS(left,right) || ! PROD_INTOBJS(val,left,right) ) { \
486 val = PROD( left, right ); \
487 }
488
489
490 /****************************************************************************
491 **
492 *F C_PROD_INTOBJS( <val>, <left>, <right> ) compute product of two integers
493 */
494 #define C_PROD_INTOBJS(val,left,right) \
495 if ( ! PROD_INTOBJS(val,left,right) ) { \
496 val = PROD( left, right ); \
497 }
498
499
500 /****************************************************************************
501 **
502 *V QuoFuncs[<typeL>][<typeR>] . . . . . . . . . . table of quotient methods
503 */
504 extern ArithMethod2 QuoFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
505
506
507 /****************************************************************************
508 **
509 *F QUO( <opL>, <opR> ) . . . . . . . . . . . . . . . quotient of two objects
510 **
511 ** 'QUO' returns the quotient of the object <opL> by the object <opR>.
512 */
QUO(Obj opL,Obj opR)513 EXPORT_INLINE Obj QUO(Obj opL, Obj opR)
514 {
515 UInt tnumL = TNUM_OBJ(opL);
516 UInt tnumR = TNUM_OBJ(opR);
517 return (*QuoFuncs[tnumL][tnumR])(opL, opR);
518 }
519
520
521 /****************************************************************************
522 **
523 *V LQuoFuncs[<typeL>][<typeR>] . . . . . . . table of left quotient methods
524 */
525 extern ArithMethod2 LQuoFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
526
527
528 /****************************************************************************
529 **
530 *F LQUO( <opL>, <opR> ) . . . . . . . . . . . left quotient of two operand
531 **
532 ** 'LQUO' returns the left quotient of the object <opL> by the object <opR>.
533 */
LQUO(Obj opL,Obj opR)534 EXPORT_INLINE Obj LQUO(Obj opL, Obj opR)
535 {
536 UInt tnumL = TNUM_OBJ(opL);
537 UInt tnumR = TNUM_OBJ(opR);
538 return (*LQuoFuncs[tnumL][tnumR])(opL, opR);
539 }
540
541
542 /****************************************************************************
543 **
544 *V PowFuncs[<typeL>][<typeR>] . . . . . . . . . . . table of power methods
545 */
546 extern ArithMethod2 PowFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
547
548
549 /****************************************************************************
550 **
551 *F POW( <opL>, <opR> ) . . . . . . . . . . . . . . . . power of two objects
552 **
553 ** 'POW' returns the power of the object <opL> by the object <opL>.
554 */
POW(Obj opL,Obj opR)555 EXPORT_INLINE Obj POW(Obj opL, Obj opR)
556 {
557 UInt tnumL = TNUM_OBJ(opL);
558 UInt tnumR = TNUM_OBJ(opR);
559 return (*PowFuncs[tnumL][tnumR])(opL, opR);
560 }
561
562
563 /****************************************************************************
564 **
565 *V CommFuncs[<typeL>][<typeR>] . . . . . . . . . table of commutator methods
566 */
567 extern ArithMethod2 CommFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
568
569
570 /****************************************************************************
571 **
572 *F COMM( <opL>, <opR> ) . . . . . . . . . . . . . commutator of two objects
573 **
574 ** 'COMM' returns the commutator of the two objects <opL> and <opR>.
575 */
COMM(Obj opL,Obj opR)576 EXPORT_INLINE Obj COMM(Obj opL, Obj opR)
577 {
578 UInt tnumL = TNUM_OBJ(opL);
579 UInt tnumR = TNUM_OBJ(opR);
580 return (*CommFuncs[tnumL][tnumR])(opL, opR);
581 }
582
583
584 /****************************************************************************
585 **
586 *V ModFuncs[<typeL>][<typeR>] . . . . . . . . . table of remainder methods
587 */
588 extern ArithMethod2 ModFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
589
590
591 /****************************************************************************
592 **
593 *F MOD( <opL>, <opR> ) . . . . . . . . . . . . . . remainder of two objects
594 **
595 ** 'MOD' returns the remainder of the object <opL> by the object <opR>.
596 */
MOD(Obj opL,Obj opR)597 EXPORT_INLINE Obj MOD(Obj opL, Obj opR)
598 {
599 UInt tnumL = TNUM_OBJ(opL);
600 UInt tnumR = TNUM_OBJ(opR);
601 return (*ModFuncs[tnumL][tnumR])(opL, opR);
602 }
603
604
605 /****************************************************************************
606 **
607 *F ChangeArithDoOperations( <oper>, <verb> )
608 */
609 void ChangeArithDoOperations(Obj oper, Int verb);
610
611
612 /****************************************************************************
613 **
614 *F * * * * * * * * * * * * * initialize module * * * * * * * * * * * * * * *
615 */
616
617 /****************************************************************************
618 **
619 *F InitInfoAriths() . . . . . . . . . . . . . . . . table of init functions
620 */
621 StructInitInfo * InitInfoAriths ( void );
622
623
624 #endif // GAP_ARITHS_H
625