]> www.ginac.de Git - ginac.git/blobdiff - ginac/numeric.h
Remove 'level' argument of evalf().
[ginac.git] / ginac / numeric.h
index c56c56bd84dee5ae85715c7ca70ee0879d218ee3..115987eccef56e5a2dd00528d68521a1e1eb6810 100644 (file)
@@ -3,7 +3,7 @@
  *  Makes the interface to the underlying bignum package available. */
 
 /*
- *  GiNaC Copyright (C) 1999-2003 Johannes Gutenberg University Mainz, Germany
+ *  GiNaC Copyright (C) 1999-2016 Johannes Gutenberg University Mainz, Germany
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#ifndef __GINAC_NUMERIC_H__
-#define __GINAC_NUMERIC_H__
+#ifndef GINAC_NUMERIC_H
+#define GINAC_NUMERIC_H
 
 #include "basic.h"
 #include "ex.h"
+#include "archive.h"
 
-#include <cln/number.h>
-// forward decln of cln::cl_N, since cln/complex_class.h is not included:
-namespace cln { class cl_N; }
-
-#if defined(G__CINTVERSION) && !defined(__MAKECINT__)
-// Cint @$#$! doesn't like forward declaring classes used for casting operators
-// so we have to include the definition of cln::cl_N here, but it is enough to
-// do so for the compiler, hence the !defined(__MAKECINT__).
-  #include <cln/complex_class.h>
-#endif
+#include <cln/complex.h>
+#include <stdexcept>
+#include <vector>
 
 namespace GiNaC {
 
+/** Function pointer to implement callbacks in the case 'Digits' gets changed.
+ *  Main purpose of such callbacks is to adjust look-up tables of certain
+ *  functions to the new precision. Parameter contains the signed difference
+ *  between new Digits and old Digits. */
+typedef void (* digits_changed_callback)(long);
+
 /** This class is used to instantiate a global singleton object Digits
  *  which behaves just like Maple's Digits.  We need an object rather 
  *  than a dumber basic type since as a side-effect we let it change
  *  cl_default_float_format when it gets changed.  The only other
  *  meaningful thing to do with it is converting it to an unsigned,
- *  for temprary storing its value e.g.  The user must not create an
+ *  for temporarily storing its value e.g.  The user must not create an
  *  own working object of this class!  Since C++ forces us to make the
  *  class definition visible in order to use an object we put in a
  *  flag which prevents other objects of that class to be created. */
@@ -55,13 +55,27 @@ public:
        _numeric_digits();
        _numeric_digits& operator=(long prec);
        operator long();
-       void print(std::ostream &os) const;
+       void print(std::ostream& os) const;
+       void add_callback(digits_changed_callback callback);
 // member variables
 private:
        long digits;                        ///< Number of decimal digits
        static bool too_late;               ///< Already one object present
+       // Holds a list of functions that get called when digits is changed.
+       std::vector<digits_changed_callback> callbacklist;
 };
 
+
+/** Exception class thrown when a singularity is encountered. */
+class pole_error : public std::domain_error {
+public:
+       explicit pole_error(const std::string& what_arg, int degree);
+       int degree() const;
+private:
+       int deg;
+};
+
+
 /** This class is a wrapper around CLN-numbers within the GiNaC class
  *  hierarchy. Objects of this type may directly be created by the user.*/
 class numeric : public basic
@@ -70,7 +84,7 @@ class numeric : public basic
        
 // member functions
        
-       // other ctors
+       // other constructors
 public:
        numeric(int i);
        numeric(unsigned int i);
@@ -82,26 +96,35 @@ public:
        
        // functions overriding virtual functions from base classes
 public:
-       void print(const print_context & c, unsigned level = 0) const;
-       unsigned precedence(void) const {return 30;}
-       bool info(unsigned inf) const;
-       int degree(const ex & s) const;
-       int ldegree(const ex & s) const;
-       ex coeff(const ex & s, int n = 1) const;
-       bool has(const ex &other) const;
-       ex eval(int level = 0) const;
-       ex evalf(int level = 0) const;
-       ex normal(lst &sym_lst, lst &repl_lst, int level = 0) const;
-       ex to_rational(lst &repl_lst) const;
-       numeric integer_content(void) const;
-       ex smod(const numeric &xi) const;
-       numeric max_coefficient(void) const;
+       unsigned precedence() const override {return 30;}
+       bool info(unsigned inf) const override;
+       bool is_polynomial(const ex & var) const override;
+       int degree(const ex & s) const override;
+       int ldegree(const ex & s) const override;
+       ex coeff(const ex & s, int n = 1) const override;
+       bool has(const ex &other, unsigned options = 0) const override;
+       ex eval() const override;
+       ex evalf() const override;
+       ex subs(const exmap & m, unsigned options = 0) const override { return subs_one_level(m, options); } // overwrites basic::subs() for performance reasons
+       ex normal(exmap & repl, exmap & rev_lookup, int level = 0) const override;
+       ex to_rational(exmap & repl) const override;
+       ex to_polynomial(exmap & repl) const override;
+       numeric integer_content() const override;
+       ex smod(const numeric &xi) const override;
+       numeric max_coefficient() const override;
+       ex conjugate() const override;
+       ex real_part() const override;
+       ex imag_part() const override;
+       /** Save (a.k.a. serialize) object into archive. */
+       void archive(archive_node& n) const override;
+       /** Read (a.k.a. deserialize) object from archive. */
+       void read_archive(const archive_node& n, lst& syms) override;
 protected:
        /** Implementation of ex::diff for a numeric always returns 0.
         *  @see ex::diff */
-       ex derivative(const symbol &s) const { return 0; }
-       bool is_equal_same_type(const basic &other) const;
-       unsigned calchash(void) const;
+       ex derivative(const symbol &s) const override { return 0; }
+       bool is_equal_same_type(const basic &other) const override;
+       unsigned calchash() const override;
        
        // new virtual functions which can be overridden by derived classes
        // (none)
@@ -124,55 +147,64 @@ public:
        const numeric & operator=(unsigned long i);
        const numeric & operator=(double d);
        const numeric & operator=(const char *s);
-       const numeric inverse(void) const;
-       int csgn(void) const;
+       const numeric inverse() const;
+       numeric step() const;
+       int csgn() const;
        int compare(const numeric &other) const;
        bool is_equal(const numeric &other) const;
-       bool is_zero(void) const;
-       bool is_positive(void) const;
-       bool is_negative(void) const;
-       bool is_integer(void) const;
-       bool is_pos_integer(void) const;
-       bool is_nonneg_integer(void) const;
-       bool is_even(void) const;
-       bool is_odd(void) const;
-       bool is_prime(void) const;
-       bool is_rational(void) const;
-       bool is_real(void) const;
-       bool is_cinteger(void) const;
-       bool is_crational(void) const;
+       bool is_zero() const;
+       bool is_positive() const;
+       bool is_negative() const;
+       bool is_integer() const;
+       bool is_pos_integer() const;
+       bool is_nonneg_integer() const;
+       bool is_even() const;
+       bool is_odd() const;
+       bool is_prime() const;
+       bool is_rational() const;
+       bool is_real() const;
+       bool is_cinteger() const;
+       bool is_crational() const;
        bool operator==(const numeric &other) const;
        bool operator!=(const numeric &other) const;
        bool operator<(const numeric &other) const;
        bool operator<=(const numeric &other) const;
        bool operator>(const numeric &other) const;
        bool operator>=(const numeric &other) const;
-       int to_int(void) const;
-       long to_long(void) const;
-       double to_double(void) const;
-       cln::cl_N to_cl_N(void) const;
-       const numeric real(void) const;
-       const numeric imag(void) const;
-       const numeric numer(void) const;
-       const numeric denom(void) const;
-       int int_length(void) const;
+       int to_int() const;
+       long to_long() const;
+       double to_double() const;
+       cln::cl_N to_cl_N() const;
+       const numeric real() const;
+       const numeric imag() const;
+       const numeric numer() const;
+       const numeric denom() const;
+       int int_length() const;
        // converting routines for interfacing with CLN:
-       numeric(const cln::cl_N &z);
+       explicit numeric(const cln::cl_N &z);
+
+protected:
+       void 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;
+       void do_print(const print_context & c, unsigned level) const;
+       void do_print_latex(const print_latex & c, unsigned level) const;
+       void do_print_csrc(const print_csrc & c, unsigned level) const;
+       void do_print_csrc_cl_N(const print_csrc_cl_N & c, unsigned level) const;
+       void do_print_tree(const print_tree & c, unsigned level) const;
+       void do_print_python_repr(const print_python_repr & c, unsigned level) const;
 
 // member variables
 
 protected:
-       cln::cl_number value;
+       cln::cl_N value;
 };
+GINAC_DECLARE_UNARCHIVER(numeric); 
+
 
 // global constants
 
 extern const numeric I;
 extern _numeric_digits Digits;
 
-// deprecated macro, for internal use only
-#define is_a_numeric_hash(x) ((x)&0x80000000U)
-
 // global functions
 
 const numeric exp(const numeric &x);
@@ -220,6 +252,9 @@ inline const numeric pow(const numeric &x, const numeric &y)
 inline const numeric inverse(const numeric &x)
 { return x.inverse(); }
 
+inline numeric step(const numeric &x)
+{ return x.step(); }
+
 inline int csgn(const numeric &x)
 { return x.csgn(); }
 
@@ -229,6 +264,9 @@ inline bool is_zero(const numeric &x)
 inline bool is_positive(const numeric &x)
 { return x.is_positive(); }
 
+inline bool is_negative(const numeric &x)
+{ return x.is_negative(); }
+
 inline bool is_integer(const numeric &x)
 { return x.is_integer(); }
 
@@ -282,24 +320,11 @@ inline const numeric denom(const numeric &x)
 
 // numeric evaluation functions for class constant objects:
 
-ex PiEvalf(void);
-ex EulerEvalf(void);
-ex CatalanEvalf(void);
+ex PiEvalf();
+ex EulerEvalf();
+ex CatalanEvalf();
 
 
-// utility functions
-
-/** Specialization of is_exactly_a<numeric>(obj) for numeric objects. */
-template<> inline bool is_exactly_a<numeric>(const basic & obj)
-{
-       return obj.tinfo()==TINFO_numeric;
-}
-
 } // namespace GiNaC
 
-#ifdef __MAKECINT__
-#pragma link off defined_in cln/number.h;
-#pragma link off defined_in cln/complex_class.h;
-#endif
-
-#endif // ndef __GINAC_NUMERIC_H__
+#endif // ndef GINAC_NUMERIC_H