00001
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "config.h"
00028
00029 #include "numeric.h"
00030 #include "ex.h"
00031 #include "operators.h"
00032 #include "archive.h"
00033 #include "tostring.h"
00034 #include "utils.h"
00035
00036 #include <limits>
00037 #include <sstream>
00038 #include <stdexcept>
00039 #include <string>
00040 #include <vector>
00041
00042
00043
00044
00045
00046
00047
00048 #include <cln/output.h>
00049 #include <cln/integer_io.h>
00050 #include <cln/integer_ring.h>
00051 #include <cln/rational_io.h>
00052 #include <cln/rational_ring.h>
00053 #include <cln/lfloat_class.h>
00054 #include <cln/lfloat_io.h>
00055 #include <cln/real_io.h>
00056 #include <cln/real_ring.h>
00057 #include <cln/complex_io.h>
00058 #include <cln/complex_ring.h>
00059 #include <cln/numtheory.h>
00060
00061 namespace GiNaC {
00062
00063 GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(numeric, basic,
00064 print_func<print_context>(&numeric::do_print).
00065 print_func<print_latex>(&numeric::do_print_latex).
00066 print_func<print_csrc>(&numeric::do_print_csrc).
00067 print_func<print_csrc_cl_N>(&numeric::do_print_csrc_cl_N).
00068 print_func<print_tree>(&numeric::do_print_tree).
00069 print_func<print_python_repr>(&numeric::do_print_python_repr))
00070
00071
00072
00074
00076 numeric::numeric()
00077 {
00078 value = cln::cl_I(0);
00079 setflag(status_flags::evaluated | status_flags::expanded);
00080 }
00081
00083
00085
00086
00087
00088 numeric::numeric(int i)
00089 {
00090
00091
00092
00093
00094
00095
00096
00097 #if cl_value_len >= 32
00098 value = cln::cl_I(i);
00099 #else
00100 if (i < (1L << (cl_value_len-1)) && i >= -(1L << (cl_value_len-1)))
00101 value = cln::cl_I(i);
00102 else
00103 value = cln::cl_I(static_cast<long>(i));
00104 #endif
00105 setflag(status_flags::evaluated | status_flags::expanded);
00106 }
00107
00108
00109 numeric::numeric(unsigned int i)
00110 {
00111
00112
00113
00114
00115
00116
00117
00118 #if cl_value_len >= 32
00119 value = cln::cl_I(i);
00120 #else
00121 if (i < (1UL << (cl_value_len-1)))
00122 value = cln::cl_I(i);
00123 else
00124 value = cln::cl_I(static_cast<unsigned long>(i));
00125 #endif
00126 setflag(status_flags::evaluated | status_flags::expanded);
00127 }
00128
00129
00130 numeric::numeric(long i)
00131 {
00132 value = cln::cl_I(i);
00133 setflag(status_flags::evaluated | status_flags::expanded);
00134 }
00135
00136
00137 numeric::numeric(unsigned long i)
00138 {
00139 value = cln::cl_I(i);
00140 setflag(status_flags::evaluated | status_flags::expanded);
00141 }
00142
00143
00147 numeric::numeric(long numer, long denom)
00148 {
00149 if (!denom)
00150 throw std::overflow_error("division by zero");
00151 value = cln::cl_I(numer) / cln::cl_I(denom);
00152 setflag(status_flags::evaluated | status_flags::expanded);
00153 }
00154
00155
00156 numeric::numeric(double d)
00157 {
00158
00159
00160
00161 value = cln::cl_float(d, cln::default_float_format);
00162 setflag(status_flags::evaluated | status_flags::expanded);
00163 }
00164
00165
00168 numeric::numeric(const char *s)
00169 {
00170 cln::cl_N ctorval = 0;
00171
00172
00173
00174 std::string ss = s;
00175 std::string::size_type delim;
00176
00177
00178 if (ss.at(0) != '+' && ss.at(0) != '-' && ss.at(0) != '#')
00179 ss = '+' + ss;
00180
00181
00182
00183 while ((delim = ss.find("e"))!=std::string::npos)
00184 ss.replace(delim,1,"E");
00185
00186
00187 do {
00188
00189 std::string term;
00190 bool imaginary = false;
00191 delim = ss.find_first_of(std::string("+-"),1);
00192
00193 if (delim!=std::string::npos && ss.at(delim-1)=='E')
00194 delim = ss.find_first_of(std::string("+-"),delim+1);
00195 term = ss.substr(0,delim);
00196 if (delim!=std::string::npos)
00197 ss = ss.substr(delim);
00198
00199 if (term.find("I")!=std::string::npos) {
00200
00201 term.erase(term.find("I"),1);
00202
00203 if (term.find("*")!=std::string::npos)
00204 term.erase(term.find("*"),1);
00205
00206 if (term.size()==1)
00207 term += '1';
00208 imaginary = true;
00209 }
00210 if (term.find('.')!=std::string::npos || term.find('E')!=std::string::npos) {
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 if (term.find("E")==std::string::npos)
00222 term += "E0";
00223
00224 term = term.replace(term.find("E"),1,"e");
00225
00226 term += "_" + ToString((unsigned)Digits);
00227
00228 if (imaginary)
00229 ctorval = ctorval + cln::complex(cln::cl_I(0),cln::cl_F(term.c_str()));
00230 else
00231 ctorval = ctorval + cln::cl_F(term.c_str());
00232 } else {
00233
00234 if (imaginary)
00235 ctorval = ctorval + cln::complex(cln::cl_I(0),cln::cl_R(term.c_str()));
00236 else
00237 ctorval = ctorval + cln::cl_R(term.c_str());
00238 }
00239 } while (delim != std::string::npos);
00240 value = ctorval;
00241 setflag(status_flags::evaluated | status_flags::expanded);
00242 }
00243
00244
00247 numeric::numeric(const cln::cl_N &z)
00248 {
00249 value = z;
00250 setflag(status_flags::evaluated | status_flags::expanded);
00251 }
00252
00253
00255
00257
00261 static const cln::cl_F make_real_float(const cln::cl_idecoded_float& dec)
00262 {
00263 cln::cl_F x = cln::cl_float(dec.mantissa, cln::default_float_format);
00264 x = cln::scale_float(x, dec.exponent);
00265 cln::cl_F sign = cln::cl_float(dec.sign, cln::default_float_format);
00266 x = cln::float_sign(sign, x);
00267 return x;
00268 }
00269
00273 static const cln::cl_F read_real_float(std::istream& s)
00274 {
00275 cln::cl_idecoded_float dec;
00276 s >> dec.sign >> dec.mantissa >> dec.exponent;
00277 const cln::cl_F x = make_real_float(dec);
00278 return x;
00279 }
00280
00281 void numeric::read_archive(const archive_node &n, lst &sym_lst)
00282 {
00283 inherited::read_archive(n, sym_lst);
00284 value = 0;
00285
00286
00287 std::string str;
00288 if (n.find_string("number", str)) {
00289 std::istringstream s(str);
00290 cln::cl_R re, im;
00291 char c;
00292 s.get(c);
00293 switch (c) {
00294 case 'R':
00295
00296 re = read_real_float(s);
00297 value = re;
00298 break;
00299 case 'C':
00300
00301 re = read_real_float(s);
00302 im = read_real_float(s);
00303 value = cln::complex(re, im);
00304 break;
00305 case 'H':
00306
00307
00308 s >> re;
00309 im = read_real_float(s);
00310 value = cln::complex(re, im);
00311 break;
00312 case 'J':
00313
00314
00315 re = read_real_float(s);
00316 s >> im;
00317 value = cln::complex(re, im);
00318 break;
00319 default:
00320
00321 s.putback(c);
00322 s >> value;
00323 break;
00324 }
00325 }
00326 setflag(status_flags::evaluated | status_flags::expanded);
00327 }
00328 GINAC_BIND_UNARCHIVER(numeric);
00329
00330 static void write_real_float(std::ostream& s, const cln::cl_R& n)
00331 {
00332 const cln::cl_idecoded_float dec = cln::integer_decode_float(cln::the<cln::cl_F>(n));
00333 s << dec.sign << ' ' << dec.mantissa << ' ' << dec.exponent;
00334 }
00335
00336 void numeric::archive(archive_node &n) const
00337 {
00338 inherited::archive(n);
00339
00340
00341
00342 const cln::cl_R re = cln::realpart(value);
00343 const cln::cl_R im = cln::imagpart(value);
00344 const bool re_rationalp = cln::instanceof(re, cln::cl_RA_ring);
00345 const bool im_rationalp = cln::instanceof(im, cln::cl_RA_ring);
00346
00347
00348
00349 std::ostringstream s;
00350 if (re_rationalp && im_rationalp)
00351 s << value;
00352 else if (zerop(im)) {
00353
00354 s << 'R';
00355 write_real_float(s, re);
00356 } else if (re_rationalp) {
00357 s << 'H';
00358
00359
00360 s << re << ' ';
00361 write_real_float(s, im);
00362 } else if (im_rationalp) {
00363 s << 'J';
00364
00365
00366 write_real_float(s, re);
00367 s << ' ' << im;
00368 } else {
00369
00370 s << 'C';
00371 write_real_float(s, re);
00372 s << ' ';
00373 write_real_float(s, im);
00374 }
00375 n.add_string("number", s.str());
00376 }
00377
00379
00381
00389 static void print_real_number(const print_context & c, const cln::cl_R & x)
00390 {
00391 cln::cl_print_flags ourflags;
00392 if (cln::instanceof(x, cln::cl_RA_ring)) {
00393
00394 if (cln::instanceof(x, cln::cl_I_ring) ||
00395 !is_a<print_latex>(c)) {
00396 cln::print_real(c.s, ourflags, x);
00397 } else {
00398 if (x < 0)
00399 c.s << "-";
00400 c.s << "\\frac{";
00401 cln::print_real(c.s, ourflags, cln::abs(cln::numerator(cln::the<cln::cl_RA>(x))));
00402 c.s << "}{";
00403 cln::print_real(c.s, ourflags, cln::denominator(cln::the<cln::cl_RA>(x)));
00404 c.s << '}';
00405 }
00406 } else {
00407
00408
00409
00410 ourflags.default_float_format = cln::float_format(cln::the<cln::cl_F>(x));
00411 cln::print_real(c.s, ourflags, x);
00412 }
00413 }
00414
00418 static void print_integer_csrc(const print_context & c, const cln::cl_I & x)
00419 {
00420
00421
00422 const int max_cln_int = 536870911;
00423 if (x >= cln::cl_I(-max_cln_int) && x <= cln::cl_I(max_cln_int))
00424 c.s << cln::cl_I_to_int(x) << ".0";
00425 else
00426 c.s << cln::double_approx(x);
00427 }
00428
00432 static void print_real_csrc(const print_context & c, const cln::cl_R & x)
00433 {
00434 if (cln::instanceof(x, cln::cl_I_ring)) {
00435
00436
00437 print_integer_csrc(c, cln::the<cln::cl_I>(x));
00438
00439 } else if (cln::instanceof(x, cln::cl_RA_ring)) {
00440
00441
00442 const cln::cl_I numer = cln::numerator(cln::the<cln::cl_RA>(x));
00443 const cln::cl_I denom = cln::denominator(cln::the<cln::cl_RA>(x));
00444 if (cln::plusp(x) > 0) {
00445 c.s << "(";
00446 print_integer_csrc(c, numer);
00447 } else {
00448 c.s << "-(";
00449 print_integer_csrc(c, -numer);
00450 }
00451 c.s << "/";
00452 print_integer_csrc(c, denom);
00453 c.s << ")";
00454
00455 } else {
00456
00457
00458 c.s << cln::double_approx(x);
00459 }
00460 }
00461
00462 template<typename T1, typename T2>
00463 static inline bool coerce(T1& dst, const T2& arg);
00464
00470 template<>
00471 inline bool coerce<int, cln::cl_I>(int& dst, const cln::cl_I& arg)
00472 {
00473 static const cln::cl_I cl_max_int =
00474 (cln::cl_I)(long)(std::numeric_limits<int>::max());
00475 static const cln::cl_I cl_min_int =
00476 (cln::cl_I)(long)(std::numeric_limits<int>::min());
00477 if ((arg >= cl_min_int) && (arg <= cl_max_int)) {
00478 dst = cl_I_to_int(arg);
00479 return true;
00480 }
00481 return false;
00482 }
00483
00484 template<>
00485 inline bool coerce<unsigned int, cln::cl_I>(unsigned int& dst, const cln::cl_I& arg)
00486 {
00487 static const cln::cl_I cl_max_uint =
00488 (cln::cl_I)(unsigned long)(std::numeric_limits<unsigned int>::max());
00489 if ((! minusp(arg)) && (arg <= cl_max_uint)) {
00490 dst = cl_I_to_uint(arg);
00491 return true;
00492 }
00493 return false;
00494 }
00495
00499 static void print_real_cl_N(const print_context & c, const cln::cl_R & x)
00500 {
00501 if (cln::instanceof(x, cln::cl_I_ring)) {
00502
00503 int dst;
00504
00505 if (coerce(dst, cln::the<cln::cl_I>(x))) {
00506
00507 if (dst < 0)
00508 c.s << "(-" << dst << ")";
00509 else
00510 c.s << dst;
00511 } else {
00512
00513 c.s << "cln::cl_I(\"";
00514 print_real_number(c, x);
00515 c.s << "\")";
00516 }
00517 } else if (cln::instanceof(x, cln::cl_RA_ring)) {
00518
00519
00520 cln::cl_print_flags ourflags;
00521 c.s << "cln::cl_RA(\"";
00522 cln::print_rational(c.s, ourflags, cln::the<cln::cl_RA>(x));
00523 c.s << "\")";
00524
00525 } else {
00526
00527
00528 c.s << "cln::cl_F(\"";
00529 print_real_number(c, cln::cl_float(1.0, cln::default_float_format) * x);
00530 c.s << "_" << Digits << "\")";
00531 }
00532 }
00533
00534 void numeric::print_numeric(const print_context & c, const char *par_open, const char *par_close, const char *imag_sym, const char *mul_sym, unsigned level) const
00535 {
00536 const cln::cl_R r = cln::realpart(value);
00537 const cln::cl_R i = cln::imagpart(value);
00538
00539 if (cln::zerop(i)) {
00540
00541
00542 if ((precedence() <= level) && (!this->is_nonneg_integer())) {
00543 c.s << par_open;
00544 print_real_number(c, r);
00545 c.s << par_close;
00546 } else {
00547 print_real_number(c, r);
00548 }
00549
00550 } else {
00551 if (cln::zerop(r)) {
00552
00553
00554 if (i == 1)
00555 c.s << imag_sym;
00556 else {
00557 if (precedence()<=level)
00558 c.s << par_open;
00559 if (i == -1)
00560 c.s << "-" << imag_sym;
00561 else {
00562 print_real_number(c, i);
00563 c.s << mul_sym << imag_sym;
00564 }
00565 if (precedence()<=level)
00566 c.s << par_close;
00567 }
00568
00569 } else {
00570
00571
00572 if (precedence() <= level)
00573 c.s << par_open;
00574 print_real_number(c, r);
00575 if (i < 0) {
00576 if (i == -1) {
00577 c.s << "-" << imag_sym;
00578 } else {
00579 print_real_number(c, i);
00580 c.s << mul_sym << imag_sym;
00581 }
00582 } else {
00583 if (i == 1) {
00584 c.s << "+" << imag_sym;
00585 } else {
00586 c.s << "+";
00587 print_real_number(c, i);
00588 c.s << mul_sym << imag_sym;
00589 }
00590 }
00591 if (precedence() <= level)
00592 c.s << par_close;
00593 }
00594 }
00595 }
00596
00597 void numeric::do_print(const print_context & c, unsigned level) const
00598 {
00599 print_numeric(c, "(", ")", "I", "*", level);
00600 }
00601
00602 void numeric::do_print_latex(const print_latex & c, unsigned level) const
00603 {
00604 print_numeric(c, "{(", ")}", "i", " ", level);
00605 }
00606
00607 void numeric::do_print_csrc(const print_csrc & c, unsigned level) const
00608 {
00609 std::ios::fmtflags oldflags = c.s.flags();
00610 c.s.setf(std::ios::scientific);
00611 int oldprec = c.s.precision();
00612
00613
00614 if (is_a<print_csrc_double>(c))
00615 c.s.precision(std::numeric_limits<double>::digits10 + 1);
00616 else
00617 c.s.precision(std::numeric_limits<float>::digits10 + 1);
00618
00619 if (this->is_real()) {
00620
00621
00622 print_real_csrc(c, cln::the<cln::cl_R>(value));
00623
00624 } else {
00625
00626
00627 c.s << "std::complex<";
00628 if (is_a<print_csrc_double>(c))
00629 c.s << "double>(";
00630 else
00631 c.s << "float>(";
00632
00633 print_real_csrc(c, cln::realpart(value));
00634 c.s << ",";
00635 print_real_csrc(c, cln::imagpart(value));
00636 c.s << ")";
00637 }
00638
00639 c.s.flags(oldflags);
00640 c.s.precision(oldprec);
00641 }
00642
00643 void numeric::do_print_csrc_cl_N(const print_csrc_cl_N & c, unsigned level) const
00644 {
00645 if (this->is_real()) {
00646
00647
00648 print_real_cl_N(c, cln::the<cln::cl_R>(value));
00649
00650 } else {
00651
00652
00653 c.s << "cln::complex(";
00654 print_real_cl_N(c, cln::realpart(value));
00655 c.s << ",";
00656 print_real_cl_N(c, cln::imagpart(value));
00657 c.s << ")";
00658 }
00659 }
00660
00661 void numeric::do_print_tree(const print_tree & c, unsigned level) const
00662 {
00663 c.s << std::string(level, ' ') << value
00664 << " (" << class_name() << ")" << " @" << this
00665 << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
00666 << std::endl;
00667 }
00668
00669 void numeric::do_print_python_repr(const print_python_repr & c, unsigned level) const
00670 {
00671 c.s << class_name() << "('";
00672 print_numeric(c, "(", ")", "I", "*", level);
00673 c.s << "')";
00674 }
00675
00676 bool numeric::info(unsigned inf) const
00677 {
00678 switch (inf) {
00679 case info_flags::numeric:
00680 case info_flags::polynomial:
00681 case info_flags::rational_function:
00682 case info_flags::expanded:
00683 return true;
00684 case info_flags::real:
00685 return is_real();
00686 case info_flags::rational:
00687 case info_flags::rational_polynomial:
00688 return is_rational();
00689 case info_flags::crational:
00690 case info_flags::crational_polynomial:
00691 return is_crational();
00692 case info_flags::integer:
00693 case info_flags::integer_polynomial:
00694 return is_integer();
00695 case info_flags::cinteger:
00696 case info_flags::cinteger_polynomial:
00697 return is_cinteger();
00698 case info_flags::positive:
00699 return is_positive();
00700 case info_flags::negative:
00701 return is_negative();
00702 case info_flags::nonnegative:
00703 return !is_negative();
00704 case info_flags::posint:
00705 return is_pos_integer();
00706 case info_flags::negint:
00707 return is_integer() && is_negative();
00708 case info_flags::nonnegint:
00709 return is_nonneg_integer();
00710 case info_flags::even:
00711 return is_even();
00712 case info_flags::odd:
00713 return is_odd();
00714 case info_flags::prime:
00715 return is_prime();
00716 case info_flags::algebraic:
00717 return !is_real();
00718 }
00719 return false;
00720 }
00721
00722 bool numeric::is_polynomial(const ex & var) const
00723 {
00724 return true;
00725 }
00726
00727 int numeric::degree(const ex & s) const
00728 {
00729 return 0;
00730 }
00731
00732 int numeric::ldegree(const ex & s) const
00733 {
00734 return 0;
00735 }
00736
00737 ex numeric::coeff(const ex & s, int n) const
00738 {
00739 return n==0 ? *this : _ex0;
00740 }
00741
00748 bool numeric::has(const ex &other, unsigned options) const
00749 {
00750 if (!is_exactly_a<numeric>(other))
00751 return false;
00752 const numeric &o = ex_to<numeric>(other);
00753 if (this->is_equal(o) || this->is_equal(-o))
00754 return true;
00755 if (o.imag().is_zero()) {
00756 if (!this->real().is_equal(*_num0_p))
00757 if (this->real().is_equal(o) || this->real().is_equal(-o))
00758 return true;
00759 if (!this->imag().is_equal(*_num0_p))
00760 if (this->imag().is_equal(o) || this->imag().is_equal(-o))
00761 return true;
00762 return false;
00763 }
00764 else {
00765 if (o.is_equal(I))
00766 return !this->is_real();
00767 if (o.real().is_zero())
00768 if (!this->imag().is_equal(*_num0_p))
00769 if (this->imag().is_equal(o*I) || this->imag().is_equal(-o*I))
00770 return true;
00771 }
00772 return false;
00773 }
00774
00775
00777 ex numeric::eval(int level) const
00778 {
00779
00780
00781 return this->hold();
00782 }
00783
00784
00792 ex numeric::evalf(int level) const
00793 {
00794
00795 return numeric(cln::cl_float(1.0, cln::default_float_format) * value);
00796 }
00797
00798 ex numeric::conjugate() const
00799 {
00800 if (is_real()) {
00801 return *this;
00802 }
00803 return numeric(cln::conjugate(this->value));
00804 }
00805
00806 ex numeric::real_part() const
00807 {
00808 return numeric(cln::realpart(value));
00809 }
00810
00811 ex numeric::imag_part() const
00812 {
00813 return numeric(cln::imagpart(value));
00814 }
00815
00816
00817
00818 int numeric::compare_same_type(const basic &other) const
00819 {
00820 GINAC_ASSERT(is_exactly_a<numeric>(other));
00821 const numeric &o = static_cast<const numeric &>(other);
00822
00823 return this->compare(o);
00824 }
00825
00826
00827 bool numeric::is_equal_same_type(const basic &other) const
00828 {
00829 GINAC_ASSERT(is_exactly_a<numeric>(other));
00830 const numeric &o = static_cast<const numeric &>(other);
00831
00832 return this->is_equal(o);
00833 }
00834
00835
00836 unsigned numeric::calchash() const
00837 {
00838
00839
00840
00841
00842 setflag(status_flags::hash_calculated);
00843 hashvalue = golden_ratio_hash(cln::equal_hashcode(value));
00844 return hashvalue;
00845 }
00846
00847
00849
00851
00852
00853
00855
00857
00858
00859
00862 const numeric numeric::add(const numeric &other) const
00863 {
00864 return numeric(value + other.value);
00865 }
00866
00867
00870 const numeric numeric::sub(const numeric &other) const
00871 {
00872 return numeric(value - other.value);
00873 }
00874
00875
00878 const numeric numeric::mul(const numeric &other) const
00879 {
00880 return numeric(value * other.value);
00881 }
00882
00883
00888 const numeric numeric::div(const numeric &other) const
00889 {
00890 if (cln::zerop(other.value))
00891 throw std::overflow_error("numeric::div(): division by zero");
00892 return numeric(value / other.value);
00893 }
00894
00895
00898 const numeric numeric::power(const numeric &other) const
00899 {
00900
00901
00902 if (&other==_num1_p || cln::equal(other.value,_num1_p->value))
00903 return *this;
00904
00905 if (cln::zerop(value)) {
00906 if (cln::zerop(other.value))
00907 throw std::domain_error("numeric::eval(): pow(0,0) is undefined");
00908 else if (cln::zerop(cln::realpart(other.value)))
00909 throw std::domain_error("numeric::eval(): pow(0,I) is undefined");
00910 else if (cln::minusp(cln::realpart(other.value)))
00911 throw std::overflow_error("numeric::eval(): division by zero");
00912 else
00913 return *_num0_p;
00914 }
00915 return numeric(cln::expt(value, other.value));
00916 }
00917
00918
00919
00923 const numeric &numeric::add_dyn(const numeric &other) const
00924 {
00925
00926
00927 if (this==_num0_p)
00928 return other;
00929 else if (&other==_num0_p)
00930 return *this;
00931
00932 return static_cast<const numeric &>((new numeric(value + other.value))->
00933 setflag(status_flags::dynallocated));
00934 }
00935
00936
00941 const numeric &numeric::sub_dyn(const numeric &other) const
00942 {
00943
00944
00945 if (&other==_num0_p || cln::zerop(other.value))
00946 return *this;
00947
00948 return static_cast<const numeric &>((new numeric(value - other.value))->
00949 setflag(status_flags::dynallocated));
00950 }
00951
00952
00957 const numeric &numeric::mul_dyn(const numeric &other) const
00958 {
00959
00960
00961 if (this==_num1_p)
00962 return other;
00963 else if (&other==_num1_p)
00964 return *this;
00965
00966 return static_cast<const numeric &>((new numeric(value * other.value))->
00967 setflag(status_flags::dynallocated));
00968 }
00969
00970
00977 const numeric &numeric::div_dyn(const numeric &other) const
00978 {
00979
00980
00981 if (&other==_num1_p)
00982 return *this;
00983 if (cln::zerop(cln::the<cln::cl_N>(other.value)))
00984 throw std::overflow_error("division by zero");
00985 return static_cast<const numeric &>((new numeric(value / other.value))->
00986 setflag(status_flags::dynallocated));
00987 }
00988
00989
00994 const numeric &numeric::power_dyn(const numeric &other) const
00995 {
00996
00997
00998
00999 if (&other==_num1_p || cln::equal(other.value, _num1_p->value))
01000 return *this;
01001
01002 if (cln::zerop(value)) {
01003 if (cln::zerop(other.value))
01004 throw std::domain_error("numeric::eval(): pow(0,0) is undefined");
01005 else if (cln::zerop(cln::realpart(other.value)))
01006 throw std::domain_error("numeric::eval(): pow(0,I) is undefined");
01007 else if (cln::minusp(cln::realpart(other.value)))
01008 throw std::overflow_error("numeric::eval(): division by zero");
01009 else
01010 return *_num0_p;
01011 }
01012 return static_cast<const numeric &>((new numeric(cln::expt(value, other.value)))->
01013 setflag(status_flags::dynallocated));
01014 }
01015
01016
01017 const numeric &numeric::operator=(int i)
01018 {
01019 return operator=(numeric(i));
01020 }
01021
01022
01023 const numeric &numeric::operator=(unsigned int i)
01024 {
01025 return operator=(numeric(i));
01026 }
01027
01028
01029 const numeric &numeric::operator=(long i)
01030 {
01031 return operator=(numeric(i));
01032 }
01033
01034
01035 const numeric &numeric::operator=(unsigned long i)
01036 {
01037 return operator=(numeric(i));
01038 }
01039
01040
01041 const numeric &numeric::operator=(double d)
01042 {
01043 return operator=(numeric(d));
01044 }
01045
01046
01047 const numeric &numeric::operator=(const char * s)
01048 {
01049 return operator=(numeric(s));
01050 }
01051
01052
01054 const numeric numeric::inverse() const
01055 {
01056 if (cln::zerop(value))
01057 throw std::overflow_error("numeric::inverse(): division by zero");
01058 return numeric(cln::recip(value));
01059 }
01060
01065 numeric numeric::step() const
01066 { cln::cl_R r = cln::realpart(value);
01067 if(cln::zerop(r))
01068 return numeric(1,2);
01069 if(cln::plusp(r))
01070 return 1;
01071 return 0;
01072 }
01073
01079 int numeric::csgn() const
01080 {
01081 if (cln::zerop(value))
01082 return 0;
01083 cln::cl_R r = cln::realpart(value);
01084 if (!cln::zerop(r)) {
01085 if (cln::plusp(r))
01086 return 1;
01087 else
01088 return -1;
01089 } else {
01090 if (cln::plusp(cln::imagpart(value)))
01091 return 1;
01092 else
01093 return -1;
01094 }
01095 }
01096
01097
01105 int numeric::compare(const numeric &other) const
01106 {
01107
01108 if (cln::instanceof(value, cln::cl_R_ring) &&
01109 cln::instanceof(other.value, cln::cl_R_ring))
01110
01111 return cln::compare(cln::the<cln::cl_R>(value), cln::the<cln::cl_R>(other.value));
01112 else {
01113
01114 cl_signean real_cmp = cln::compare(cln::realpart(value), cln::realpart(other.value));
01115 if (real_cmp)
01116 return real_cmp;
01117
01118 return cln::compare(cln::imagpart(value), cln::imagpart(other.value));
01119 }
01120 }
01121
01122
01123 bool numeric::is_equal(const numeric &other) const
01124 {
01125 return cln::equal(value, other.value);
01126 }
01127
01128
01130 bool numeric::is_zero() const
01131 {
01132 return cln::zerop(value);
01133 }
01134
01135
01137 bool numeric::is_positive() const
01138 {
01139 if (cln::instanceof(value, cln::cl_R_ring))
01140 return cln::plusp(cln::the<cln::cl_R>(value));
01141 return false;
01142 }
01143
01144
01146 bool numeric::is_negative() const
01147 {
01148 if (cln::instanceof(value, cln::cl_R_ring))
01149 return cln::minusp(cln::the<cln::cl_R>(value));
01150 return false;
01151 }
01152
01153
01155 bool numeric::is_integer() const
01156 {
01157 return cln::instanceof(value, cln::cl_I_ring);
01158 }
01159
01160
01162 bool numeric::is_pos_integer() const
01163 {
01164 return (cln::instanceof(value, cln::cl_I_ring) && cln::plusp(cln::the<cln::cl_I>(value)));
01165 }
01166
01167
01169 bool numeric::is_nonneg_integer() const
01170 {
01171 return (cln::instanceof(value, cln::cl_I_ring) && !cln::minusp(cln::the<cln::cl_I>(value)));
01172 }
01173
01174
01176 bool numeric::is_even() const
01177 {
01178 return (cln::instanceof(value, cln::cl_I_ring) && cln::evenp(cln::the<cln::cl_I>(value)));
01179 }
01180
01181
01183 bool numeric::is_odd() const
01184 {
01185 return (cln::instanceof(value, cln::cl_I_ring) && cln::oddp(cln::the<cln::cl_I>(value)));
01186 }
01187
01188
01192 bool numeric::is_prime() const
01193 {
01194 return (cln::instanceof(value, cln::cl_I_ring)
01195 && cln::plusp(cln::the<cln::cl_I>(value))
01196 && cln::isprobprime(cln::the<cln::cl_I>(value)));
01197 }
01198
01199
01202 bool numeric::is_rational() const
01203 {
01204 return cln::instanceof(value, cln::cl_RA_ring);
01205 }
01206
01207
01209 bool numeric::is_real() const
01210 {
01211 return cln::instanceof(value, cln::cl_R_ring);
01212 }
01213
01214
01215 bool numeric::operator==(const numeric &other) const
01216 {
01217 return cln::equal(value, other.value);
01218 }
01219
01220
01221 bool numeric::operator!=(const numeric &other) const
01222 {
01223 return !cln::equal(value, other.value);
01224 }
01225
01226
01229 bool numeric::is_cinteger() const
01230 {
01231 if (cln::instanceof(value, cln::cl_I_ring))
01232 return true;
01233 else if (!this->is_real()) {
01234 if (cln::instanceof(cln::realpart(value), cln::cl_I_ring) &&
01235 cln::instanceof(cln::imagpart(value), cln::cl_I_ring))
01236 return true;
01237 }
01238 return false;
01239 }
01240
01241
01244 bool numeric::is_crational() const
01245 {
01246 if (cln::instanceof(value, cln::cl_RA_ring))
01247 return true;
01248 else if (!this->is_real()) {
01249 if (cln::instanceof(cln::realpart(value), cln::cl_RA_ring) &&
01250 cln::instanceof(cln::imagpart(value), cln::cl_RA_ring))
01251 return true;
01252 }
01253 return false;
01254 }
01255
01256
01260 bool numeric::operator<(const numeric &other) const
01261 {
01262 if (this->is_real() && other.is_real())
01263 return (cln::the<cln::cl_R>(value) < cln::the<cln::cl_R>(other.value));
01264 throw std::invalid_argument("numeric::operator<(): complex inequality");
01265 }
01266
01267
01271 bool numeric::operator<=(const numeric &other) const
01272 {
01273 if (this->is_real() && other.is_real())
01274 return (cln::the<cln::cl_R>(value) <= cln::the<cln::cl_R>(other.value));
01275 throw std::invalid_argument("numeric::operator<=(): complex inequality");
01276 }
01277
01278
01282 bool numeric::operator>(const numeric &other) const
01283 {
01284 if (this->is_real() && other.is_real())
01285 return (cln::the<cln::cl_R>(value) > cln::the<cln::cl_R>(other.value));
01286 throw std::invalid_argument("numeric::operator>(): complex inequality");
01287 }
01288
01289
01293 bool numeric::operator>=(const numeric &other) const
01294 {
01295 if (this->is_real() && other.is_real())
01296 return (cln::the<cln::cl_R>(value) >= cln::the<cln::cl_R>(other.value));
01297 throw std::invalid_argument("numeric::operator>=(): complex inequality");
01298 }
01299
01300
01304 int numeric::to_int() const
01305 {
01306 GINAC_ASSERT(this->is_integer());
01307 return cln::cl_I_to_int(cln::the<cln::cl_I>(value));
01308 }
01309
01310
01314 long numeric::to_long() const
01315 {
01316 GINAC_ASSERT(this->is_integer());
01317 return cln::cl_I_to_long(cln::the<cln::cl_I>(value));
01318 }
01319
01320
01323 double numeric::to_double() const
01324 {
01325 GINAC_ASSERT(this->is_real());
01326 return cln::double_approx(cln::realpart(value));
01327 }
01328
01329
01333 cln::cl_N numeric::to_cl_N() const
01334 {
01335 return value;
01336 }
01337
01338
01340 const numeric numeric::real() const
01341 {
01342 return numeric(cln::realpart(value));
01343 }
01344
01345
01347 const numeric numeric::imag() const
01348 {
01349 return numeric(cln::imagpart(value));
01350 }
01351
01352
01357 const numeric numeric::numer() const
01358 {
01359 if (cln::instanceof(value, cln::cl_I_ring))
01360 return numeric(*this);
01361
01362 else if (cln::instanceof(value, cln::cl_RA_ring))
01363 return numeric(cln::numerator(cln::the<cln::cl_RA>(value)));
01364
01365 else if (!this->is_real()) {
01366 const cln::cl_RA r = cln::the<cln::cl_RA>(cln::realpart(value));
01367 const cln::cl_RA i = cln::the<cln::cl_RA>(cln::imagpart(value));
01368 if (cln::instanceof(r, cln::cl_I_ring) && cln::instanceof(i, cln::cl_I_ring))
01369 return numeric(*this);
01370 if (cln::instanceof(r, cln::cl_I_ring) && cln::instanceof(i, cln::cl_RA_ring))
01371 return numeric(cln::complex(r*cln::denominator(i), cln::numerator(i)));
01372 if (cln::instanceof(r, cln::cl_RA_ring) && cln::instanceof(i, cln::cl_I_ring))
01373 return numeric(cln::complex(cln::numerator(r), i*cln::denominator(r)));
01374 if (cln::instanceof(r, cln::cl_RA_ring) && cln::instanceof(i, cln::cl_RA_ring)) {
01375 const cln::cl_I s = cln::lcm(cln::denominator(r), cln::denominator(i));
01376 return numeric(cln::complex(cln::numerator(r)*(cln::exquo(s,cln::denominator(r))),
01377 cln::numerator(i)*(cln::exquo(s,cln::denominator(i)))));
01378 }
01379 }
01380
01381 return numeric(*this);
01382 }
01383
01384
01388 const numeric numeric::denom() const
01389 {
01390 if (cln::instanceof(value, cln::cl_I_ring))
01391 return *_num1_p;
01392
01393 if (cln::instanceof(value, cln::cl_RA_ring))
01394 return numeric(cln::denominator(cln::the<cln::cl_RA>(value)));
01395
01396 if (!this->is_real()) {
01397 const cln::cl_RA r = cln::the<cln::cl_RA>(cln::realpart(value));
01398 const cln::cl_RA i = cln::the<cln::cl_RA>(cln::imagpart(value));
01399 if (cln::instanceof(r, cln::cl_I_ring) && cln::instanceof(i, cln::cl_I_ring))
01400 return *_num1_p;
01401 if (cln::instanceof(r, cln::cl_I_ring) && cln::instanceof(i, cln::cl_RA_ring))
01402 return numeric(cln::denominator(i));
01403 if (cln::instanceof(r, cln::cl_RA_ring) && cln::instanceof(i, cln::cl_I_ring))
01404 return numeric(cln::denominator(r));
01405 if (cln::instanceof(r, cln::cl_RA_ring) && cln::instanceof(i, cln::cl_RA_ring))
01406 return numeric(cln::lcm(cln::denominator(r), cln::denominator(i)));
01407 }
01408
01409 return *_num1_p;
01410 }
01411
01412
01419 int numeric::int_length() const
01420 {
01421 if (cln::instanceof(value, cln::cl_I_ring))
01422 return cln::integer_length(cln::the<cln::cl_I>(value));
01423 else
01424 return 0;
01425 }
01426
01428
01430
01434 const numeric I = numeric(cln::complex(cln::cl_I(0),cln::cl_I(1)));
01435
01436
01440 const numeric exp(const numeric &x)
01441 {
01442 return numeric(cln::exp(x.to_cl_N()));
01443 }
01444
01445
01451 const numeric log(const numeric &x)
01452 {
01453 if (x.is_zero())
01454 throw pole_error("log(): logarithmic pole",0);
01455 return numeric(cln::log(x.to_cl_N()));
01456 }
01457
01458
01462 const numeric sin(const numeric &x)
01463 {
01464 return numeric(cln::sin(x.to_cl_N()));
01465 }
01466
01467
01471 const numeric cos(const numeric &x)
01472 {
01473 return numeric(cln::cos(x.to_cl_N()));
01474 }
01475
01476
01480 const numeric tan(const numeric &x)
01481 {
01482 return numeric(cln::tan(x.to_cl_N()));
01483 }
01484
01485
01489 const numeric asin(const numeric &x)
01490 {
01491 return numeric(cln::asin(x.to_cl_N()));
01492 }
01493
01494
01498 const numeric acos(const numeric &x)
01499 {
01500 return numeric(cln::acos(x.to_cl_N()));
01501 }
01502
01503
01509 const numeric atan(const numeric &x)
01510 {
01511 if (!x.is_real() &&
01512 x.real().is_zero() &&
01513 abs(x.imag()).is_equal(*_num1_p))
01514 throw pole_error("atan(): logarithmic pole",0);
01515 return numeric(cln::atan(x.to_cl_N()));
01516 }
01517
01518
01526 const numeric atan(const numeric &y, const numeric &x)
01527 {
01528 if (x.is_zero() && y.is_zero())
01529 return *_num0_p;
01530 if (x.is_real() && y.is_real())
01531 return numeric(cln::atan(cln::the<cln::cl_R>(x.to_cl_N()),
01532 cln::the<cln::cl_R>(y.to_cl_N())));
01533
01534
01535
01536
01537
01538 const cln::cl_N aux_p = x.to_cl_N()+cln::complex(0,1)*y.to_cl_N();
01539 if (cln::zerop(aux_p)) {
01540
01541 throw pole_error("atan(): logarithmic pole",0);
01542 }
01543 const cln::cl_N aux_m = x.to_cl_N()-cln::complex(0,1)*y.to_cl_N();
01544 if (cln::zerop(aux_m)) {
01545
01546 throw pole_error("atan(): logarithmic pole",0);
01547 }
01548 return numeric(cln::complex(0,-1)*cln::log(aux_p/cln::sqrt(aux_p*aux_m)));
01549 }
01550
01551
01555 const numeric sinh(const numeric &x)
01556 {
01557 return numeric(cln::sinh(x.to_cl_N()));
01558 }
01559
01560
01564 const numeric cosh(const numeric &x)
01565 {
01566 return numeric(cln::cosh(x.to_cl_N()));
01567 }
01568
01569
01573 const numeric tanh(const numeric &x)
01574 {
01575 return numeric(cln::tanh(x.to_cl_N()));
01576 }
01577
01578
01582 const numeric asinh(const numeric &x)
01583 {
01584 return numeric(cln::asinh(x.to_cl_N()));
01585 }
01586
01587
01591 const numeric acosh(const numeric &x)
01592 {
01593 return numeric(cln::acosh(x.to_cl_N()));
01594 }
01595
01596
01600 const numeric atanh(const numeric &x)
01601 {
01602 return numeric(cln::atanh(x.to_cl_N()));
01603 }
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01634 static cln::cl_N Li2_series(const cln::cl_N &x,
01635 const cln::float_format_t &prec)
01636 {
01637
01638 cln::cl_N aug, acc;
01639 cln::cl_N num = cln::complex(cln::cl_float(1, prec), 0);
01640 cln::cl_I den = 0;
01641 unsigned i = 1;
01642 do {
01643 num = num * x;
01644 den = den + i;
01645 i += 2;
01646 aug = num / den;
01647 acc = acc + aug;
01648 } while (acc != acc+aug);
01649 return acc;
01650 }
01651
01653 static cln::cl_N Li2_projection(const cln::cl_N &x,
01654 const cln::float_format_t &prec)
01655 {
01656 const cln::cl_R re = cln::realpart(x);
01657 const cln::cl_R im = cln::imagpart(x);
01658 if (re > cln::cl_F(".5"))
01659
01660 return(cln::zeta(2)
01661 - Li2_series(1-x, prec)
01662 - cln::log(x)*cln::log(1-x));
01663 if ((re <= 0 && cln::abs(im) > cln::cl_F(".75")) || (re < cln::cl_F("-.5")))
01664
01665 return(- cln::square(cln::log(1-x))/2
01666 - Li2_series(x/(x-1), prec));
01667 if (re > 0 && cln::abs(im) > cln::cl_LF(".75"))
01668
01669 return(Li2_projection(cln::square(x), prec)/2
01670 - Li2_projection(-x, prec));
01671 return Li2_series(x, prec);
01672 }
01673
01674
01680 const cln::cl_N Li2_(const cln::cl_N& value)
01681 {
01682 if (zerop(value))
01683 return 0;
01684
01685
01686
01687 cln::float_format_t prec = cln::default_float_format;
01688
01689 if (!instanceof(realpart(value), cln::cl_RA_ring))
01690 prec = cln::float_format(cln::the<cln::cl_F>(cln::realpart(value)));
01691 else if (!instanceof(imagpart(value), cln::cl_RA_ring))
01692 prec = cln::float_format(cln::the<cln::cl_F>(cln::imagpart(value)));
01693
01694 if (value==1)
01695 return cln::zeta(2, prec);
01696
01697 if (cln::abs(value) > 1)
01698
01699 return(- cln::square(cln::log(-value))/2
01700 - cln::zeta(2, prec)
01701 - Li2_projection(cln::recip(value), prec));
01702 else
01703 return Li2_projection(value, prec);
01704 }
01705
01706 const numeric Li2(const numeric &x)
01707 {
01708 const cln::cl_N x_ = x.to_cl_N();
01709 if (zerop(x_))
01710 return *_num0_p;
01711 const cln::cl_N result = Li2_(x_);
01712 return numeric(result);
01713 }
01714
01715
01718 const numeric zeta(const numeric &x)
01719 {
01720
01721
01722
01723
01724
01725 if (x.is_real()) {
01726 const int aux = (int)(cln::double_approx(cln::the<cln::cl_R>(x.to_cl_N())));
01727 if (cln::zerop(x.to_cl_N()-aux))
01728 return numeric(cln::zeta(aux));
01729 }
01730 throw dunno();
01731 }
01732
01733 class lanczos_coeffs
01734 {
01735 public:
01736 lanczos_coeffs();
01737 bool sufficiently_accurate(int digits);
01738 int get_order() const { return current_vector->size(); }
01739 cln::cl_N calc_lanczos_A(const cln::cl_N &) const;
01740 private:
01741
01742
01743
01744
01745 static std::vector<cln::cl_N> *coeffs;
01746
01747 std::vector<cln::cl_N> *current_vector;
01748 };
01749
01750 std::vector<cln::cl_N>* lanczos_coeffs::coeffs = 0;
01751
01752 bool lanczos_coeffs::sufficiently_accurate(int digits)
01753 { if (digits<=20) {
01754 current_vector = &(coeffs[0]);
01755 return true;
01756 }
01757 if (digits<=50) {
01758 current_vector = &(coeffs[1]);
01759 return true;
01760 }
01761 if (digits<=100) {
01762 current_vector = &(coeffs[2]);
01763 return true;
01764 }
01765 if (digits<=200) {
01766 current_vector = &(coeffs[3]);
01767 return true;
01768 }
01769 return false;
01770 }
01771
01772 cln::cl_N lanczos_coeffs::calc_lanczos_A(const cln::cl_N &x) const
01773 {
01774 cln::cl_N A = (*current_vector)[0];
01775 int size = current_vector->size();
01776 for (int i=1; i<size; ++i)
01777 A = A + (*current_vector)[i]/(x+cln::cl_I(-1+i));
01778 return A;
01779 }
01780
01781
01782
01783
01784 lanczos_coeffs::lanczos_coeffs()
01785 { if (coeffs)
01786 return;
01787
01788 coeffs = new std::vector<cln::cl_N>[4];
01789 std::vector<cln::cl_N> coeffs_12(12);
01790
01791 coeffs_12[0] = "1.000000000000000002194974863102775496587";
01792 coeffs_12[1] = "133550.502942477423232096703994753698903";
01793 coeffs_12[2] = "-492930.93529936026920053070245469905582";
01794 coeffs_12[3] = "741287.473697611642492293025524275986598";
01795 coeffs_12[4] = "-585097.37760399665198416642641725036094";
01796 coeffs_12[5] = "260425.270330385275465083772352301818652";
01797 coeffs_12[6] = "-65413.3533961142651069690504470463782994";
01798 coeffs_12[7] = "8801.45963508441793636152568413199291892";
01799 coeffs_12[8] = "-564.805024129362118607692062642312799553";
01800 coeffs_12[9] = "13.80379833961490898061357227729422691903";
01801 coeffs_12[10] = "-0.0807817619724537563116612761921260762075";
01802 coeffs_12[11] = "3.47974801622326717770813986587340515986E-5";
01803 coeffs[0].swap(coeffs_12);
01804 std::vector<cln::cl_N> coeffs_30(30);
01805
01806 coeffs_30[0] = "1.0000000000000000000000000000000000000000000000445658922238202528026977308762";
01807 coeffs_30[1] = "1.40445649204966682962030786915579421135474600150789821268713805046080310901683E13";
01808 coeffs_30[2] = "-1.4473384178280338809560100504713144673757322488310852336205875273000116908753E14";
01809 coeffs_30[3] = "6.9392104219998816400402602197781299548036066538116472480223222192156630720206E14";
01810 coeffs_30[4] = "-2.05552680548452350127164925238339710431333013110755662640014074226849466382297E15";
01811 coeffs_30[5] = "4.21346047774975891986783355395961145235696863271597017695734168781011785582523E15";
01812 coeffs_30[6] = "-6.3439111294220458481092019992445750626799029041090235945435769621790257585491E15";
01813 coeffs_30[7] = "7.2684029986336427327225410026373012514882246322145965580608264703248155838791E15";
01814 coeffs_30[8] = "-6.4784969409198000751978874152931803231807770528527455966624850088042561231024E15";
01815 coeffs_30[9] = "4.5545745239457403086706103662737668418631761744785802123770605916210445083544E15";
01816 coeffs_30[10] = "-2.54592491966737919409139938046543941491145224466411852277136834553178078105403E15";
01817 coeffs_30[11] = "1.1356718195163150156198936885250451780214219874255251444701005988134747787666E15";
01818 coeffs_30[12] = "-4.04275236298036712070700727222520609783336229393218886420197964965371362011123E14";
01819 coeffs_30[13] = "1.14472757259832757229433124273590647229089622322597383276758880048004748372644E14";
01820 coeffs_30[14] = "-2.56166271828342920179612184110684658183432315551120625854181503468327037516717E13";
01821 coeffs_30[15] = "4.4861708254018935131376878973710146069395814469656232761173409397653101421558E12";
01822 coeffs_30[16] = "-6.0657495816705687896607821799338217335976369800808791959096705890743701166037E11";
01823 coeffs_30[17] = "6.21975328147406581536747878587069711930541459818297675578654403265380823122363E10";
01824 coeffs_30[18] = "-4.7255003764027411113501086372508071116675161078057298991208060427341079636661E9";
01825 coeffs_30[19] = "2.5814613908651936680441351265410235295992556406609945442133129515256889464315E8";
01826 coeffs_30[20] = "-9752115.5047412418881417732027953903591189993329461844657371497174389592441887";
01827 coeffs_30[21] = "242056.60372411758318197954509546521913927205056839365620249547101194072057318";
01828 coeffs_30[22] = "-3686.17673045938850138289555088011327333352145765167200561022138925168680049115";
01829 coeffs_30[23] = "31.3494924501834034405048975310989414795238339283146314931357877820190435258517";
01830 coeffs_30[24] = "-0.130254774344853676030752542814176943723937677940441021884132211221409382350105";
01831 coeffs_30[25] = "2.16625679868432886771581352257834967866602495378408740265571976698475288337338E-4";
01832 coeffs_30[26] = "-1.05077239977528252603869373455592388508233760416601143477182890107978206726294E-7";
01833 coeffs_30[27] = "8.5728436055212340846907439451102962820713733082683634385104363203776378266115E-12";
01834 coeffs_30[28] = "-3.9175430218003196379961975369936752665267219444417121562332986822123821080906E-17";
01835 coeffs_30[29] = "1.06841715008998384033789050831892757796251622802680860264598247667384268519263E-24";
01836 coeffs[1].swap(coeffs_30);
01837 std::vector<cln::cl_N> coeffs_60(60);
01838
01839 coeffs_60[0] = "1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000007301368866363013444179014835363181183419450549774";
01840 coeffs_60[1] = "2.13152397525281235754468356918725048606852617746577461250754322057711822075135461598274984226013367948201688447853106595646692682568953E26";
01841 coeffs_60[2] = "-4.548529924829267669336610112411669181387790087825260737133755173032543313325682598833009521765336124891170163525664509845740222794717604E27";
01842 coeffs_60[3] = "4.6879437426294973235875133160595324795437824160731608900005486977197800919261614723948577079551305728583507312310069280623018775850412E28";
01843 coeffs_60[4] = "-3.10861265267020467624457768823845414206135580030123228715133927538323570190367768297139526311161786169387040978744732051184844409191231E29";
01844 coeffs_60[5] = "1.490599577483981276717037178787147902256911799467742317379590487947009001487476793680630580522955117318124168494382267800788736334308E30";
01845 coeffs_60[6] = "-5.50755504045738806940255910881807353185463857314393682608295373644157298562106198431098170107741597645409216199785852260920496247655646E30";
01846 coeffs_60[7] = "1.631668518639067070100242032960081591016027803392225476881353619523143028349554534276268195490790113905102273979193269720381236708853746E31";
01847 coeffs_60[8] = "-3.9823057865511431381368541930378720290638930941334849821428293955264049587073723565727061718251925950255036781219414607001763225298119E31";
01848 coeffs_60[9] = "8.16425963140638737297557821827674142140347732117757126331775708561852858085860735359056658172512163756926693444882201094206795155146202E31";
01849 coeffs_60[10] = "-1.426548236351667330492229413193359354309705120770113917370333660827270957172393778178051742077714657388432785747112574456061555034588373E32";
01850 coeffs_60[11] = "2.14821861694536170414714365485614715949416083667308573285807894910742621740039595483105992136915471547998283891842897000924199509164799E32";
01851 coeffs_60[12] = "-2.81233281290021706519566203146379395136352592819625378308636458418501787286411189089807465993150834399778687427813779950602826375635436E32";
01852 coeffs_60[13] = "3.222783358826786224404373038021509245352188734386849874296356404770508945395436142634892645963851510893216093037595555902121365717716154E32";
01853 coeffs_60[14] = "-3.250409075716999887328836263791911196138647661969351655925350981785153422033954649154242209471752219326556302767677017396179477496948985E32";
01854 coeffs_60[15] = "2.897783210826628399578158893643627107049805015801395657097255344786041806868455726759715576609013221857885740543509045196763816109465777E32";
01855 coeffs_60[16] = "-2.29136919195969647663887561122314618826917230275433296293059354280077561407373070937197721317435316121212106870152659174216557412788874E32";
01856 coeffs_60[17] = "1.611288006928200619663496306945576194382628760891807800193737346171844871295031418730500946186238469256168610033434708290528870722514911E32";
01857 coeffs_60[18] = "-1.009632466053186015034182792930705530447465885425278324598880797572411588461783484686932989855033967294215840157892487264656571258327313E32";
01858 coeffs_60[19] = "5.64520651042784179741815642438421132518008517154942873706221206276337451930555926854271086501686252334516011905237101877044320182980053E31";
01859 coeffs_60[20] = "-2.81912877441595327683492797147781153304080114512116755424671954256427789550109614317215500473322621746416096887803928883800132453510579E31";
01860 coeffs_60[21] = "1.257934257434294354026338893625531254891110662111965279263894740714811495074726866375858553579650295684850594211744093582249745250079168E31";
01861 coeffs_60[22] = "-5.01544407232599962845688086323662774702854661522104499328570796808858930542190600193190967249971520736397504227594619670310759235566195E30";
01862 coeffs_60[23] = "1.786035425040937365122699272239542501767986628253845452136132211710520249195280548478081559036323184490150479070929923213045153333111476E30";
01863 coeffs_60[24] = "-5.67605430104368150038863866362066081946938075036837029856903803768657069745962581310398542442108872722631658677177822712376500859930109E29";
01864 coeffs_60[25] = "1.607878222558573982505999018371559631909289246981490321219650132406126936263403946310818841465409950661433241956831540547593847161412447E29";
01865 coeffs_60[26] = "-4.05332042374309456146169816144083508836132423024788116321074411679252452773181941601763924562378611113519038766273534176937279867894066E28";
01866 coeffs_60[27] = "9.07493596543985672039002802030098143847503854224661484396413496012780904911929710460264147600378604646912175235271954302119768907744722E27";
01867 coeffs_60[28] = "-1.800074018924350353143489874038038169034914082090587278672411654146678304871125651069902339241049552886098125667720181441150399048551683E27";
01868 coeffs_60[29] = "3.154250688078046681602499411296013099183808016176992164829953752437167774310360166977972581670851790753785195101324694758021403186162394E26";
01869 coeffs_60[30] = "-4.86629244083379932983782216256143990390210226006560452979433243294026128577640975980482675864760717747936401374948595060083674140963469E25";
01870 coeffs_60[31] = "6.58428611248406176613133080039790689602908099995907522692286902207707012485115422092589779128693214784991500936878932461139361901566087E24";
01871 coeffs_60[32] = "-7.77846893445970039116628280774361378296946997639645747353868461156972352366479641995295874152354776734003001337605345817120316052066992E23";
01872 coeffs_60[33] = "7.98268735994772082084918485121285571015813651374688487489679943603727447378945977989630573952891101472578977333720105112837324185659362E22";
01873 coeffs_60[34] = "-7.07562692971089746095546542541499489835693326760069291570193808615779224025348460132750549389189539682228913778397783434269420284483726E21";
01874 coeffs_60[35] = "5.381346729881846847476909845563262674288431852755093265786345982700437823098162630059919716651136095720390719236493773958116646152386075E20";
01875 coeffs_60[36] = "-3.4856856542678356876484367392130359114150104987588151214926676834365219571876912071608359944324610844909103855562977795837329347647911E19";
01876 coeffs_60[37] = "1.90665542883474657677037950113781854248329048412482665873254624417996252139138481002200079466749149325431679310476862249520001277129217E18";
01877 coeffs_60[38] = "-8.72254994006151131395107200045641306281165826830744222866994799005490857259177347821280095689079457417603257537321939951004603693393316E16";
01878 coeffs_60[39] = "3.30066663941625244322555483012774856710545517350986120571194216206848716066355962922968824538055042855044917677713272771363157100391997E15";
01879 coeffs_60[40] = "-1.020092089391030771746960980075254826475625668908623135552682999358854102567810002206013823466362488147261886160954607897574298699485318E14";
01880 coeffs_60[41] = "2.537518136375035057088980117582986067754938584307761188810498418760131416720976321039509027979006220650166651208980823946300429957067604E12";
01881 coeffs_60[42] = "-4.99523339577986301543863423322168947825482352498610406809585164155176248614834684219539096936869521198401912030883142734471627752449382E10";
01882 coeffs_60[43] = "7.62961024898383965152735310352890448678585029645218309944823403624458716639413808284778269959424212699922000610764015063766429510499158E8";
01883 coeffs_60[44] = "-8834336.1370238009649936481782352367054397712953420330251745022286767420934395739052638862442455545176778475848478708230456099596423988";
01884 coeffs_60[45] = "75445.9196169409678879362111492280315111800786619928588067631801224813888137547544321383450353324917130013984795690223150786036557545929";
01885 coeffs_60[46] = "-459.8458738886001056822131294892698769439281099450630714273592488999986769567563218319365007529495798105783705491469742412340762305916056";
01886 coeffs_60[47] = "1.922366163948404706136462977961544621491268971185908661903800938507393909575693892375103171073678191394626251633433930639174604982075991";
01887 coeffs_60[48] = "-0.00524987734300376305383172698735851896799115189212445098242699916121836353753886238290792298378658233479210271064792489583846726184351881";
01888 coeffs_60[49] = "8.81521840386771771843311455937479573971716020932982441671173279504850522350287085310420429874536637110755391716691475171030099411021337E-6";
01889 coeffs_60[50] = "-8.42883518072336499031504944519862331274440110738275125460829656821173301216150526266773841539372995424665091651911614576906895281293397E-9";
01890 coeffs_60[51] = "4.1559932977982056953309753711587342647729282359841592558743510304569204546713517319749817560490538963802716194154620384631597656968764E-12";
01891 coeffs_60[52] = "-9.26494376646923216540342478135986593801117330292329759013854851055518195892306285985326338987592590319793280515888731024676428929933443E-16";
01892 coeffs_60[53] = "7.80165274836868312019654872701978288745672229459298320116385383568401529728308916875595120085091565550085090877341856355815270191309086E-20";
01893 coeffs_60[54] = "-1.922049272463411538721456378153955404697617250978865956250065913541261535132290272529565880980548519758359440057376306817458561627984943E-24";
01894 coeffs_60[55] = "9.46189821976955264154519811789356895736753858729897267240554901027053652869864043679401817030067356960879571432881603836052222728024736E-30";
01895 coeffs_60[56] = "-5.06814507370603015985813829025522226614719112357562650414521252967497371724973383019436312018485582224796590023220166954083973156538672E-36";
01896 coeffs_60[57] = "1.022249951013180267209479446016461291488484443236553319305574600271584296178678167457933405768832443689762998392188667506451117069946568E-43";
01897 coeffs_60[58] = "-1.158776990252157075591666544736990249102708476419363164106801472497162421792350234416969073422311477683246469337273059290064112071625785E-47";
01898 coeffs_60[59] = "4.27222387142756413870104074160770434521893587460314314301300261552300727494374933435001642531897059406263033431558827297492879960920275E-49";
01899 coeffs[2].swap(coeffs_60);
01900 std::vector<cln::cl_N> coeffs_120(120);
01901
01902 coeffs_120[0] = "1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060166025676976656004344991957470171590616719251813003320122316373430327091055571";
01903 coeffs_120[1] = "3.4497260317073952007403696383770947678893302981614719279265682622766639811173298171511730607823612517530376844024218507032522459279662180470113961839690189982241536061314319614353993672315096520499373373015802582693649149063603309572777186560148513524E52";
01904 coeffs_120[2] = "-1.4975581565000729527538170857594663742319328925831469933998274880997450758924704742659571258591716460336677591345828722528085692201176737000527729600671680178988361119859420301844184208079614468449296788394212801103162564922199859549237082372776667464E54";
01905 coeffs_120[3] = "3.1957762163065481328529158845807843312720427291703934903666695190945338610786360201875291048323381336567812569171891600400186742244091402566230953251621720778096033490814848238417212345597975915378369497445590090951446115848410773972658485451963575288E55";
01906 coeffs_120[4] = "-4.4689623509319752841609439083871154399631153121231062689347162975834499076693093642474289117173045421812089871506249999929076992135798925381959196225961791389783472385803138226317976820364502651110639008585046458007356178875618627927171581950486124233E56";
01907 coeffs_120[5] = "4.606068718424276543329442566011849623375399823565351941825685310847310447457609082356012685588953435307896055516214072529445026693975872604267789672469025113562486157850515006504573881812473997762948360804814769118883992998548055557441646946685125118E57";
01908 coeffs_120[6] = "-3.7314461146854666499272326592212099391213696621869706562566612605818861385928266960370453310708465394226398321257508947092784006446784523328681347046673172481746936234783770854350210504707173921547794426833735429199925024679815789545465854297845328325E58";
01909 coeffs_120[7] = "2.474425401670711256989398808079221298913654027234786607507813220440957186918973475366048940039541074278444160674001228864321389049663140487504402096319272526201782217412803784224929141788255724630940381342478088455751340159338461174261577243566175687E59";
01910 coeffs_120[8] = "-1.3811875718622847750042362590249762290599823842851465148429257970104907280458901604054390293828410620002370526629527048636126473391278330353375163563724888073254512227198849135923692811222561965740181944727170495185714496890490479692693474125883791901E60";
01911 coeffs_120[9] = "6.623089858532754482582703479109160446021743439335073883710993620625687271109284320721410901325182604938578905712329203551531862389936804947105415805829404869727743706364603519433193421234231031076682156125442577335383798263985569601899041876776866622E60";
01912 coeffs_120[10] = "-2.7709515004299938864490083840820063124223529009388282231525445615826433364331567602934962481829061542793349831611106716261513624279121506887680318284535361848032886450351898892264386237450622827397559067350672965967202437971930333676917000390477963866E61";
01913 coeffs_120[11] = "1.02386112293172223921263435003659366453292875147351461165091656394534393086780717052422266565203902889367201592668259202439166666819852985689989767402099479793087277263747942659943270101657408462079787397068550734516045511611701546009078868077038808757E62";
01914 coeffs_120[12] = "-3.3740197731917655541744976218513993073761175468772389726802124778433432226803314067431898210976006853342921093194297198044021414900546886804610561082663076825192459864843102368108908666053756409152492134638014803233805912009476407113691438596300794146E62";
01915 coeffs_120[13] = "9.996217786487670355655374796561399578704294298563457268841140703036898520360123177193155340144551120260016445533739357030180277693840431766824113840895797510199955331557143980793267795747200088810293047731873192410526786931879590684673414288653913515E62";
01916 coeffs_120[14] = "-2.6804750990199908441443350402311488850281543531194918304012545530803283220192092419107511475988099394746800512008906823331244710178292896561401750166818497729239682879419868799442954945496319510685448344062610897698253544876306888341881254056091234759E63";
01917 coeffs_120[15] = "6.5422964482833531603879610057815197301035372862466791995455246163778529556707384145891730234453157337303612060344197138180893720879196243783337539071284141345021864817147590781643393947019750353147151780290464319306645652085743359080495090595200531486E63";
01918 coeffs_120[16] = "-1.4604487304348366496825146715570516556564950771546738885215899741781982964860978993963272314092830563320794184042847908967120542212316261920409301852237223308467032419706968676861616456179895880956772385510853673982424825597152850339588189159102980666E64";
01919 coeffs_120[17] = "2.9942297466313630831467808691292548682230644559492580161942357031681185068971393754352871129412787966878287389513657398203481589163498279625760316093736277896138061249076616695157422053188087353540756151586375196486093987258640269607104978950906670704E64";
01920 coeffs_120[18] = "-5.658399283776588293772725313973093187743120982052603944865098913586526167668102733207163739469977271584007101869254711458133873627143366757941713180350370056955237604551850024423889291598422917971467957836705917204903687959901869098540153925178692732E64";
01921 coeffs_120[19] = "9.887368951584101622633538892976576123080629424367489037686110916264512731398396560326756128205833849608930564615629875435100785011872254223744155330328477703592008501954532369042429700051416733748454350165515933757314793533786385104271308839525639768E64";
01922 coeffs_120[20] = "-1.6019504550228766725078575508839635707919311420327486864048705642201106895239857903763208049376932672160478820626774934879424498715258948985194011690204294886396827446040036506699933786721588971678753877371518212675519147446728054067639530675249526082E65";
01923 coeffs_120[21] = "2.4124568469636899540706437405441629738413207418758399778576327598069435452295650039157974716832514441625728576753250737726840109004878753294786785674578138926529507088264657400701828947949531197915861820274684954206665488761473274445827472596875582911E65";
01924 coeffs_120[22] = "-3.3841653726400000079488483558717068873181168418395106876260246491163166726612427450773591871178866824643300679819366574162583413250423974373322308130319007820863363304629451933781204964221002853140392226489420463827400812929748772154909106349410663293E65";
01925 coeffs_120[23] = "4.4305670380812288478773282114598811227924298131011853412998479811262358077680067168455361591598296346480072528806092976336961470360354620203822421524751468329936930212919915114854135818230382164555078957880154875221176513434392525189922941290050575762E65";
01926 coeffs_120[24] = "-5.4228176962574428947233160003094662570284359565811627941401342797491445636152854865132166939274138115146035207618348708829039395974942115203986578386666664945394109693178927438991059414217518334491360514633536224841961444935232548483014691997071543828E65";
01927 coeffs_120[25] = "6.214554789078092267222051275213928685756510105900211846145778269883351640710249139978059486185007208670776100912863866582278800642692097830681092656540813877576256048148229340562594504915197956922387464825593941922429396202734006609196778697870436014E65";
01928 coeffs_120[26] = "-6.6773485088895517986512141063848395783979405189075416643094283756118912554557672721632998501682483143868731647507940026369035991063923616298815637819145806214374157182512600196214559297579802178103007615921637577873304407436850546650711237281572008424E65";
01929 coeffs_120[27] = "6.734925330317694704469314845373778479111077864464012553672292377883525864326847400954413754291163739900219432201437895152976917857427306427115230048061308424221525123820493252697918698598513232640014129066982507718245232516657455821629338155744427538E65";
01930 coeffs_120[28] = "-6.383582878496429871173501676061533991181960023885889537277705274319508246322757005217436814481703326467002683699047193244918123789600842413060331898515872574523803039779899326755393070345055586059441271293717500426377884349137309244757708993087958455E65";
01931 coeffs_120[29] = "5.6913529405959275511022780614007027176288843526260372650173869440228336395668389555081751187360483397341349300975285817498083216487282169140596290796279875175764991375447348355187090404486257481827615256024271536396461908482904537799521891879785332367E65";
01932 coeffs_120[30] = "-4.776996734587211249165031248400648409423153869394988746115380756083311986805300361459383722536698540926452976310737678416019979202990255666249869917768885659350216400547190883549730059461513588008706974008085270389354525600694962352952715682056375518E65";
01933 coeffs_120[31] = "3.7775367524287124255443145064623569295746034916892464094281613465046063954544055573214473155479196552309207209647540614474216985097792266203411723082566949978062697757983354600199199984244302856099811940389910544756210676400851240882142140969864764468E65";
01934 coeffs_120[32] = "-2.8161966171919236962021901287860232075259781334554793534017516884995332700369401674058517414969240048359891934178343992080557338603528540157030635217682829894098359736903943078409166055640608627322968554856315650475005062493399450913753277478547118352E65";
01935 coeffs_120[33] = "1.9804651678733327456903212258413521470612733719543558365536494344764973229749132899499862883369665827727506916597326744330471802598610837032598656197205238983585794266213317465548361566327435762497208877015986690267754534342053368396181078097467171858E65";
01936 coeffs_120[34] = "-1.3144275813663231527166312401997093907605894997476799416306355417933431514642211250592825223377757973148122542735038736133300194844844655961425683877005418926364412294006123974642296395931311307760050290069031276972832755406161248577410950671224318855E65";
01937 coeffs_120[35] = "8.2367260670024829522614096155108151082106397954565823313893008773930966293786646885943761866773022391428854862805955553810619924412431932999726399857050871862122529700098570542876369425991842818202826823540112018849926644955200888291063471724203391548E64";
01938 coeffs_120[36] = "-4.8749964750377069822933994525197085013480654713783888755556109773660249389776804499013517227967180500633060271953473316017147397601291325922904139209860429881054757911243087427393920494271315804033914011087815785282473032714919188637172020633929566123E64";
01939 coeffs_120[37] = "2.7259664773094932979328467102942769029907299417406744864696200699394594868759231280169149208728483197299648608091313447896342349454038879581019820193316159535211365363553004387852005780736869678460092714636910972426808304270369152189989142121207224142E64";
01940 coeffs_120[38] = "-1.440426226855027726783521340050349148103881707415523724377763633849488875095817796257895327883428230885349760692732068174527147156893314818583058727424251827006457849321094911262818557954829248070170426870959233263267490276774734065709978749400927185E64";
01941 coeffs_120[39] = "7.193790858249547212173205531149034887209275529426061411129294234841122474820371873361100215884757249851960370114629943083807936135915003201800204713978377250292881453568756354858194614039311248345228434431020394729104593125888325843724239404594830488E63";
01942 coeffs_120[40] = "-3.3960029336234301755324970935705944032408435186630159101426062821929524761770439420961993430248258136340087498829339209014794230274407979103789924433683527009234592433480445831820377517333956042612961562022604325181492952329031432513768020816986814393E63";
01943 coeffs_120[41] = "1.5154618904112106565112797443687014834429200069480460967081898435635890576815349145926430052596468033907024005478559584915319911380449387176530845634833237204659108290330613043367085829373476690728522550189678729181372902816898536141595215616716630939E63";
01944 coeffs_120[42] = "-6.3927647843464050458917092484911245813170740434503951669888756878206365814594631676413018245438405308353724023007754523096143775098898268650326908751515418318201372985246418468844138298345777180517875695389655616000832495210812684049030674085212697428E62";
01945 coeffs_120[43] = "2.5490394366379355452002449693074954071810215414182359403355645652443600688717811337587901850157210686351097591461582890354662732336749618027675479531031836144519267481752770036252137747675754903974915999567019837855523058289177148692481402871253211324E62";
01946 coeffs_120[44] = "-9.606466879185328464666445215840505657671157752044466089989040292763536710311599947887918708456526669882072519263973105599580140713596301388561639705589314111762600854460059589939760935803484446888352368360433606245369171819922425771642408570388554052E61";
01947 coeffs_120[45] = "3.4212392804723358445152430359637323789304939688937873921904941412927756295848104328630952153624979489607759834359194243032109828811134607612715016533909375981353098879969472700079242226099049323998286020341979178782935852542355220403299144612362244738E61";
01948 coeffs_120[46] = "-1.15119134701605919461057899755821946453925102458815313053351247263978303346790555715641513756644038607667203392289423834966320935498856390723555744530789850290369071103208529608463210398231590077340268751005311531529356083188150256469829678612245577446E61";
01949 coeffs_120[47] = "3.6588622583411432033523084711047679684233731128914152509273818448610176621874654252431411048902598388935105893946323641003087000410095802098177375492833543391040706755511234323104846636415419597151008153829618275459606044459923718022154035121167198784E60";
01950 coeffs_120[48] = "-1.0981148514467449476248066871827754422009180048705085132882492434176164929454140182025449006310206725429473330511884213470600326782740663313311256352613244044500057688932314549669435095761340307817735687643806167483576999980691227831561891265615422486E60";
01951 coeffs_120[49] = "3.110998209448997739767747906196101611409160829345058138064861244336130082424927251851805875584197897229644157110035272012393338413235208343342708685139492629786435072305986349067452739209758702078026647999828517440754895711519542954337931090643534216E59";
01952 coeffs_120[50] = "-8.3162485922574890007748232799240657004521608654422032389269811102140449056333167761296051794842882201869698963586030628312914066893199727852512779320175952962772072653493447297721128265231294406156925752496310087025926300388984242024436858845487466277E58";
01953 coeffs_120[51] = "2.0966904516945699848169820408710416999765756367767199815424586610234585829069218729220161654233351574517459523275756901094737085187558904179251813051891939079067686519817858153690134828671544815635956527611986498479411756457222935682849773436423295467E58";
01954 coeffs_120[52] = "-4.983121305881207125553776640558094509942884568949257704810973508397697839859902664482541160531856121365759763455699578413261749913567077796586919935391984240753355552646184306812426079133011894826183873855851966310877619118554510972675999316631346679E57";
01955 coeffs_120[53] = "1.1158023601951707374356047495258406415892974604387009613173591921419195864040428221070481312383179580486787822935456571355463718115785982888531393271665510645725283439572279946304699780331972095822869500426555507626639723865965516308476400920600382357E57";
01956 coeffs_120[54] = "-2.3524850615012075127499506758220926725372558166170912192116695445007095502575329450463479860779122789467638956004572617263549199692255055063165454868102165975951768676031140009643202074220557325155838768661030361538572755082660730808847591840060467064E56";
01957 coeffs_120[55] = "4.6669318431895615057208826641721251136909284138581355667925884903657855204100373961676117747969449100495897986226609480142908763981931305129946569690612924941456739524153327260627627771254850382983581593260532259539447965597396206625726656509884058042E55";
01958 coeffs_120[56] = "-8.7053773217442419007560462613131691749734845382618514999712446313788486289774350240165530159591402631439776213579542026449818009956904779042347595401565525081115611496250192338958392965746523979241969677734430475813057146574920495171984815351708574336E54";
01959 coeffs_120[57] = "1.5256552489620511464542280446639568546874380361953025589702692266626310669215652044048704882910412155084167930513006634430352568411276836880182348033924636960897794333644980768878022821035659978039286230061734024129667272393315169114199838321062607299E54";
01960 coeffs_120[58] = "-2.5099934505534008439782195609383796207770494575364994376922414269548303512602084430128307108303305643530918354709126474742035537827601791192999467996479881350277448357927640707861695639576629921988481117017137420422963638277868648516492581097660522547E53";
01961 coeffs_120[59] = "3.872963359882179682964169603201046384616694634651871844057456079738892419308420856725974686574980381399016464501318163662938118593626674643538005780375691959391996340141057698193381380484420715733863044826589570328349973407598034428591146829028071358E52";
01962 coeffs_120[60] = "-5.59947633823301408044455223877913062308847941596689956112764416031828413291312481723036534632655608672535030921469531903033364444816678754679807809159478411100820014592865068932440734964265842594875758737421026093110624848762070026616564150314951394E51";
01963 coeffs_120[61] = "7.57762861280525531438216991274899157834431478755285945898172885086150762425529113816148806028462888396660067975773261101497666568988246606837690320098870044112671149076084444095163491848634465373822951831018725769263871497616640732007420499659069842E50";
01964 coeffs_120[62] = "-9.587786106526273406187878833167940811862067040706459726637556599860244751467528905534431960251166924163661188573831350928972391892492380823531476387272791432306808700507685765850397294118719242350333451452137838374120658600691461454898577711260078952E49";
01965 coeffs_120[63] = "1.13288726401696728230264357306938076698155303500407071418573081766541065136778223998897791839613776442037036668986628122296219518360439574147622758002647495909592177914657175019781723803408732148262293125845657503039410078589916085532057725749397276232E49";
01966 coeffs_120[64] = "-1.24849787223197441956280303618704887038709792250544105638342097080498907831514597860418910331910245753340059089147824955071899315894649696314820492532126554883819507650973976145456660786429117569053901704116877128391672511345177517877672824534972448216E48";
01967 coeffs_120[65] = "1.2815463720972693091316233381473056495608681859925407504190742949467232967966271661733907550222983737930524555721493736920130260377888287772008209963158064973076933575966719577456540496444474944074979736374259087350416613616719928507635667369740203319E47";
01968 coeffs_120[66] = "-1.2234887340201843394744986892310393596065877342193196880417674427168862926389642850813687099959036354499094230765541977493433449153438766822382486040215211159359175689369230076522107734270943423777076523650345103234411047700646432924770659676420158487E46";
01969 coeffs_120[67] = "1.0847187881607033339631651118075716564835185723270640503055198532318419482330026641941088359447807553514405522074008969583213861070993661224871455023365601323302778638456843760403418046238489404394483720438784739822580385277055304353975028280477740796E45";
01970 coeffs_120[68] = "-8.9160881476675795743767277986448579964735858351472748620623279571408606135698760493224031735408212513500922230670883171668702983221921543376953865813604783695111225412173880768170509738290662806468458720236121755965944855709552219268353813402612336565E43";
01971 coeffs_120[69] = "6.782864920104031936272293608616215844503387641476821968620772153274069873138756405621471099960069602613619793775294358177761533027360002770186566164041138064221354961783144649476276625776241973967317262115970868665380343599565811072109785000646703404E42";
01972 coeffs_120[70] = "-4.7667808452660756441368384708874451089976319738852731080495062883240643961463680300964077232336439626019128672679703771884184482488932861160134911816225569323838390204451496983578077563176966732010513231048738892639707790407292070646798259086924770995E41";
01973 coeffs_120[71] = "3.0885057140860079424719232591765602418793465632939298397987628606701994268384966881159469651774584648643122830739130127593326652998108850492039117928976417052691273804304806596509726701594300563830431015215234640024338277573401498998072908815285293868E40";
01974 coeffs_120[72] = "-1.8410405906573614531857309495652487774337134256805076777639383854080936219680656594060736479739035202182601529001321266214227848431889644620036213870966329509961114940541333851155401637197303308322414678191211465563854205816313387785764908216851396633E39";
01975 coeffs_120[73] = "1.0073694433024942271325653907485159683302928496826793112696958500366488338508211620934892875328717073528902110227362794694820010124321343709182901273795782541866547318841893692957109947576483162095037812781379193423759617638948859880051822460818418552E38";
01976 coeffs_120[74] = "-5.0475051506252944853315611134428802424958512917967945464108691542854207821486654807141339210375899950551724141366521361887864357385178212628348794663127149312605456165451981719848656127310229221238908657530297751682848475855876378576874607521597136906E36";
01977 coeffs_120[75] = "2.3099766115359817610656986443137072041797751710805647712896098246833051023271876304983288225638204962631413469467959017768113430777226924099787875749611560913177631681394153889301715579572842026181746028117354815826836594637709952294015960031772162547E35";
01978 coeffs_120[76] = "-9.629053850440590569772960665435833408449876392175761493622541259322053209458881628458334353756739601360772251654643632187697620334088992038575944303101187678397564511853344433267011583960451100374611538881978045643233876974513962362084978095067025623E33";
01979 coeffs_120[77] = "3.6452126546120530579393646694066971671091434168707822859890104373691687449831950255953317231572802167174179528347370588567969602221261721708890001616085516755796796282628169745443137768549800602834096924025507345446292715781107949529692160434800323E32";
01980 coeffs_120[78] = "-1.2492564030201607643388368733220662634846470405464496879151879822123866671204541555507638492613046717628358162773937737774832271305618491107140304474323049182605167775847584622690299098207979849043605983558768056117581593008210986863088433891075743152E31";
01981 coeffs_120[79] = "3.8627447638297686357472526935538070834588578920414538227245516723308987020816841052950727259618753144711425856434270832495754300189881199851254605718213699755258867641301730599979474865704144160112269948588154919128986989885090481959424806312935273075E29";
01982 coeffs_120[80] = "-1.0736758703963497284148841547397192249226725101007524773889805877171959717011395181953504058502607435217886087332761920207901621377557079619638699346496468750455986591040017334237734940082333954589067611955107878899677189289648293223359861027746438121E28";
01983 coeffs_120[81] = "2.6722714785740082059347577649909834926335247252399259683264830680945466475595847553753509546415283809619181144796536494882020159787371993099998263815645014317923922311421330376008111312767167437401741178863083976628261471599264811824656877164988491393E26";
01984 coeffs_120[82] = "-5.9304047185329750657632568788530498935629656326502947505210292278638825286675833282579834326765999907183142489791905921257123760969245535649745876992946512033156167841406724363867902645010435996961270021857807247440211477908060243655541266857227638988E24";
01985 coeffs_120[83] = "1.16817022089143274700208191285335154155497013626172270535715899131321522799010543339535307798264602677955894930046454353008462671803498794203612585729705145312299224155123919877760274781582850868001155383467754608529345730226972329454404720862870618607E23";
01986 coeffs_120[84] = "-2.03239515657536501213472165328009690017090356606547792466197690386716728380893226886179282271040418637806139515373566132123131620086873213475424131345589653019635327048678766191769576650893957440830876852296666120473866301097954633389040518870395767125E21";
01987 coeffs_120[85] = "3.1065334503269182605978912331263087603258864771943471481540265718169544724355602987297631515907391374943512439350265433478241465606056187134785807375293801936399644663199667496663518171930757047012102683120173353568660795955174938680248863153863947508E19";
01988 coeffs_120[86] = "-4.1476244154347831048636005592317388215032295704489937704602030038303705695463546496640638505584602502764898113504560236629804442607426019604639559875021291459916615723777004493344143132459204229291886967479716413925814352313734234340863490128872380307E17";
01989 coeffs_120[87] = "4.8067293487250079673131214670887682215073707729621636364424152483295071605326220176372385638491275365750175037404843071051780212494354459897540110089573898336327006157766256896984455454193271731091632286742192439925748114360605084629432813597189767538E15";
01990 coeffs_120[88] = "-4.8023544548381246628003457039588616467438691159189277447469028024236284353593054364114519649309416187375157096932150251663679454372678125518452171003992957433311257042292636706448339781439297178835786059318810522834929923770539615271536113963729385909E13";
01991 coeffs_120[89] = "4.1055087514683476865343055835875083237542317413651906253058979029083965525058905726360233143503628224856307545474786181299719957472120906835233967660557875100202077212004953379299507351564181758434304881046845705855303854083493519588411179065109026834E11";
01992 coeffs_120[90] = "-2.9787503393847675871205038539267895335240592213878943742323972872214441728681744433089698206110260166068266926018988659692353298939109421567999207730700359726920482465669373553804927535369930188390246988033893916611435406224816632683980860607732310186E9";
01993 coeffs_120[91] = "1.8178328110729629877907010659834277046059726898311908447099830056830012488194646687474150289147446390570639168063598563291822008033517936194534129929881015025633519502485415000390171249019651579295905194415531994026553693578406432674734610095421683863E7";
01994 coeffs_120[92] = "-92391.136314434380495997449781381513978328604842061708454699991154771188446049720445502194923435235472458378926242100033122111143321209059959788378033220861638093951546784186137626553022963832352496255851690092415165826965388502958309163995296640164754";
01995 coeffs_120[93] = "386.82763074890451546182061419449593717951707520472938425276820204065379182568600735469831672149785863654956632602671563997131280046154927653332261114114005498875447205079045401364007035880825957300757663780618819785476980699579657587509130753204519233";
01996 coeffs_120[94] = "-1.3181204292571874302358432444324779303744749959754136019600954846045028319805074783759764870805734807693739252625657350494147444011046941331047057337345953605042408524072436811726898109072388160378243068564382623631658424851676817690976343859083960324";
01997 coeffs_120[95] = "0.003606538673252695455085947121496196507159591230095595764694813152630524319596509155920374890595867709349176662036024214476302717902368680224618116411588086562230407996267622244422187853090635901906175373997993725355114393033631058067900506212434600015";
01998 coeffs_120[96] = "-7.805244503909439374422205381130511738566245024242591464192744568789876715121004646510755612128565674260161510215430132815223049297785205382643947556846567064565241387424696940674258789227398935846571768027456535982674711768030751512030174841314425949E-6";
01999 coeffs_120[97] = "1.31373705470989377112938364152965446631228819123896570245455699237549295870321627234421140232628798373711221392827979836922621437205363811871692678679625916100572037589291239046725228767017131155814257944742981208252138821140381478767814046301821211856E-8";
02000 coeffs_120[98] = "-1.6872873094408224472617181717534409090015431593544429529131126514352910895332010213914243717484771690790552077128803350550170014347729272790464826195676369023970955260051387240496705602732313607409271794413329062030561818907163134089683283286623809325E-11";
02001 coeffs_120[99] = "1.6183083251905685095057354853863188515437903228178486856957070037813756492593759658405336450433607296873747595037080703825755020175480385843762609522889527239577435110258291566585028919336090916225831079571865425410181260759913688103716786795647286451E-14";
02002 coeffs_120[100] = "-1.13097359411474028225398794102354853670936316496817819635688647804142428962171772690717075128208102537660772310780986623575005236651312181907812813813504742701120603881086064664411899253566047514905519888629604717647221817372977488600336785871295304013E-17";
02003 coeffs_120[101] = "5.599216369109121957949255319730053610385733330502739423509794477602247233276045188197007198417289907263120960704056657544648432653622931077692740961599655386871075693202473992087883485704436336279135221721374640982826144708808646466699352755417123702E-21";
02004 coeffs_120[102] = "-1.9009180102993021108185348502624676395148544369474718879637745630712451378711342634099259114111847962752555305470572286326367888004493816251811794947276966269738750207359305252041104539066278002044545942171476984766923991983055271262414217352967659228E-24";
02005 coeffs_120[103] = "4.261262509940940316499754264112111685174274727656165126333137554124192224955656564229887938745508952447664695831728428607673797269945824475565104978593072684829487175697371245288754204324544164474840153141042852153497051337607734150135978754952561336E-28";
02006 coeffs_120[104] = "-6.033854291373449912236926137860325602686312455380825767485673949251953414778800668020214699151728472172651816317924130614791108454134597377848088327850505473503152696524861086193124979489104732214189466703901268332265826882296309653009237279831825243E-32";
02007 coeffs_120[105] = "5.1208402745272379096703574714836785944518835939702823617280147111145234914591060871138496110227453241036619229980622243972303295470574470937679143516006222494480144845809123492603651773613707216680534850900104861326332900592715684757980394834998321888E-36";
02008 coeffs_120[106] = "-2.4463535717946588550832618025289907099586319384566637643650142186828541109926588999585266911960640972919441499109750654299062004147686492034166034659422424525984094382368955916181276646903453872999065929058429821759475215620044891133652431220664754175E-40";
02009 coeffs_120[107] = "6.0973480699773886324239008989591793773608942051497498591908583910660358857815864266160341286217871697703362816166340947142517661604423899536979689047275448159991318658879804351288744125363072102852651926942302209139318098544348348564409845011546432615E-45";
02010 coeffs_120[108] = "-7.2234185761285078775026471720270426097727212523472472797635230392183067756271499246654638332288950167477129840028892565652782123508855602380279653475510712205780583313834027906297063690370430285856541927759405826980856379432703473274890527421175151858E-50";
02011 coeffs_120[109] = "3.6217112680215791206171182969894344487335819731880124290544082848140757826983885738735436324684863867140575000400288923606439193119990961489053513339202655922248092157737577138929144240507796562250602457839068582279379672722261563501188150876583184441E-55";
02012 coeffs_120[110] = "-6.6329300032795486066608594142675837603786558782159646987663521197523704085781830169369726460621246948945196657495305819768951424025780824076252490918306538895670861455244641773606980519824591785816943621538721352987553804824051051144609050417497894495E-61";
02013 coeffs_120[111] = "3.6664720904335295532012711597888717227860988776477301054518326674835421172405060906940404374163713097964932859351917152390238690399278248344863365606468942320103392909602843987855082225592776850615943708151738327210634139824601616072015258461809772448E-67";
02014 coeffs_120[112] = "-4.7466013179695826928232672846686064011594588664906398407027593213652099998530859940288723349213099851532139911079905393494419637612780994270110734378146177806681489226896952731800026849872070824592339117757940119304241732812925979963178130104280115315E-74";
02015 coeffs_120[113] = "1.0163707785221910939390789816391472677729665860532352695801597334766068288835382195560328979864550624486740471947632369344045378626680607890520366137741785540226552923584183986350590955499329375427326072319268396685478606934920507703868118038891818762E-81";
02016 coeffs_120[114] = "-3.4814151260242800905467399051937942442621710748397374123807284826536707678408888416026868585492229216524609739211131993326633970334388991812593549702868877534701822990946125111761892723042376117665640296993581745994557803052315791392349639065203872505E-90";
02017 coeffs_120[115] = "1.18525924288117432386770939895670573772658621857195305986011196724304231598127227408839423385042572374412446842112646168302015480830234100570192462192015131968307084609177540911503689228342834030959242458698413980031135644018348590823980902427540799814E-91";
02018 coeffs_120[116] = "-8.5714961216566153236700116412888006837408819915951896129362859520462766617634320531162919426026429378433105901035364956643086394331335747930198070611009941831387116980941022864465946989065467218665543814574849964435089931072761832853235509961870476035E-93";
02019 coeffs_120[117] = "4.5681983751743456413033268196376305093509590040595182930261094908859252761697530924655649930852283295534503341542929581967081012867692190108698698006237799801339418962091877730207560007839789937153876806052229193448161273005984514504886230869730232561E-94";
02020 coeffs_120[118] = "-1.5943139155457706045530478744891549581317663177038648406493256399589001327414318955746453934207742828511041930090849236963271943244329753764497401819704943705370596846318480510254313447057477914171472190541408193443142906466279172123681623644325254209E-95";
02021 coeffs_120[119] = "2.7319125666863032595604997603472305262880292377469053594326527505796348018540179196191192420176181194669607935656210005192217186286873953583571180312679155204061051208771126804209623533044988888808754656646355388901404252058383561064953226611421609762E-97";
02022 coeffs[3].swap(coeffs_120);
02023 }
02024
02025 static const cln::float_format_t guess_precision(const cln::cl_N& x)
02026 {
02027 cln::float_format_t prec = cln::default_float_format;
02028 if (!instanceof(realpart(x), cln::cl_RA_ring))
02029 prec = cln::float_format(cln::the<cln::cl_F>(realpart(x)));
02030 if (!instanceof(imagpart(x), cln::cl_RA_ring))
02031 prec = cln::float_format(cln::the<cln::cl_F>(imagpart(x)));
02032 return prec;
02033 }
02034
02040 const cln::cl_N lgamma(const cln::cl_N &x)
02041 {
02042 cln::float_format_t prec = guess_precision(x);
02043 lanczos_coeffs lc;
02044 if (lc.sufficiently_accurate(prec)) {
02045 cln::cl_N pi_val = cln::pi(prec);
02046 if (realpart(x) < 0.5)
02047 return cln::log(pi_val) - cln::log(sin(pi_val*x))
02048 - lgamma(1 - x);
02049 cln::cl_N A = lc.calc_lanczos_A(x);
02050 cln::cl_N temp = x + lc.get_order() - cln::cl_N(1)/2;
02051 cln::cl_N result = log(cln::cl_I(2)*pi_val)/2
02052 + (x-cln::cl_N(1)/2)*log(temp)
02053 - temp
02054 + log(A);
02055 return result;
02056 }
02057 else
02058 throw dunno();
02059 }
02060
02061 const numeric lgamma(const numeric &x)
02062 {
02063 const cln::cl_N x_ = x.to_cl_N();
02064 const cln::cl_N result = lgamma(x_);
02065 return numeric(result);
02066 }
02067
02068 const cln::cl_N tgamma(const cln::cl_N &x)
02069 {
02070 cln::float_format_t prec = guess_precision(x);
02071 lanczos_coeffs lc;
02072 if (lc.sufficiently_accurate(prec)) {
02073 cln::cl_N pi_val = cln::pi(prec);
02074 if (realpart(x) < 0.5)
02075 return pi_val/(cln::sin(pi_val*x))/tgamma(1 - x);
02076 cln::cl_N A = lc.calc_lanczos_A(x);
02077 cln::cl_N temp = x + lc.get_order() - cln::cl_N(1)/2;
02078 cln::cl_N result
02079 = sqrt(cln::cl_I(2)*pi_val) * expt(temp, x - cln::cl_N(1)/2)
02080 * exp(-temp) * A;
02081 return result;
02082 }
02083 else
02084 throw dunno();
02085 }
02086
02087 const numeric tgamma(const numeric &x)
02088 {
02089 const cln::cl_N x_ = x.to_cl_N();
02090 const cln::cl_N result = tgamma(x_);
02091 return numeric(result);
02092 }
02093
02096 const numeric psi(const numeric &x)
02097 {
02098 throw dunno();
02099 }
02100
02101
02104 const numeric psi(const numeric &n, const numeric &x)
02105 {
02106 throw dunno();
02107 }
02108
02109
02114 const numeric factorial(const numeric &n)
02115 {
02116 if (!n.is_nonneg_integer())
02117 throw std::range_error("numeric::factorial(): argument must be integer >= 0");
02118 return numeric(cln::factorial(n.to_int()));
02119 }
02120
02121
02128 const numeric doublefactorial(const numeric &n)
02129 {
02130 if (n.is_equal(*_num_1_p))
02131 return *_num1_p;
02132
02133 if (!n.is_nonneg_integer())
02134 throw std::range_error("numeric::doublefactorial(): argument must be integer >= -1");
02135
02136 return numeric(cln::doublefactorial(n.to_int()));
02137 }
02138
02139
02144 const numeric binomial(const numeric &n, const numeric &k)
02145 {
02146 if (n.is_integer() && k.is_integer()) {
02147 if (n.is_nonneg_integer()) {
02148 if (k.compare(n)!=1 && k.compare(*_num0_p)!=-1)
02149 return numeric(cln::binomial(n.to_int(),k.to_int()));
02150 else
02151 return *_num0_p;
02152 } else {
02153 return _num_1_p->power(k)*binomial(k-n-(*_num1_p),k);
02154 }
02155 }
02156
02157
02158 throw std::range_error("numeric::binomial(): don't know how to evaluate that.");
02159 }
02160
02161
02167 const numeric bernoulli(const numeric &nn)
02168 {
02169 if (!nn.is_integer() || nn.is_negative())
02170 throw std::range_error("numeric::bernoulli(): argument must be integer >= 0");
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206 const unsigned n = nn.to_int();
02207
02208
02209 if (n & 1)
02210 return (n==1) ? (*_num_1_2_p) : (*_num0_p);
02211 if (!n)
02212 return *_num1_p;
02213
02214
02215 static std::vector< cln::cl_RA > results;
02216 static unsigned next_r = 0;
02217
02218
02219 if (!next_r) {
02220 results.push_back(cln::recip(cln::cl_RA(6)));
02221 next_r = 4;
02222 }
02223 if (n<next_r)
02224 return numeric(results[n/2-1]);
02225
02226 results.reserve(n/2);
02227 for (unsigned p=next_r; p<=n; p+=2) {
02228 cln::cl_I c = 1;
02229 cln::cl_RA b = cln::cl_RA(p-1)/-2;
02230
02231
02232
02233
02234
02235 if (p < (1UL<<cl_value_len/2)) {
02236 for (unsigned k=1; k<=p/2-1; ++k) {
02237 c = cln::exquo(c * ((p+3-2*k) * (p/2-k+1)), (2*k-1)*k);
02238 b = b + c*results[k-1];
02239 }
02240 } else {
02241 for (unsigned k=1; k<=p/2-1; ++k) {
02242 c = cln::exquo((c * (p+3-2*k)) * (p/2-k+1), cln::cl_I(2*k-1)*k);
02243 b = b + c*results[k-1];
02244 }
02245 }
02246 results.push_back(-b/(p+1));
02247 }
02248 next_r = n+2;
02249 return numeric(results[n/2-1]);
02250 }
02251
02252
02259 const numeric fibonacci(const numeric &n)
02260 {
02261 if (!n.is_integer())
02262 throw std::range_error("numeric::fibonacci(): argument must be integer");
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279 if (n.is_zero())
02280 return *_num0_p;
02281 if (n.is_negative()) {
02282 if (n.is_even()) {
02283 return -fibonacci(-n);
02284 }
02285 else {
02286 return fibonacci(-n);
02287 }
02288 }
02289
02290 cln::cl_I u(0);
02291 cln::cl_I v(1);
02292 cln::cl_I m = cln::the<cln::cl_I>(n.to_cl_N()) >> 1L;
02293 for (uintL bit=cln::integer_length(m); bit>0; --bit) {
02294
02295
02296 cln::cl_I u2 = cln::square(u);
02297 cln::cl_I v2 = cln::square(v);
02298 if (cln::logbitp(bit-1, m)) {
02299 v = cln::square(u + v) - u2;
02300 u = u2 + v2;
02301 } else {
02302 u = v2 - cln::square(v - u);
02303 v = u2 + v2;
02304 }
02305 }
02306 if (n.is_even())
02307
02308
02309 return numeric(u * ((v << 1) - u));
02310 else
02311 return numeric(cln::square(u) + cln::square(v));
02312 }
02313
02314
02316 const numeric abs(const numeric& x)
02317 {
02318 return numeric(cln::abs(x.to_cl_N()));
02319 }
02320
02321
02329 const numeric mod(const numeric &a, const numeric &b)
02330 {
02331 if (a.is_integer() && b.is_integer())
02332 return numeric(cln::mod(cln::the<cln::cl_I>(a.to_cl_N()),
02333 cln::the<cln::cl_I>(b.to_cl_N())));
02334 else
02335 return *_num0_p;
02336 }
02337
02338
02342 const numeric smod(const numeric &a_, const numeric &b_)
02343 {
02344 if (a_.is_integer() && b_.is_integer()) {
02345 const cln::cl_I a = cln::the<cln::cl_I>(a_.to_cl_N());
02346 const cln::cl_I b = cln::the<cln::cl_I>(b_.to_cl_N());
02347 const cln::cl_I b2 = b >> 1;
02348 const cln::cl_I m = cln::mod(a, b);
02349 const cln::cl_I m_b = m - b;
02350 const cln::cl_I ret = m > b2 ? m_b : m;
02351 return numeric(ret);
02352 } else
02353 return *_num0_p;
02354 }
02355
02356
02364 const numeric irem(const numeric &a, const numeric &b)
02365 {
02366 if (b.is_zero())
02367 throw std::overflow_error("numeric::irem(): division by zero");
02368 if (a.is_integer() && b.is_integer())
02369 return numeric(cln::rem(cln::the<cln::cl_I>(a.to_cl_N()),
02370 cln::the<cln::cl_I>(b.to_cl_N())));
02371 else
02372 return *_num0_p;
02373 }
02374
02375
02384 const numeric irem(const numeric &a, const numeric &b, numeric &q)
02385 {
02386 if (b.is_zero())
02387 throw std::overflow_error("numeric::irem(): division by zero");
02388 if (a.is_integer() && b.is_integer()) {
02389 const cln::cl_I_div_t rem_quo = cln::truncate2(cln::the<cln::cl_I>(a.to_cl_N()),
02390 cln::the<cln::cl_I>(b.to_cl_N()));
02391 q = numeric(rem_quo.quotient);
02392 return numeric(rem_quo.remainder);
02393 } else {
02394 q = *_num0_p;
02395 return *_num0_p;
02396 }
02397 }
02398
02399
02405 const numeric iquo(const numeric &a, const numeric &b)
02406 {
02407 if (b.is_zero())
02408 throw std::overflow_error("numeric::iquo(): division by zero");
02409 if (a.is_integer() && b.is_integer())
02410 return numeric(cln::truncate1(cln::the<cln::cl_I>(a.to_cl_N()),
02411 cln::the<cln::cl_I>(b.to_cl_N())));
02412 else
02413 return *_num0_p;
02414 }
02415
02416
02424 const numeric iquo(const numeric &a, const numeric &b, numeric &r)
02425 {
02426 if (b.is_zero())
02427 throw std::overflow_error("numeric::iquo(): division by zero");
02428 if (a.is_integer() && b.is_integer()) {
02429 const cln::cl_I_div_t rem_quo = cln::truncate2(cln::the<cln::cl_I>(a.to_cl_N()),
02430 cln::the<cln::cl_I>(b.to_cl_N()));
02431 r = numeric(rem_quo.remainder);
02432 return numeric(rem_quo.quotient);
02433 } else {
02434 r = *_num0_p;
02435 return *_num0_p;
02436 }
02437 }
02438
02439
02444 const numeric gcd(const numeric &a, const numeric &b)
02445 {
02446 if (a.is_integer() && b.is_integer())
02447 return numeric(cln::gcd(cln::the<cln::cl_I>(a.to_cl_N()),
02448 cln::the<cln::cl_I>(b.to_cl_N())));
02449 else
02450 return *_num1_p;
02451 }
02452
02453
02458 const numeric lcm(const numeric &a, const numeric &b)
02459 {
02460 if (a.is_integer() && b.is_integer())
02461 return numeric(cln::lcm(cln::the<cln::cl_I>(a.to_cl_N()),
02462 cln::the<cln::cl_I>(b.to_cl_N())));
02463 else
02464 return a.mul(b);
02465 }
02466
02467
02476 const numeric sqrt(const numeric &x)
02477 {
02478 return numeric(cln::sqrt(x.to_cl_N()));
02479 }
02480
02481
02483 const numeric isqrt(const numeric &x)
02484 {
02485 if (x.is_integer()) {
02486 cln::cl_I root;
02487 cln::isqrt(cln::the<cln::cl_I>(x.to_cl_N()), &root);
02488 return numeric(root);
02489 } else
02490 return *_num0_p;
02491 }
02492
02493
02495 ex PiEvalf()
02496 {
02497 return numeric(cln::pi(cln::default_float_format));
02498 }
02499
02500
02502 ex EulerEvalf()
02503 {
02504 return numeric(cln::eulerconst(cln::default_float_format));
02505 }
02506
02507
02509 ex CatalanEvalf()
02510 {
02511 return numeric(cln::catalanconst(cln::default_float_format));
02512 }
02513
02514
02516 _numeric_digits::_numeric_digits()
02517 : digits(17)
02518 {
02519
02520
02521
02522 if (too_late)
02523 throw(std::runtime_error("I told you not to do instantiate me!"));
02524 too_late = true;
02525 cln::default_float_format = cln::float_format(17);
02526
02527
02528
02529 }
02530
02531
02533 _numeric_digits& _numeric_digits::operator=(long prec)
02534 {
02535 long digitsdiff = prec - digits;
02536 digits = prec;
02537 cln::default_float_format = cln::float_format(prec);
02538
02539
02540 std::vector<digits_changed_callback>::const_iterator it = callbacklist.begin(), end = callbacklist.end();
02541 for (; it != end; ++it) {
02542 (*it)(digitsdiff);
02543 }
02544
02545 return *this;
02546 }
02547
02548
02550 _numeric_digits::operator long()
02551 {
02552
02553 return (long)digits;
02554 }
02555
02556
02558 void _numeric_digits::print(std::ostream &os) const
02559 {
02560 os << digits;
02561 }
02562
02563
02565 void _numeric_digits::add_callback(digits_changed_callback callback)
02566 {
02567 callbacklist.push_back(callback);
02568 }
02569
02570
02571 std::ostream& operator<<(std::ostream &os, const _numeric_digits &e)
02572 {
02573 e.print(os);
02574 return os;
02575 }
02576
02578
02580
02581
02582
02583 bool _numeric_digits::too_late = false;
02584
02585
02588 _numeric_digits Digits;
02589
02590 }