bld-chain fix from Nelson
[sxemacs] / src / ent / ent-gaussian.c
1 /*
2   ent-gaussian.c -- Numeric types for SXEmacs
3   Copyright (C) 2005, 2006 Sebastian Freundt
4
5   Author:  Sebastian Freundt
6
7 This file is part of SXEmacs
8
9 SXEmacs is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 SXEmacs is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program.  If not, see <http://www.gnu.org/licenses/>. */
21
22
23 #include <config.h>
24 #include <limits.h>
25 #include <math.h>
26 #include "lisp.h"
27 #include "sysproc.h"    /* For qxe_getpid */
28
29 #include "ent.h"
30 #include "ent-float.h"
31 #ifdef HAVE_MPFR
32 #include "ent-mpfr.h"
33 #endif
34 #include "ent-gaussian.h"
35 #ifdef HAVE_MPC
36 #include "ent-mpc.h"
37 #endif
38
39 bigg ent_scratch_bigg;
40 static ase_nullary_operation_f Qent_gaussian_zero, Qent_gaussian_one;
41
42 \f
43 static void
44 bigg_print(Lisp_Object obj, Lisp_Object printcharfun, int SXE_UNUSED(escapeflag))
45 {
46         Bufbyte *fstr = bigg_to_string(XBIGG_DATA(obj), 10);
47         write_c_string((char*)fstr, printcharfun);
48         xfree(fstr);
49         fstr = (Bufbyte *)NULL;
50         return;
51 }
52
53 static int
54 bigg_equal(Lisp_Object obj1, Lisp_Object obj2, int depth)
55 {
56         return bigg_eql(XBIGG_DATA(obj1), XBIGG_DATA(obj2));
57
58         /* less warnings */
59         if (depth);
60 }
61
62 static unsigned long
63 bigg_hash(Lisp_Object obj, int depth)
64 {
65         return bigg_hashcode(XBIGG_DATA(obj));
66
67         /* less warnings */
68         if (depth);
69 }
70
71 static Lisp_Object
72 bigg_mark(Lisp_Object obj)
73 {
74         return Qnil;
75
76         /* less warnings */
77         if (obj == Qnil);
78 }
79
80 static void
81 bigg_finalise(void *header, int for_disksave)
82 {
83         if (for_disksave)
84                 signal_simple_error
85                         ("Can't dump an emacs containing "
86                          "pseudo-gaussian objects",Qt);
87
88         /* less warnings */
89         if (header);
90 }
91
92 static const struct lrecord_description bigg_description[] = {
93         { XD_OPAQUE_DATA_PTR, offsetof(Lisp_Bigg, data) },
94         { XD_END }
95 };
96
97 DEFINE_BASIC_LRECORD_IMPLEMENTATION("bigg", bigg,
98                                     bigg_mark, bigg_print, bigg_finalise,
99                                     bigg_equal, bigg_hash,
100                                     bigg_description, Lisp_Bigg);
101
102 DEFUN("make-bigg", Fmake_bigg, 2, 2, 0, /*
103 Return the Gaussian number whose rational component is REAL-PART
104 and whose imaginary component is IMAGINARY-PART.
105 */
106        (real_part, imaginary_part))
107 {
108         CHECK_COMPARABLE(real_part);
109         CHECK_COMPARABLE(imaginary_part);
110
111         {
112                 Lisp_Object tmp_r = Fcoerce_number(real_part, Qbigz, Qnil);
113                 Lisp_Object tmp_i = Fcoerce_number(imaginary_part, Qbigz, Qnil);
114                 return make_bigg_bz(XBIGZ_DATA(tmp_r), XBIGZ_DATA(tmp_i));
115         }
116 }
117
118 \f
119 /* basic functions */
120 void bigg_init(bigg g)
121 {
122         bigz_init(bigg_re(g));
123         bigz_init(bigg_im(g));
124 }
125
126 void bigg_fini(bigg g)
127 {
128         bigz_fini(bigg_re(g));
129         bigz_fini(bigg_im(g));
130 }
131
132 unsigned long bigg_hashcode(bigg g)
133 {
134         return (bigz_hashcode(bigg_re(g)) ^
135                 bigz_hashcode(bigg_im(g)));
136 }
137
138 Bufbyte *bigg_to_string(bigg g, int base)
139 {
140         Bufbyte *intg_str;
141         Bufbyte *imag_str;
142         int intg_len, imag_len;
143         int sign, neg;
144
145         intg_str = (Bufbyte*)bigz_to_string(bigg_re(g), base);
146         imag_str = (Bufbyte*)bigz_to_string(bigg_im(g), base);
147
148         intg_len = strlen((char*)intg_str);
149         imag_len = strlen((char*)imag_str);
150
151         sign = bigz_sign(bigg_im(g));
152         neg = (sign >= 0) ? 1 : 0;
153
154         /* now append the imaginary string */
155         XREALLOC_ARRAY(intg_str, Bufbyte, intg_len + neg + imag_len + 2);
156         if (neg)
157                 intg_str[intg_len] = '+';
158         memmove(&intg_str[intg_len + neg],
159                 &imag_str[0],
160                 imag_len);
161         intg_str[intg_len+neg+imag_len] = 'i';
162         intg_str[intg_len+neg+imag_len+1] = '\0';
163         xfree(imag_str);
164
165         return intg_str;
166 }
167
168 /***** Bigg: converting assignments *****/
169 void bigg_set(bigg g1,bigg g2)
170 {
171         bigz_set(bigg_re(g1), bigg_re(g2));
172         bigz_set(bigg_im(g1), bigg_im(g2));
173 }
174
175 void bigg_set_long(bigg g, long l)
176 {
177         bigz_set_long(bigg_re(g), l);
178         bigz_set_long(bigg_im(g), 0L);
179 }
180
181 void bigg_set_long_long(bigg g, long l1, long l2)
182 {
183         bigz_set_long(bigg_re(g), l1);
184         bigz_set_long(bigg_im(g), l2);
185 }
186
187 void bigg_set_ulong(bigg g, unsigned long ul)
188 {
189         bigz_set_ulong(bigg_re(g), ul);
190         bigz_set_ulong(bigg_im(g), 0UL);
191 }
192
193 void bigg_set_ulong_ulong(bigg g, unsigned long ul1, unsigned long ul2)
194 {
195         bigz_set_ulong(bigg_re(g), ul1);
196         bigz_set_ulong(bigg_im(g), ul2);
197 }
198
199 void bigg_set_bigz(bigg g, bigz z)
200 {
201         bigz_set(bigg_re(g), z);
202         bigz_set_long(bigg_im(g), 0L);
203 }
204
205 void bigg_set_bigz_bigz(bigg g, bigz z1, bigz z2)
206 {
207         bigz_set(bigg_re(g), z1);
208         bigz_set(bigg_im(g), z2);
209 }
210
211 /* void bigc_set_bigg(bigc c, bigg g)
212  * {
213  *      bigc_set_bigfr_bigfr(bigg_re(g), z1);
214  * }
215  */
216
217 /***** Bigg: comparisons *****/
218 int bigg_eql(bigg g1, bigg g2)
219 {
220         return ((bigz_eql(bigg_re(g1), bigg_re(g2))) &&
221                 (bigz_eql(bigg_im(g1), bigg_im(g2))));
222 }
223
224 /***** Bigg: arithmetic *****/
225 #if defined HAVE_MPFR && defined WITH_MPFR
226 void bigg_abs(bigfr res, bigg g)
227 {
228         /* the absolute archimedean valuation of a+bi is defined as:
229          * (a^2 + b^2)^(1/2)
230          */
231         bigz accu1, accu2, bz;
232         bigz_init(accu1);
233         bigz_init(accu2);
234         bigz_init(bz);
235
236         bigz_mul(accu1, bigg_re(g), bigg_re(g));
237         bigz_mul(accu2, bigg_im(g), bigg_im(g));
238         bigz_add(bz, accu1, accu2);
239
240         bigfr_set_bigz(res, bz);
241         bigfr_sqrt(res, res);
242
243         bigz_fini(accu1);
244         bigz_fini(accu2);
245         bigz_fini(bz);
246 }
247 #endif
248
249 void bigg_norm(bigz res, bigg g)
250 {
251         /* norm is the square of the absolute archimedean valuation */
252         bigz accu1, accu2;
253         bigz_init(accu1);
254         bigz_init(accu2);
255
256         bigz_mul(accu1, bigg_re(g), bigg_re(g));
257         bigz_mul(accu2, bigg_im(g), bigg_im(g));
258         bigz_add(res, accu1, accu2);
259
260         bigz_fini(accu1);
261         bigz_fini(accu2);
262 }
263
264 void bigg_neg(bigg res, bigg g)
265 {
266         /* negation is defined point-wise */
267         bigz_neg(bigg_re(res), bigg_re(g));
268         bigz_neg(bigg_im(res), bigg_im(g));
269 }
270
271 void bigg_conj(bigg res, bigg g)
272 {
273         bigg_set(res, g);
274         bigz_neg(bigg_im(res), bigg_im(res));
275 }
276
277 void bigg_add(bigg res, bigg g1, bigg g2)
278 {
279         /* addition is defined point-wise */
280         bigz accu1, accu2;
281         bigz_init(accu1);
282         bigz_init(accu2);
283
284         bigz_add(accu1, bigg_re(g1), bigg_re(g2));
285         bigz_add(accu2, bigg_im(g1), bigg_im(g2));
286         bigg_set_bigz_bigz(res, accu1, accu2);
287
288         bigz_fini(accu1);
289         bigz_fini(accu2);
290 }
291
292 void bigg_sub(bigg res, bigg g1, bigg g2)
293 {
294         /* subtraction is defined point-wise */
295         bigz_sub(bigg_re(res), bigg_re(g1), bigg_re(g2));
296         bigz_sub(bigg_im(res), bigg_im(g1), bigg_im(g2));
297 }
298
299 void bigg_mul(bigg res, bigg g1, bigg g2)
300 {
301         /* multiplication is defined as:
302          * (a + bi)*(c + di) = (ac - bd) + (ad + bc)i
303          */
304         bigz accu1, accu2, accu3, accu4;
305         bigz_init(accu1);
306         bigz_init(accu2);
307         bigz_init(accu3);
308         bigz_init(accu4);
309
310         bigz_mul(accu1, bigg_re(g1), bigg_re(g2));
311         bigz_mul(accu2, bigg_im(g1), bigg_im(g2));
312         bigz_mul(accu3, bigg_re(g1), bigg_im(g2));
313         bigz_mul(accu4, bigg_im(g1), bigg_re(g2));
314
315         bigz_sub(bigg_re(res), accu1, accu2);
316         bigz_add(bigg_im(res), accu3, accu4);
317
318         bigz_fini(accu1);
319         bigz_fini(accu2);
320         bigz_fini(accu3);
321         bigz_fini(accu4);
322 }
323
324 void bigg_div(bigg res, bigg g1, bigg g2)
325 {
326         /* division is defined as:
327          * (a + bi) div (c + di) = ((a+bi)*(c-di)) div (c*c+d*d)
328          */
329         bigz accu1, accu2;
330         bigg accug;
331         bigz_init(accu1);
332         bigz_init(accu2);
333         bigg_init(accug);
334
335         /* compute: c^2 + d^2 */
336         bigz_mul(accu1, bigg_re(g2), bigg_re(g2));
337         bigz_mul(accu2, bigg_im(g2), bigg_im(g2));
338         bigz_add(accu1, accu1, accu2);
339
340         /* do normal multiplication with conjugate of g2 */
341         bigg_conj(accug, g2);
342         bigg_mul(accug, g1, accug);
343
344         bigg_set(res, accug);
345
346         /* now divide (g1*conj(g2)) by c^2+d^2 (point-wise) */
347         bigz_div(bigg_re(res), bigg_re(accug), accu1);
348         bigz_div(bigg_im(res), bigg_im(accug), accu1);
349
350         bigg_fini(accug);
351         bigz_fini(accu2);
352         bigz_fini(accu1);
353 }
354
355 void bigg_mod(bigg res, bigg g1, bigg g2)
356 {
357         /* the modulo relation is defined as:
358          * (a + bi) mod (c + di) ~
359          * (a+bi) - ((a+bi) div (c-di)) * (c+di)
360          */
361         bigg accug;
362         bigg_init(accug);
363
364         /* do normal division */
365         bigg_div(accug, g1, g2);
366
367         /* now re-multiply g2 */
368         bigg_mul(accug, accug, g2);
369
370         /* and find the difference */
371         bigg_sub(res, g1, accug);
372
373         bigg_fini(accug);
374 }
375
376 void bigg_pow(bigg res, bigg g1, unsigned long g2)
377 {
378 #if defined(HAVE_MPZ) && defined(WITH_GMP)
379         unsigned long i;
380         bigz bin, resintg, resimag, tmpbz1, tmpbz2, tmpbz3, intg, imag;
381
382         bigz_init(bin);
383         bigz_init(resintg);
384         bigz_init(resimag);
385         bigz_init(intg);
386         bigz_init(imag);
387         bigz_init(tmpbz1);
388         bigz_init(tmpbz2);
389         bigz_init(tmpbz3);
390
391         bigz_set_long(resintg, 0L);
392         bigz_set_long(resimag, 0L);
393
394         bigz_set(intg, bigg_re(g1));
395         bigz_set(imag, bigg_im(g1));
396
397         /* we compute using the binomial coefficients */
398         for (i=0; i<=g2; i++) {
399                 mpz_bin_uiui(bin, g2, i);
400                 if (i % 2 == 0) {
401                         /* real part changes */
402                         bigz_pow(tmpbz1, intg, g2-i);
403                         bigz_pow(tmpbz2, imag, i);
404                         bigz_mul(tmpbz3, tmpbz1, tmpbz2);
405                         bigz_mul(bin, bin, tmpbz3);
406                         if (i % 4 == 0) {
407                                 bigz_add(resintg, resintg, bin);
408                         } else if (i % 4 == 2) {
409                                 bigz_sub(resintg, resintg, bin);
410                         }
411                 } else {
412                         /* imag part changes */
413                         bigz_pow(tmpbz1, intg, g2-i);
414                         bigz_pow(tmpbz2, imag, i);
415                         bigz_mul(tmpbz3, tmpbz1, tmpbz2);
416                         bigz_mul(bin, bin, tmpbz3);
417                         if (i % 4 == 1) {
418                                 bigz_add(resimag, resimag, bin);
419                         } else if (i % 4 == 3) {
420                                 bigz_sub(resimag, resimag, bin);
421                         }
422                 }
423         }
424
425         bigg_set_bigz_bigz(res, resintg, resimag);
426
427         bigz_fini(bin);
428         bigz_fini(intg);
429         bigz_fini(imag);
430         bigz_init(resintg);
431         bigz_init(resimag);
432         bigz_fini(tmpbz1);
433         bigz_fini(tmpbz2);
434         bigz_fini(tmpbz3);
435 #else
436         bigg_set_long_long(res, 0L, 0L);
437 #endif
438 }
439
440 Lisp_Object read_bigg_string(char *cp)
441 {
442         bigz bz_re, bz_im;
443         int sign;
444         Lisp_Object result;
445         Bufbyte *end;
446         Bufbyte tmp;
447
448         bigz_init(bz_re);
449         bigz_init(bz_im);
450
451         /* MPZ bigz_set_string has no effect
452          * with initial + sign */
453         if (*cp == '+')
454                 cp++;
455
456         end = (Bufbyte *)cp;
457
458         if (*cp == '-') {
459                 /* jump over a leading minus */
460                 cp++;
461         }
462
463         while ((*cp >= '0' && *cp <= '9'))
464                 cp++;
465
466         /* MPZ cannot read numbers with characters after them.
467          * See limitations below in convert GMP-MPZ strings
468          */
469         tmp = (Bufbyte)*cp;
470         *cp = '\0';
471         bigz_set_string(bz_re, (char *)end, 0);
472         *cp = tmp;
473
474         /* read the imaginary part */
475         sign = 0;
476         if (*cp == '+') {
477                 cp++;
478                 sign = 1;
479         }
480         if (*cp == '-') {
481                 cp++;
482                 sign = -1;
483         }
484         if ((*cp == 'i' || *cp == 'I') && (sign == 1)) {
485                 /* expand +i to +1i and -i to -1i */
486                 bigz_set_long(bz_im, 1L);
487         } else if ((*cp == 'i' || *cp == 'I') && (sign == -1)) {
488                 /* expand +i to +1i and -i to -1i */
489                 bigz_set_long(bz_im, -1L);
490         } else if (sign == 0) {
491                 /* obviously we did not have a+bi,
492                  * but merely bi
493                  */
494                 bigz_set(bz_im, bz_re);
495                 bigz_set_long(bz_re, 0L);
496         } else {
497                 end = (Bufbyte*)cp;
498                 if (sign == -1)
499                         end--;
500                 while ((*cp >= '0' && *cp <= '9'))
501                         cp++;
502                 tmp = (Bufbyte)*cp;
503                 *cp = '\0';
504                 bigz_set_string(bz_im, (char *)end, 0);
505                 *cp = tmp;
506         }
507
508         result = make_bigg_bz(bz_re, bz_im);
509
510         bigz_fini(bz_re);
511         bigz_fini(bz_im);
512         return result;
513 }
514
515 /* bigg ops */
516 static inline int
517 ent_gaussian_zerop(Lisp_Object o)
518 {
519         return (bigz_sign(bigg_re(XBIGG_DATA(o))) == 0 &&
520                 bigz_sign(bigg_im(XBIGG_DATA(o))) == 0);
521 }
522
523 static inline int
524 ent_gaussian_onep(Lisp_Object o)
525 {
526         return ((bigz_fits_long_p(bigg_re(XBIGG_DATA(o))) &&
527                  bigz_to_long(bigg_re(XBIGG_DATA(o))) == 1L) &&
528                 bigz_sign(bigg_im(XBIGG_DATA(o))) == 0);
529 }
530
531 static inline int
532 ent_gaussian_unitp(Lisp_Object o)
533 {
534         return (!ent_gaussian_zerop(o) &&
535                 (bigz_fits_long_p(bigg_re(XBIGG_DATA(o))) &&
536                  (bigz_to_long(bigg_re(XBIGG_DATA(o))) == 0L ||
537                   bigz_to_long(bigg_re(XBIGG_DATA(o))) == 1L ||
538                   bigz_to_long(bigg_re(XBIGG_DATA(o))) == -1L)) &&
539                 (bigz_fits_long_p(bigg_im(XBIGG_DATA(o))) &&
540                  (bigz_to_long(bigg_im(XBIGG_DATA(o))) == 0L ||
541                   bigz_to_long(bigg_im(XBIGG_DATA(o))) == 1L ||
542                   bigz_to_long(bigg_im(XBIGG_DATA(o))) == -1L)));
543 }
544
545 static inline Lisp_Object
546 ent_sum_BIGG_T(Lisp_Object l, Lisp_Object r)
547 {
548         bigg_add(ent_scratch_bigg, XBIGG_DATA(l), XBIGG_DATA(r));
549         return make_bigg_bg(ent_scratch_bigg);
550 }
551 static inline Lisp_Object
552 ent_sum_BIGG_T_COMPARABLE(Lisp_Object l, Lisp_Object r)
553 {
554         CHECK_COMPARABLE(r);
555
556         r = ent_lift(r, BIGZ_T, NULL);
557
558         bigg_set_bigz(ent_scratch_bigg, XBIGZ_DATA(r));
559         bigg_add(ent_scratch_bigg, XBIGG_DATA(l), ent_scratch_bigg);
560         return make_bigg_bg(ent_scratch_bigg);
561 }
562 static inline Lisp_Object
563 ent_sum_COMPARABLE_BIGG_T(Lisp_Object l, Lisp_Object r)
564 {
565         CHECK_COMPARABLE(l);
566
567         l = ent_lift(l, BIGZ_T, NULL);
568
569         bigg_set_bigz(ent_scratch_bigg, XBIGZ_DATA(l));
570         bigg_add(ent_scratch_bigg, ent_scratch_bigg, XBIGG_DATA(r));
571         return make_bigg_bg(ent_scratch_bigg);
572 }
573
574 static inline Lisp_Object
575 ent_diff_BIGG_T(Lisp_Object l, Lisp_Object r)
576 {
577         bigg_sub(ent_scratch_bigg, XBIGG_DATA(l), XBIGG_DATA(r));
578         return make_bigg_bg(ent_scratch_bigg);
579 }
580 static inline Lisp_Object
581 ent_diff_BIGG_T_COMPARABLE(Lisp_Object l, Lisp_Object r)
582 {
583         CHECK_COMPARABLE(r);
584
585         r = ent_lift(r, BIGZ_T, NULL);
586
587         bigg_set_bigz(ent_scratch_bigg, XBIGZ_DATA(r));
588         bigg_sub(ent_scratch_bigg, XBIGG_DATA(l), ent_scratch_bigg);
589         return make_bigg_bg(ent_scratch_bigg);
590 }
591 static inline Lisp_Object
592 ent_diff_COMPARABLE_BIGG_T(Lisp_Object l, Lisp_Object r)
593 {
594         CHECK_COMPARABLE(l);
595
596         l = ent_lift(l, BIGZ_T, NULL);
597
598         bigg_set_bigz(ent_scratch_bigg, XBIGZ_DATA(l));
599         bigg_sub(ent_scratch_bigg, ent_scratch_bigg, XBIGG_DATA(r));
600         return make_bigg_bg(ent_scratch_bigg);
601 }
602
603 static inline Lisp_Object
604 ent_neg_BIGG_T(Lisp_Object l)
605 {
606         bigg_neg(ent_scratch_bigg, XBIGG_DATA(l));
607         return make_bigg_bg(ent_scratch_bigg);
608 }
609
610 static inline Lisp_Object
611 ent_prod_BIGG_T(Lisp_Object l, Lisp_Object r)
612 {
613         bigg_mul(ent_scratch_bigg, XBIGG_DATA(l), XBIGG_DATA(r));
614         return make_bigg_bg(ent_scratch_bigg);
615 }
616 static inline Lisp_Object
617 ent_prod_BIGG_T_COMPARABLE(Lisp_Object l, Lisp_Object r)
618 {
619         CHECK_COMPARABLE(r);
620
621         r = ent_lift(r, BIGZ_T, NULL);
622
623         bigg_set_bigz(ent_scratch_bigg, XBIGZ_DATA(r));
624         bigg_mul(ent_scratch_bigg, XBIGG_DATA(l), ent_scratch_bigg);
625         return make_bigg_bg(ent_scratch_bigg);
626 }
627 static inline Lisp_Object
628 ent_prod_COMPARABLE_BIGG_T(Lisp_Object l, Lisp_Object r)
629 {
630         CHECK_COMPARABLE(l);
631
632         l = ent_lift(l, BIGZ_T, NULL);
633
634         bigg_set_bigz(ent_scratch_bigg, XBIGZ_DATA(l));
635         bigg_mul(ent_scratch_bigg, ent_scratch_bigg, XBIGG_DATA(r));
636         return make_bigg_bg(ent_scratch_bigg);
637 }
638
639 static inline Lisp_Object
640 ent_div_BIGG_T(Lisp_Object l, Lisp_Object r)
641 {
642         if (ent_gaussian_zerop(r)) {
643                 if (!ent_gaussian_zerop(l)) {
644                         return make_indef(COMPLEX_INFINITY);
645                 } else {
646                         return make_indef(NOT_A_NUMBER);
647                 }
648         }
649         bigg_div(ent_scratch_bigg, XBIGG_DATA(l), XBIGG_DATA(r));
650         return make_bigg_bg(ent_scratch_bigg);
651 }
652 static inline Lisp_Object
653 ent_div_BIGG_T_COMPARABLE(Lisp_Object l, Lisp_Object r)
654 {
655         CHECK_COMPARABLE(r);
656
657         if (ent_unrel_zerop(l)) {
658                 if (!ent_gaussian_zerop(l)) {
659                         return make_indef(COMPLEX_INFINITY);
660                 } else {
661                         return make_indef(NOT_A_NUMBER);
662                 }
663         }
664
665         r = ent_lift(r, BIGZ_T, NULL);
666
667         bigg_set_bigz(ent_scratch_bigg, XBIGZ_DATA(r));
668         bigg_div(ent_scratch_bigg, XBIGG_DATA(l), ent_scratch_bigg);
669         return make_bigg_bg(ent_scratch_bigg);
670 }
671 static inline Lisp_Object
672 ent_div_COMPARABLE_BIGG_T(Lisp_Object l, Lisp_Object r)
673 {
674         CHECK_COMPARABLE(l);
675
676         if (ent_gaussian_zerop(r)) {
677                 if (!ent_unrel_zerop(l)) {
678                         return make_indef(COMPLEX_INFINITY);
679                 } else {
680                         return make_indef(NOT_A_NUMBER);
681                 }
682         }
683
684         l = ent_lift(l, BIGZ_T, NULL);
685
686         bigg_set_bigz(ent_scratch_bigg, XBIGZ_DATA(l));
687         bigg_div(ent_scratch_bigg, ent_scratch_bigg, XBIGG_DATA(r));
688         return make_bigg_bg(ent_scratch_bigg);
689 }
690
691 #if defined HAVE_MPC && defined WITH_MPC ||     \
692         defined HAVE_PSEUC && defined WITH_PSEUC
693 static inline Lisp_Object
694 ent_quo_BIGG_T(Lisp_Object l, Lisp_Object r)
695 {
696         Lisp_Object tmp_l, tmp_r;
697
698         if (ent_gaussian_zerop(r)) {
699                 if (!ent_gaussian_zerop(l)) {
700                         return make_indef(COMPLEX_INFINITY);
701                 } else {
702                         return make_indef(NOT_A_NUMBER);
703                 }
704         }
705
706         bigc_set_prec(ent_scratch_bigc, internal_get_precision(Qnil));
707         tmp_l = Fcoerce_number(l, Qbigc, Qnil);
708         tmp_r = Fcoerce_number(r, Qbigc, Qnil);
709         bigc_div(ent_scratch_bigc, XBIGC_DATA(tmp_l), XBIGC_DATA(tmp_r));
710         return make_bigc_bc(ent_scratch_bigc);
711 }
712 static inline Lisp_Object
713 ent_quo_BIGG_T_COMPARABLE(Lisp_Object l, Lisp_Object r)
714 {
715         CHECK_COMPARABLE(r);
716
717         if (ent_unrel_zerop(r)) {
718                 if (!ent_gaussian_zerop(l)) {
719                         return make_indef(COMPLEX_INFINITY);
720                 } else {
721                         return make_indef(NOT_A_NUMBER);
722                 }
723         }
724
725         l = ent_lift(l, BIGC_T, NULL);
726         return ent_binop(ASE_BINARY_OP_QUO, l, r);
727 }
728 static inline Lisp_Object
729 ent_quo_COMPARABLE_BIGG_T(Lisp_Object l, Lisp_Object r)
730 {
731         CHECK_COMPARABLE(l);
732
733         if (ent_gaussian_zerop(r)) {
734                 if (!ent_unrel_zerop(l)) {
735                         return make_indef(COMPLEX_INFINITY);
736                 } else {
737                         return make_indef(NOT_A_NUMBER);
738                 }
739         }
740
741         r = ent_lift(r, BIGC_T, NULL);
742         return ent_binop(ASE_BINARY_OP_QUO, l, r);
743 }
744 #endif
745
746 static inline Lisp_Object
747 ent_inv_BIGG_T(Lisp_Object r)
748 {
749         if (ent_gaussian_zerop(r)) {
750                 return make_indef(COMPLEX_INFINITY);
751         }
752         bigg_div(ent_scratch_bigg,
753                  XBIGG_DATA(Qent_gaussian_one), XBIGG_DATA(r));
754         return make_bigg_bg(ent_scratch_bigg);
755 }
756 static inline Lisp_Object
757 ent_rem_BIGG_T(Lisp_Object l, Lisp_Object r)
758 {
759         if (ent_gaussian_zerop(r)) {
760                 return make_bigg(0, 0);
761         }
762         bigg_mod(ent_scratch_bigg, XBIGG_DATA(l), XBIGG_DATA(r));
763         return make_bigg_bg(ent_scratch_bigg);
764 }
765 static inline Lisp_Object
766 ent_pow_BIGG_T_integer(Lisp_Object l, Lisp_Object r)
767 {
768         long unsigned int expo = 0UL;
769
770         if (INTP(r)) {
771                 expo = ent_int(r);
772         } else if (BIGZP(r)) {
773                 if (bigz_fits_ulong_p(XBIGZ_DATA(r)))
774                         expo = bigz_to_ulong(XBIGZ_DATA(r));
775                 else
776                         Fsignal(Qarith_error, r);
777         } else {
778                 Fsignal(Qdomain_error, r);
779         }
780         bigg_pow(ent_scratch_bigg, XBIGG_DATA(l), expo);
781         return make_bigg_bg(ent_scratch_bigg);
782 }
783
784 /* relations */
785 static inline int
786 ent_eq_bigg(Lisp_Object l, Lisp_Object r)
787 {
788         return (bigz_eql(bigg_re(XBIGG_DATA(l)), bigg_re(XBIGG_DATA(r))) &&
789                 bigz_eql(bigg_im(XBIGG_DATA(l)), bigg_im(XBIGG_DATA(r))));
790 }
791
792 static inline int
793 ent_ne_bigg(Lisp_Object l, Lisp_Object r)
794 {
795         return !(bigz_eql(bigg_re(XBIGG_DATA(l)), bigg_re(XBIGG_DATA(r))) &&
796                  bigz_eql(bigg_im(XBIGG_DATA(l)), bigg_im(XBIGG_DATA(r))));
797 }
798
799 #if 0
800 static inline Lisp_Object
801 ent_vallt_BIGG_T(Lisp_Object l, Lisp_Object r)
802 {
803         bigz b2;
804         int result;
805
806         bigz_init(b2);
807         bigg_norm(ent_scratch_bigz, XBIGG_DATA(l));
808         bigg_norm(b2, XBIGG_DATA(r));
809         result = bigz_lt(ent_scratch_bigz, b2);
810
811         bigz_fini(b2);
812         return (result) ? Qt : Qnil;
813 }
814 static inline Lisp_Object
815 ent_valgt_BIGG_T(Lisp_Object l, Lisp_Object r)
816 {
817         bigz b2;
818         int result;
819
820         bigz_init(b2);
821         bigg_norm(ent_scratch_bigz, XBIGG_DATA(l));
822         bigg_norm(b2, XBIGG_DATA(r));
823         result = bigz_gt(ent_scratch_bigz, b2);
824
825         bigz_fini(b2);
826         return (result) ? Qt : Qnil;
827 }
828 static inline Lisp_Object
829 ent_valeq_BIGG_T(Lisp_Object l, Lisp_Object r)
830 {
831         bigz b2;
832         int result;
833
834         bigz_init(b2);
835         bigg_norm(ent_scratch_bigz, XBIGG_DATA(l));
836         bigg_norm(b2, XBIGG_DATA(r));
837         result = bigz_eql(ent_scratch_bigz, b2);
838
839         bigz_fini(b2);
840         return (result) ? Qt : Qnil;
841 }
842 static inline Lisp_Object
843 ent_valne_BIGG_T(Lisp_Object l, Lisp_Object r)
844 {
845         bigz b2;
846         int result;
847
848         bigz_init(b2);
849         bigg_norm(ent_scratch_bigz, XBIGG_DATA(l));
850         bigg_norm(b2, XBIGG_DATA(r));
851         result = bigz_eql(ent_scratch_bigz, b2);
852
853         bigz_fini(b2);
854         return (result) ? Qnil : Qt;
855 }
856 #endif
857
858 \f
859 static Lisp_Object
860 ent_lift_all_BIGG_T(Lisp_Object number, ent_lift_args_t SXE_UNUSED(la))
861 {
862         number = ent_lift(number, BIGZ_T, NULL);
863         bigg_set_bigz(ent_scratch_bigg, XBIGZ_DATA(number));
864         return make_bigg_bg(ent_scratch_bigg);
865 }
866
867 #if defined HAVE_MPC && defined WITH_MPC ||     \
868         defined HAVE_PSEUC && defined WITH_PSEUC
869 static Lisp_Object
870 ent_lift_BIGC_T_BIGG_T(Lisp_Object number, ent_lift_args_t SXE_UNUSED(la))
871 {
872         Lisp_Object re, im;
873
874         re = Freal_part(number);
875         re = ent_lift(re, BIGZ_T, NULL);
876         im = Fimaginary_part(number);
877         im = ent_lift(im, BIGZ_T, NULL);
878
879         return make_bigg_bz(XBIGZ_DATA(re), XBIGZ_DATA(im));
880 }
881 #endif
882
883 \f
884 static inline void
885 ent_gaussian_nullary_optable_init(void)
886 {
887         Qent_gaussian_zero = make_bigg(0L, 0L);
888         Qent_gaussian_one = make_bigg(1L, 0L);
889         staticpro(&Qent_gaussian_zero);
890         staticpro(&Qent_gaussian_one);
891
892         ent_nullop_register(ASE_NULLARY_OP_ZERO, BIGG_T, Qent_gaussian_zero);
893         ent_nullop_register(ASE_NULLARY_OP_ONE, BIGG_T, Qent_gaussian_one);
894 }
895
896 static inline void
897 ent_gaussian_unary_optable_init(void)
898 {
899         ent_unop_register(ASE_UNARY_OP_NEG, BIGG_T, ent_neg_BIGG_T);
900         ent_unop_register(ASE_UNARY_OP_INV, BIGG_T, ent_inv_BIGG_T);
901 }
902
903 static inline void
904 ent_gaussian_binary_optable_init(void)
905 {
906         /* sums */
907         ent_binop_register(ASE_BINARY_OP_SUM,
908                            BIGG_T, BIGG_T, ent_sum_BIGG_T);
909         ent_binop_register(ASE_BINARY_OP_SUM,
910                            BIGG_T, INT_T, ent_sum_BIGG_T_COMPARABLE);
911         ent_binop_register(ASE_BINARY_OP_SUM,
912                            INT_T, BIGG_T, ent_sum_COMPARABLE_BIGG_T);
913 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
914         ent_binop_register(ASE_BINARY_OP_SUM,
915                            BIGG_T, BIGZ_T, ent_sum_BIGG_T_COMPARABLE);
916         ent_binop_register(ASE_BINARY_OP_SUM,
917                            BIGZ_T, BIGG_T, ent_sum_COMPARABLE_BIGG_T);
918 #endif
919 #if defined HAVE_MPQ && defined WITH_GMP
920         ent_binop_register(ASE_BINARY_OP_SUM,
921                            BIGG_T, BIGQ_T, ent_sum_BIGG_T_COMPARABLE);
922         ent_binop_register(ASE_BINARY_OP_SUM,
923                            BIGQ_T, BIGG_T, ent_sum_COMPARABLE_BIGG_T);
924 #endif
925 #if defined HAVE_MPF && defined WITH_GMP
926         ent_binop_register(ASE_BINARY_OP_SUM,
927                            BIGG_T, BIGF_T, ent_sum_BIGG_T_COMPARABLE);
928         ent_binop_register(ASE_BINARY_OP_SUM,
929                            BIGF_T, BIGG_T, ent_sum_COMPARABLE_BIGG_T);
930 #endif
931 #if defined HAVE_MPFR && defined WITH_MPFR
932         ent_binop_register(ASE_BINARY_OP_SUM,
933                            BIGG_T, BIGFR_T, ent_sum_BIGG_T_COMPARABLE);
934         ent_binop_register(ASE_BINARY_OP_SUM,
935                            BIGFR_T, BIGG_T, ent_sum_COMPARABLE_BIGG_T);
936 #endif
937 #ifdef HAVE_FPFLOAT
938         ent_binop_register(ASE_BINARY_OP_SUM,
939                            BIGG_T, FLOAT_T, ent_sum_BIGG_T_COMPARABLE);
940         ent_binop_register(ASE_BINARY_OP_SUM,
941                            FLOAT_T, BIGG_T, ent_sum_COMPARABLE_BIGG_T);
942 #endif
943         /* diffs */
944         ent_binop_register(ASE_BINARY_OP_DIFF,
945                            BIGG_T, BIGG_T, ent_diff_BIGG_T);
946         ent_binop_register(ASE_BINARY_OP_DIFF,
947                            BIGG_T, INT_T, ent_diff_BIGG_T_COMPARABLE);
948         ent_binop_register(ASE_BINARY_OP_DIFF,
949                            INT_T, BIGG_T, ent_diff_COMPARABLE_BIGG_T);
950         ent_binop_register(ASE_BINARY_OP_DIFF,
951                            BIGG_T, BIGZ_T, ent_diff_BIGG_T_COMPARABLE);
952         ent_binop_register(ASE_BINARY_OP_DIFF,
953                            BIGZ_T, BIGG_T, ent_diff_COMPARABLE_BIGG_T);
954 #if defined HAVE_MPQ && defined WITH_GMP
955         ent_binop_register(ASE_BINARY_OP_DIFF,
956                            BIGG_T, BIGQ_T, ent_diff_BIGG_T_COMPARABLE);
957         ent_binop_register(ASE_BINARY_OP_DIFF,
958                            BIGQ_T, BIGG_T, ent_diff_COMPARABLE_BIGG_T);
959 #endif
960 #if defined HAVE_MPF && defined WITH_GMP
961         ent_binop_register(ASE_BINARY_OP_DIFF,
962                            BIGG_T, BIGF_T, ent_diff_BIGG_T_COMPARABLE);
963         ent_binop_register(ASE_BINARY_OP_DIFF,
964                            BIGF_T, BIGG_T, ent_diff_COMPARABLE_BIGG_T);
965 #endif
966 #if defined HAVE_MPFR && defined WITH_MPFR
967         ent_binop_register(ASE_BINARY_OP_DIFF,
968                            BIGG_T, BIGFR_T, ent_diff_BIGG_T_COMPARABLE);
969         ent_binop_register(ASE_BINARY_OP_DIFF,
970                            BIGFR_T, BIGG_T, ent_diff_COMPARABLE_BIGG_T);
971 #endif
972 #ifdef HAVE_FPFLOAT
973         ent_binop_register(ASE_BINARY_OP_DIFF,
974                            BIGG_T, FLOAT_T, ent_diff_BIGG_T_COMPARABLE);
975         ent_binop_register(ASE_BINARY_OP_DIFF,
976                            FLOAT_T, BIGG_T, ent_diff_COMPARABLE_BIGG_T);
977 #endif
978         /* prods */
979         ent_binop_register(ASE_BINARY_OP_PROD,
980                            BIGG_T, BIGG_T, ent_prod_BIGG_T);
981         ent_binop_register(ASE_BINARY_OP_PROD,
982                            BIGG_T, INT_T, ent_prod_BIGG_T_COMPARABLE);
983         ent_binop_register(ASE_BINARY_OP_PROD,
984                            INT_T, BIGG_T, ent_prod_COMPARABLE_BIGG_T);
985         ent_binop_register(ASE_BINARY_OP_PROD,
986                            BIGG_T, BIGZ_T, ent_prod_BIGG_T_COMPARABLE);
987         ent_binop_register(ASE_BINARY_OP_PROD,
988                            BIGZ_T, BIGG_T, ent_prod_COMPARABLE_BIGG_T);
989 #if defined HAVE_MPQ && defined WITH_GMP
990         ent_binop_register(ASE_BINARY_OP_PROD,
991                            BIGG_T, BIGQ_T, ent_prod_BIGG_T_COMPARABLE);
992         ent_binop_register(ASE_BINARY_OP_PROD,
993                            BIGQ_T, BIGG_T, ent_prod_COMPARABLE_BIGG_T);
994 #endif
995 #if defined HAVE_MPF && defined WITH_GMP
996         ent_binop_register(ASE_BINARY_OP_PROD,
997                            BIGG_T, BIGF_T, ent_prod_BIGG_T_COMPARABLE);
998         ent_binop_register(ASE_BINARY_OP_PROD,
999                            BIGF_T, BIGG_T, ent_prod_COMPARABLE_BIGG_T);
1000 #endif
1001 #if defined HAVE_MPFR && defined WITH_MPFR
1002         ent_binop_register(ASE_BINARY_OP_PROD,
1003                            BIGG_T, BIGFR_T, ent_prod_BIGG_T_COMPARABLE);
1004         ent_binop_register(ASE_BINARY_OP_PROD,
1005                            BIGFR_T, BIGG_T, ent_prod_COMPARABLE_BIGG_T);
1006 #endif
1007 #ifdef HAVE_FPFLOAT
1008         ent_binop_register(ASE_BINARY_OP_PROD,
1009                            BIGG_T, FLOAT_T, ent_prod_BIGG_T_COMPARABLE);
1010         ent_binop_register(ASE_BINARY_OP_PROD,
1011                            FLOAT_T, BIGG_T, ent_prod_COMPARABLE_BIGG_T);
1012 #endif
1013
1014         /* divisions and quotients */
1015         ent_binop_register(ASE_BINARY_OP_DIV,
1016                            BIGG_T, BIGG_T, ent_div_BIGG_T);
1017         ent_binop_register(ASE_BINARY_OP_DIV,
1018                            BIGG_T, INT_T, ent_div_BIGG_T_COMPARABLE);
1019         ent_binop_register(ASE_BINARY_OP_DIV,
1020                            INT_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1021         ent_binop_register(ASE_BINARY_OP_DIV,
1022                            BIGG_T, BIGZ_T, ent_div_BIGG_T_COMPARABLE);
1023         ent_binop_register(ASE_BINARY_OP_DIV,
1024                            BIGZ_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1025 #if defined HAVE_MPQ && defined WITH_GMP
1026         ent_binop_register(ASE_BINARY_OP_DIV,
1027                            BIGG_T, BIGQ_T, ent_div_BIGG_T_COMPARABLE);
1028         ent_binop_register(ASE_BINARY_OP_DIV,
1029                            BIGQ_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1030 #endif
1031 #if defined HAVE_MPF && defined WITH_GMP
1032         ent_binop_register(ASE_BINARY_OP_DIV,
1033                            BIGG_T, BIGF_T, ent_div_BIGG_T_COMPARABLE);
1034         ent_binop_register(ASE_BINARY_OP_DIV,
1035                            BIGF_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1036 #endif
1037 #if defined HAVE_MPFR && defined WITH_MPFR
1038         ent_binop_register(ASE_BINARY_OP_DIV,
1039                            BIGG_T, BIGFR_T, ent_div_BIGG_T_COMPARABLE);
1040         ent_binop_register(ASE_BINARY_OP_DIV,
1041                            BIGFR_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1042 #endif
1043 #ifdef HAVE_FPFLOAT
1044         ent_binop_register(ASE_BINARY_OP_DIV,
1045                            BIGG_T, FLOAT_T, ent_div_BIGG_T_COMPARABLE);
1046         ent_binop_register(ASE_BINARY_OP_DIV,
1047                            FLOAT_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1048 #endif
1049
1050 #if defined HAVE_MPC && defined WITH_MPC ||     \
1051         defined HAVE_PSEUC && defined WITH_PSEUC
1052         ent_binop_register(ASE_BINARY_OP_QUO,
1053                            BIGG_T, BIGG_T, ent_quo_BIGG_T);
1054         ent_binop_register(ASE_BINARY_OP_QUO,
1055                            BIGG_T, BIGZ_T, ent_quo_BIGG_T_COMPARABLE);
1056         ent_binop_register(ASE_BINARY_OP_QUO,
1057                            BIGZ_T, BIGG_T, ent_quo_COMPARABLE_BIGG_T);
1058 #if defined HAVE_MPQ && defined WITH_GMP
1059         ent_binop_register(ASE_BINARY_OP_QUO,
1060                            BIGG_T, BIGQ_T, ent_quo_BIGG_T_COMPARABLE);
1061         ent_binop_register(ASE_BINARY_OP_QUO,
1062                            BIGQ_T, BIGG_T, ent_quo_COMPARABLE_BIGG_T);
1063 #endif
1064 #if defined HAVE_MPF && defined WITH_GMP
1065         ent_binop_register(ASE_BINARY_OP_QUO,
1066                            BIGG_T, BIGF_T, ent_quo_BIGG_T_COMPARABLE);
1067         ent_binop_register(ASE_BINARY_OP_QUO,
1068                            BIGF_T, BIGG_T, ent_quo_COMPARABLE_BIGG_T);
1069 #endif
1070 #if defined HAVE_MPFR && defined WITH_MPFR
1071         ent_binop_register(ASE_BINARY_OP_QUO,
1072                            BIGG_T, BIGFR_T, ent_quo_BIGG_T_COMPARABLE);
1073         ent_binop_register(ASE_BINARY_OP_QUO,
1074                            BIGFR_T, BIGG_T, ent_quo_COMPARABLE_BIGG_T);
1075 #endif
1076 #ifdef HAVE_FPFLOAT
1077         ent_binop_register(ASE_BINARY_OP_QUO,
1078                            BIGG_T, FLOAT_T, ent_quo_BIGG_T_COMPARABLE);
1079         ent_binop_register(ASE_BINARY_OP_QUO,
1080                            FLOAT_T, BIGG_T, ent_quo_COMPARABLE_BIGG_T);
1081 #endif
1082 #else  /* !HAVE_MPC */
1083         ent_binop_register(ASE_BINARY_OP_QUO,
1084                            BIGG_T, BIGG_T, ent_div_BIGG_T);
1085         ent_binop_register(ASE_BINARY_OP_QUO,
1086                            BIGG_T, BIGZ_T, ent_div_BIGG_T_COMPARABLE);
1087         ent_binop_register(ASE_BINARY_OP_QUO,
1088                            BIGZ_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1089 #if defined HAVE_MPQ && defined WITH_GMP
1090         ent_binop_register(ASE_BINARY_OP_QUO,
1091                            BIGG_T, BIGQ_T, ent_div_BIGG_T_COMPARABLE);
1092         ent_binop_register(ASE_BINARY_OP_QUO,
1093                            BIGQ_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1094 #endif
1095 #if defined HAVE_MPF && defined WITH_GMP
1096         ent_binop_register(ASE_BINARY_OP_QUO,
1097                            BIGG_T, BIGF_T, ent_div_BIGG_T_COMPARABLE);
1098         ent_binop_register(ASE_BINARY_OP_QUO,
1099                            BIGF_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1100 #endif
1101 #if defined HAVE_MPFR && defined WITH_MPFR
1102         ent_binop_register(ASE_BINARY_OP_QUO,
1103                            BIGG_T, BIGFR_T, ent_div_BIGG_T_COMPARABLE);
1104         ent_binop_register(ASE_BINARY_OP_QUO,
1105                            BIGFR_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1106 #endif
1107 #ifdef HAVE_FPFLOAT
1108         ent_binop_register(ASE_BINARY_OP_QUO,
1109                            BIGG_T, FLOAT_T, ent_div_BIGG_T_COMPARABLE);
1110         ent_binop_register(ASE_BINARY_OP_QUO,
1111                            FLOAT_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1112 #endif
1113 #endif
1114         ent_binop_register(ASE_BINARY_OP_REM,
1115                            BIGG_T, BIGG_T, ent_rem_BIGG_T);
1116         ent_binop_register(ASE_BINARY_OP_MOD,
1117                            BIGG_T, BIGG_T, ent_rem_BIGG_T);
1118         ent_binop_register(ASE_BINARY_OP_POW,
1119                            BIGG_T, INT_T, ent_pow_BIGG_T_integer);
1120         ent_binop_register(ASE_BINARY_OP_POW,
1121                            BIGG_T, BIGZ_T, ent_pow_BIGG_T_integer);
1122 }
1123
1124 static inline void
1125 ent_gaussian_unary_reltable_init(void)
1126 {
1127         ent_unrel_register(ASE_UNARY_REL_ZEROP, BIGG_T, ent_gaussian_zerop);
1128         ent_unrel_register(ASE_UNARY_REL_ONEP, BIGG_T, ent_gaussian_onep);
1129         ent_unrel_register(ASE_UNARY_REL_UNITP, BIGG_T, ent_gaussian_unitp);
1130 }
1131
1132 static inline void
1133 ent_gaussian_binary_reltable_init(void)
1134 {
1135         ent_binrel_register(ASE_BINARY_REL_EQUALP,
1136                             BIGG_T, BIGG_T, ent_eq_bigg);
1137         ent_binrel_register(ASE_BINARY_REL_NEQP,
1138                             BIGG_T, BIGG_T, ent_ne_bigg);
1139 }
1140
1141 static inline void
1142 ent_gaussian_lifttable_init(void)
1143 {
1144         ent_lift_register(INT_T, BIGG_T, ent_lift_all_BIGG_T);
1145         ent_lift_register(BIGZ_T, BIGC_T, ent_lift_all_BIGG_T);
1146 #if defined HAVE_MPQ && defined WITH_GMP
1147         ent_lift_register(BIGQ_T, BIGG_T, ent_lift_all_BIGG_T);
1148 #endif
1149 #if defined HAVE_MPF && defined WITH_GMP
1150         ent_lift_register(BIGF_T, BIGG_T, ent_lift_all_BIGG_T);
1151 #endif
1152 #if defined HAVE_MPFR && defined WITH_MPFR
1153         ent_lift_register(BIGFR_T, BIGG_T, ent_lift_all_BIGG_T);
1154 #endif
1155 #ifdef HAVE_FPFLOAT
1156         ent_lift_register(FLOAT_T, BIGG_T, ent_lift_all_BIGG_T);
1157 #endif
1158 #if defined HAVE_MPC && defined WITH_MPC ||     \
1159         defined HAVE_PSEUC && defined WITH_PSEUC
1160         ent_lift_register(BIGC_T, BIGG_T, ent_lift_BIGC_T_BIGG_T);
1161 #endif
1162 }
1163
1164 void init_optables_BIGG_T(void)
1165 {
1166         ent_gaussian_nullary_optable_init();
1167         ent_gaussian_unary_optable_init();
1168         ent_gaussian_binary_optable_init();
1169         ent_gaussian_unary_reltable_init();
1170         ent_gaussian_binary_reltable_init();
1171         ent_gaussian_lifttable_init();
1172 }
1173
1174 void init_ent_gaussian(void)
1175 {
1176         bigg_init(ent_scratch_bigg);
1177 }
1178
1179 void syms_of_ent_gaussian(void)
1180 {
1181         INIT_LRECORD_IMPLEMENTATION(bigg);
1182
1183         DEFSUBR(Fmake_bigg);
1184 }
1185
1186 void vars_of_ent_gaussian(void)
1187 {
1188         Fprovide(intern("bigg"));
1189         Fprovide(intern("gaussian"));
1190 }