2 ent-gaussian.c -- Numeric types for SXEmacs
3 Copyright (C) 2005, 2006 Sebastian Freundt
5 Author: Sebastian Freundt
7 This file is part of SXEmacs
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.
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.
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/>. */
27 #include "sysproc.h" /* For qxe_getpid */
30 #include "ent-float.h"
34 #include "ent-gaussian.h"
39 bigg ent_scratch_bigg;
40 static ase_nullary_operation_f Qent_gaussian_zero, Qent_gaussian_one;
44 bigg_print(Lisp_Object obj, Lisp_Object printcharfun, int SXE_UNUSED(escapeflag))
46 Bufbyte *fstr = bigg_to_string(XBIGG_DATA(obj), 10);
47 write_c_string((char*)fstr, printcharfun);
49 fstr = (Bufbyte *)NULL;
54 bigg_equal(Lisp_Object obj1, Lisp_Object obj2, int depth)
56 return bigg_eql(XBIGG_DATA(obj1), XBIGG_DATA(obj2));
63 bigg_hash(Lisp_Object obj, int depth)
65 return bigg_hashcode(XBIGG_DATA(obj));
72 bigg_mark(Lisp_Object obj)
81 bigg_finalise(void *header, int for_disksave)
85 ("Can't dump an emacs containing "
86 "pseudo-gaussian objects",Qt);
92 static const struct lrecord_description bigg_description[] = {
93 { XD_OPAQUE_DATA_PTR, offsetof(Lisp_Bigg, data) },
97 DEFINE_BASIC_LRECORD_IMPLEMENTATION("bigg", bigg,
98 bigg_mark, bigg_print, bigg_finalise,
99 bigg_equal, bigg_hash,
100 bigg_description, Lisp_Bigg);
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.
106 (real_part, imaginary_part))
108 CHECK_COMPARABLE(real_part);
109 CHECK_COMPARABLE(imaginary_part);
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));
119 /* basic functions */
120 void bigg_init(bigg g)
122 bigz_init(bigg_re(g));
123 bigz_init(bigg_im(g));
126 void bigg_fini(bigg g)
128 bigz_fini(bigg_re(g));
129 bigz_fini(bigg_im(g));
132 unsigned long bigg_hashcode(bigg g)
134 return (bigz_hashcode(bigg_re(g)) ^
135 bigz_hashcode(bigg_im(g)));
138 Bufbyte *bigg_to_string(bigg g, int base)
142 int intg_len, imag_len;
145 intg_str = (Bufbyte*)bigz_to_string(bigg_re(g), base);
146 imag_str = (Bufbyte*)bigz_to_string(bigg_im(g), base);
148 intg_len = strlen((char*)intg_str);
149 imag_len = strlen((char*)imag_str);
151 sign = bigz_sign(bigg_im(g));
152 neg = (sign >= 0) ? 1 : 0;
154 /* now append the imaginary string */
155 XREALLOC_ARRAY(intg_str, Bufbyte, intg_len + neg + imag_len + 2);
157 intg_str[intg_len] = '+';
158 memmove(&intg_str[intg_len + neg],
161 intg_str[intg_len+neg+imag_len] = 'i';
162 intg_str[intg_len+neg+imag_len+1] = '\0';
168 /***** Bigg: converting assignments *****/
169 void bigg_set(bigg g1,bigg g2)
171 bigz_set(bigg_re(g1), bigg_re(g2));
172 bigz_set(bigg_im(g1), bigg_im(g2));
175 void bigg_set_long(bigg g, long l)
177 bigz_set_long(bigg_re(g), l);
178 bigz_set_long(bigg_im(g), 0L);
181 void bigg_set_long_long(bigg g, long l1, long l2)
183 bigz_set_long(bigg_re(g), l1);
184 bigz_set_long(bigg_im(g), l2);
187 void bigg_set_ulong(bigg g, unsigned long ul)
189 bigz_set_ulong(bigg_re(g), ul);
190 bigz_set_ulong(bigg_im(g), 0UL);
193 void bigg_set_ulong_ulong(bigg g, unsigned long ul1, unsigned long ul2)
195 bigz_set_ulong(bigg_re(g), ul1);
196 bigz_set_ulong(bigg_im(g), ul2);
199 void bigg_set_bigz(bigg g, bigz z)
201 bigz_set(bigg_re(g), z);
202 bigz_set_long(bigg_im(g), 0L);
205 void bigg_set_bigz_bigz(bigg g, bigz z1, bigz z2)
207 bigz_set(bigg_re(g), z1);
208 bigz_set(bigg_im(g), z2);
211 /* void bigc_set_bigg(bigc c, bigg g)
213 * bigc_set_bigfr_bigfr(bigg_re(g), z1);
217 /***** Bigg: comparisons *****/
218 int bigg_eql(bigg g1, bigg g2)
220 return ((bigz_eql(bigg_re(g1), bigg_re(g2))) &&
221 (bigz_eql(bigg_im(g1), bigg_im(g2))));
224 /***** Bigg: arithmetic *****/
225 #if defined HAVE_MPFR && defined WITH_MPFR
226 void bigg_abs(bigfr res, bigg g)
228 /* the absolute archimedean valuation of a+bi is defined as:
231 bigz accu1, accu2, bz;
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);
240 bigfr_set_bigz(res, bz);
241 bigfr_sqrt(res, res);
249 void bigg_norm(bigz res, bigg g)
251 /* norm is the square of the absolute archimedean valuation */
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);
264 void bigg_neg(bigg res, bigg g)
266 /* negation is defined point-wise */
267 bigz_neg(bigg_re(res), bigg_re(g));
268 bigz_neg(bigg_im(res), bigg_im(g));
271 void bigg_conj(bigg res, bigg g)
274 bigz_neg(bigg_im(res), bigg_im(res));
277 void bigg_add(bigg res, bigg g1, bigg g2)
279 /* addition is defined point-wise */
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);
292 void bigg_sub(bigg res, bigg g1, bigg g2)
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));
299 void bigg_mul(bigg res, bigg g1, bigg g2)
301 /* multiplication is defined as:
302 * (a + bi)*(c + di) = (ac - bd) + (ad + bc)i
304 bigz accu1, accu2, accu3, accu4;
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));
315 bigz_sub(bigg_re(res), accu1, accu2);
316 bigz_add(bigg_im(res), accu3, accu4);
324 void bigg_div(bigg res, bigg g1, bigg g2)
326 /* division is defined as:
327 * (a + bi) div (c + di) = ((a+bi)*(c-di)) div (c*c+d*d)
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);
340 /* do normal multiplication with conjugate of g2 */
341 bigg_conj(accug, g2);
342 bigg_mul(accug, g1, accug);
344 bigg_set(res, accug);
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);
355 void bigg_mod(bigg res, bigg g1, bigg g2)
357 /* the modulo relation is defined as:
358 * (a + bi) mod (c + di) ~
359 * (a+bi) - ((a+bi) div (c-di)) * (c+di)
364 /* do normal division */
365 bigg_div(accug, g1, g2);
367 /* now re-multiply g2 */
368 bigg_mul(accug, accug, g2);
370 /* and find the difference */
371 bigg_sub(res, g1, accug);
376 void bigg_pow(bigg res, bigg g1, unsigned long g2)
378 #if defined(HAVE_MPZ) && defined(WITH_GMP)
380 bigz bin, resintg, resimag, tmpbz1, tmpbz2, tmpbz3, intg, imag;
391 bigz_set_long(resintg, 0L);
392 bigz_set_long(resimag, 0L);
394 bigz_set(intg, bigg_re(g1));
395 bigz_set(imag, bigg_im(g1));
397 /* we compute using the binomial coefficients */
398 for (i=0; i<=g2; i++) {
399 mpz_bin_uiui(bin, g2, i);
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);
407 bigz_add(resintg, resintg, bin);
408 } else if (i % 4 == 2) {
409 bigz_sub(resintg, resintg, bin);
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);
418 bigz_add(resimag, resimag, bin);
419 } else if (i % 4 == 3) {
420 bigz_sub(resimag, resimag, bin);
425 bigg_set_bigz_bigz(res, resintg, resimag);
436 bigg_set_long_long(res, 0L, 0L);
440 Lisp_Object read_bigg_string(char *cp)
451 /* MPZ bigz_set_string has no effect
452 * with initial + sign */
459 /* jump over a leading minus */
463 while ((*cp >= '0' && *cp <= '9'))
466 /* MPZ cannot read numbers with characters after them.
467 * See limitations below in convert GMP-MPZ strings
471 bigz_set_string(bz_re, (char *)end, 0);
474 /* read the imaginary part */
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,
494 bigz_set(bz_im, bz_re);
495 bigz_set_long(bz_re, 0L);
500 while ((*cp >= '0' && *cp <= '9'))
504 bigz_set_string(bz_im, (char *)end, 0);
508 result = make_bigg_bz(bz_re, bz_im);
517 ent_gaussian_zerop(Lisp_Object o)
519 return (bigz_sign(bigg_re(XBIGG_DATA(o))) == 0 &&
520 bigz_sign(bigg_im(XBIGG_DATA(o))) == 0);
524 ent_gaussian_onep(Lisp_Object o)
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);
532 ent_gaussian_unitp(Lisp_Object o)
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)));
545 static inline Lisp_Object
546 ent_sum_BIGG_T(Lisp_Object l, Lisp_Object r)
548 bigg_add(ent_scratch_bigg, XBIGG_DATA(l), XBIGG_DATA(r));
549 return make_bigg_bg(ent_scratch_bigg);
551 static inline Lisp_Object
552 ent_sum_BIGG_T_COMPARABLE(Lisp_Object l, Lisp_Object r)
556 r = ent_lift(r, BIGZ_T, NULL);
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);
562 static inline Lisp_Object
563 ent_sum_COMPARABLE_BIGG_T(Lisp_Object l, Lisp_Object r)
567 l = ent_lift(l, BIGZ_T, NULL);
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);
574 static inline Lisp_Object
575 ent_diff_BIGG_T(Lisp_Object l, Lisp_Object r)
577 bigg_sub(ent_scratch_bigg, XBIGG_DATA(l), XBIGG_DATA(r));
578 return make_bigg_bg(ent_scratch_bigg);
580 static inline Lisp_Object
581 ent_diff_BIGG_T_COMPARABLE(Lisp_Object l, Lisp_Object r)
585 r = ent_lift(r, BIGZ_T, NULL);
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);
591 static inline Lisp_Object
592 ent_diff_COMPARABLE_BIGG_T(Lisp_Object l, Lisp_Object r)
596 l = ent_lift(l, BIGZ_T, NULL);
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);
603 static inline Lisp_Object
604 ent_neg_BIGG_T(Lisp_Object l)
606 bigg_neg(ent_scratch_bigg, XBIGG_DATA(l));
607 return make_bigg_bg(ent_scratch_bigg);
610 static inline Lisp_Object
611 ent_prod_BIGG_T(Lisp_Object l, Lisp_Object r)
613 bigg_mul(ent_scratch_bigg, XBIGG_DATA(l), XBIGG_DATA(r));
614 return make_bigg_bg(ent_scratch_bigg);
616 static inline Lisp_Object
617 ent_prod_BIGG_T_COMPARABLE(Lisp_Object l, Lisp_Object r)
621 r = ent_lift(r, BIGZ_T, NULL);
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);
627 static inline Lisp_Object
628 ent_prod_COMPARABLE_BIGG_T(Lisp_Object l, Lisp_Object r)
632 l = ent_lift(l, BIGZ_T, NULL);
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);
639 static inline Lisp_Object
640 ent_div_BIGG_T(Lisp_Object l, Lisp_Object r)
642 if (ent_gaussian_zerop(r)) {
643 if (!ent_gaussian_zerop(l)) {
644 return make_indef(COMPLEX_INFINITY);
646 return make_indef(NOT_A_NUMBER);
649 bigg_div(ent_scratch_bigg, XBIGG_DATA(l), XBIGG_DATA(r));
650 return make_bigg_bg(ent_scratch_bigg);
652 static inline Lisp_Object
653 ent_div_BIGG_T_COMPARABLE(Lisp_Object l, Lisp_Object r)
657 if (ent_unrel_zerop(l)) {
658 if (!ent_gaussian_zerop(l)) {
659 return make_indef(COMPLEX_INFINITY);
661 return make_indef(NOT_A_NUMBER);
665 r = ent_lift(r, BIGZ_T, NULL);
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);
671 static inline Lisp_Object
672 ent_div_COMPARABLE_BIGG_T(Lisp_Object l, Lisp_Object r)
676 if (ent_gaussian_zerop(r)) {
677 if (!ent_unrel_zerop(l)) {
678 return make_indef(COMPLEX_INFINITY);
680 return make_indef(NOT_A_NUMBER);
684 l = ent_lift(l, BIGZ_T, NULL);
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);
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)
696 Lisp_Object tmp_l, tmp_r;
698 if (ent_gaussian_zerop(r)) {
699 if (!ent_gaussian_zerop(l)) {
700 return make_indef(COMPLEX_INFINITY);
702 return make_indef(NOT_A_NUMBER);
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);
712 static inline Lisp_Object
713 ent_quo_BIGG_T_COMPARABLE(Lisp_Object l, Lisp_Object r)
717 if (ent_unrel_zerop(r)) {
718 if (!ent_gaussian_zerop(l)) {
719 return make_indef(COMPLEX_INFINITY);
721 return make_indef(NOT_A_NUMBER);
725 l = ent_lift(l, BIGC_T, NULL);
726 return ent_binop(ASE_BINARY_OP_QUO, l, r);
728 static inline Lisp_Object
729 ent_quo_COMPARABLE_BIGG_T(Lisp_Object l, Lisp_Object r)
733 if (ent_gaussian_zerop(r)) {
734 if (!ent_unrel_zerop(l)) {
735 return make_indef(COMPLEX_INFINITY);
737 return make_indef(NOT_A_NUMBER);
741 r = ent_lift(r, BIGC_T, NULL);
742 return ent_binop(ASE_BINARY_OP_QUO, l, r);
746 static inline Lisp_Object
747 ent_inv_BIGG_T(Lisp_Object r)
749 if (ent_gaussian_zerop(r)) {
750 return make_indef(COMPLEX_INFINITY);
752 bigg_div(ent_scratch_bigg,
753 XBIGG_DATA(Qent_gaussian_one), XBIGG_DATA(r));
754 return make_bigg_bg(ent_scratch_bigg);
756 static inline Lisp_Object
757 ent_rem_BIGG_T(Lisp_Object l, Lisp_Object r)
759 if (ent_gaussian_zerop(r)) {
760 return make_bigg(0, 0);
762 bigg_mod(ent_scratch_bigg, XBIGG_DATA(l), XBIGG_DATA(r));
763 return make_bigg_bg(ent_scratch_bigg);
765 static inline Lisp_Object
766 ent_pow_BIGG_T_integer(Lisp_Object l, Lisp_Object r)
768 long unsigned int expo = 0UL;
772 } else if (BIGZP(r)) {
773 if (bigz_fits_ulong_p(XBIGZ_DATA(r)))
774 expo = bigz_to_ulong(XBIGZ_DATA(r));
776 Fsignal(Qarith_error, r);
778 Fsignal(Qdomain_error, r);
780 bigg_pow(ent_scratch_bigg, XBIGG_DATA(l), expo);
781 return make_bigg_bg(ent_scratch_bigg);
786 ent_eq_bigg(Lisp_Object l, Lisp_Object r)
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))));
793 ent_ne_bigg(Lisp_Object l, Lisp_Object r)
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))));
800 static inline Lisp_Object
801 ent_vallt_BIGG_T(Lisp_Object l, Lisp_Object r)
807 bigg_norm(ent_scratch_bigz, XBIGG_DATA(l));
808 bigg_norm(b2, XBIGG_DATA(r));
809 result = bigz_lt(ent_scratch_bigz, b2);
812 return (result) ? Qt : Qnil;
814 static inline Lisp_Object
815 ent_valgt_BIGG_T(Lisp_Object l, Lisp_Object r)
821 bigg_norm(ent_scratch_bigz, XBIGG_DATA(l));
822 bigg_norm(b2, XBIGG_DATA(r));
823 result = bigz_gt(ent_scratch_bigz, b2);
826 return (result) ? Qt : Qnil;
828 static inline Lisp_Object
829 ent_valeq_BIGG_T(Lisp_Object l, Lisp_Object r)
835 bigg_norm(ent_scratch_bigz, XBIGG_DATA(l));
836 bigg_norm(b2, XBIGG_DATA(r));
837 result = bigz_eql(ent_scratch_bigz, b2);
840 return (result) ? Qt : Qnil;
842 static inline Lisp_Object
843 ent_valne_BIGG_T(Lisp_Object l, Lisp_Object r)
849 bigg_norm(ent_scratch_bigz, XBIGG_DATA(l));
850 bigg_norm(b2, XBIGG_DATA(r));
851 result = bigz_eql(ent_scratch_bigz, b2);
854 return (result) ? Qnil : Qt;
860 ent_lift_all_BIGG_T(Lisp_Object number, ent_lift_args_t SXE_UNUSED(la))
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);
867 #if defined HAVE_MPC && defined WITH_MPC || \
868 defined HAVE_PSEUC && defined WITH_PSEUC
870 ent_lift_BIGC_T_BIGG_T(Lisp_Object number, ent_lift_args_t SXE_UNUSED(la))
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);
879 return make_bigg_bz(XBIGZ_DATA(re), XBIGZ_DATA(im));
885 ent_gaussian_nullary_optable_init(void)
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);
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);
897 ent_gaussian_unary_optable_init(void)
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);
904 ent_gaussian_binary_optable_init(void)
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
1125 ent_gaussian_unary_reltable_init(void)
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);
1133 ent_gaussian_binary_reltable_init(void)
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);
1142 ent_gaussian_lifttable_init(void)
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);
1149 #if defined HAVE_MPF && defined WITH_GMP
1150 ent_lift_register(BIGF_T, BIGG_T, ent_lift_all_BIGG_T);
1152 #if defined HAVE_MPFR && defined WITH_MPFR
1153 ent_lift_register(BIGFR_T, BIGG_T, ent_lift_all_BIGG_T);
1156 ent_lift_register(FLOAT_T, BIGG_T, ent_lift_all_BIGG_T);
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);
1164 void init_optables_BIGG_T(void)
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();
1174 void init_ent_gaussian(void)
1176 bigg_init(ent_scratch_bigg);
1179 void syms_of_ent_gaussian(void)
1181 INIT_LRECORD_IMPLEMENTATION(bigg);
1183 DEFSUBR(Fmake_bigg);
1186 void vars_of_ent_gaussian(void)
1188 Fprovide(intern("bigg"));
1189 Fprovide(intern("gaussian"));