1 // -*- mode:C++ ; compile-command: "g++ -I.. -g -c -DHAVE_CONFIG_H -DIN_GIAC gen.cc" -*- 2 /* 3 * Copyright (C) 2001,2014 B. Parisse, Institut Fourier, 38402 St Martin d'Heres 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 #ifndef _GIAC_GEN_H 19 #define _GIAC_GEN_H 20 #ifdef KHICAS 21 extern size_t stackptr; 22 #endif 23 24 /* Warning: the size of a gen depend on the architecture and of compile-time flags 25 Define -DSMARTPTR64 on 64 bit CPU if the pointers allocated by new are 48 bits 26 this will make sizeof(gen)==8 instead of 16 27 Currently the address of pointers is obtained by using the reserved and val fields 28 (48 bits) and adding 00 for the most significant bits 29 On systems that use pointers above 0x00ffffffff it might be better to use a table 30 of most significants 32 bits addresses (refered by the reserved field) 31 and use the val field for offset. 32 Define -DDOUBLEVAL if you did not define SMARTPTR64 and want full double precision 33 (53 bit mantissa). Otherwise, the 8 less significant bits will be used for the type 34 field of a gen, i.e. 0x01 for a double, hence 45 bit mantissa will be used for doubles 35 Using full double precision increases sizeof(gen) to 12 on a 32 bits CPU 36 (and 16 on a 64 bits CPU) 37 */ 38 39 // FIXME: macros defined in config.h are not welcome in a public header! 40 #ifdef HAVE_CONFIG_H 41 #include "config.h" 42 #endif 43 #include "first.h" 44 45 // #include <gmp.h> 46 #ifdef USE_GMP_REPLACEMENTS 47 #undef HAVE_GMPXX_H 48 #undef HAVE_LIBMPFR 49 #endif 50 #ifdef HAVE_GMPXX_H 51 #include <gmpxx.h> 52 #endif 53 #ifdef HAVE_LIBMPFR 54 #include <mpfr.h> 55 // #include <mpf2mpfr.h> 56 #endif 57 #ifdef HAVE_LIBMPFI 58 #include <mpfi.h> 59 #endif 60 #include <iostream> 61 #include <string> 62 #include "vector.h" 63 #include <map> 64 #include "dispatch.h" 65 #include "vecteur.h" 66 #include "fraction.h" 67 #include "poly.h" 68 #include "giacintl.h" 69 #include <complex> 70 #include <stdlib.h> 71 #ifdef STATIC_BUILTIN_LEXER_FUNCTIONS 72 #include "static.h" 73 #endif 74 75 #ifndef NO_NAMESPACE_GIAC 76 namespace giac { 77 #endif // ndef NO_NAMESPACE_GIAC 78 79 int sprint_int(char * s,int r); 80 void sprint_double(char * s,double d); 81 82 #ifdef USE_GMP_REPLACEMENTS 83 #undef HAVE_GMPXX_H 84 #undef HAVE_LIBMPFR 85 #endif 86 87 void my_mpz_gcd(mpz_t &z,const mpz_t & A,const mpz_t & B); 88 89 class gen ; 90 // errors 91 void settypeerr(GIAC_CONTEXT0); 92 void setsizeerr(GIAC_CONTEXT0); 93 void setdimerr(GIAC_CONTEXT0); 94 void settypeerr(const std::string & s); 95 void setsizeerr(const std::string & s); 96 void setdimerr(const std::string & s); 97 void divisionby0err(const gen &,GIAC_CONTEXT0); 98 void cksignerr(const gen &,GIAC_CONTEXT0); 99 void invalidserieserr(const std::string &,GIAC_CONTEXT0); 100 void toofewargs(const std::string & s,GIAC_CONTEXT0); 101 void toomanyargs(const std::string & s,GIAC_CONTEXT0); 102 void maxordererr(GIAC_CONTEXT0); 103 void setstabilityerr(GIAC_CONTEXT0); 104 105 gen undeferr(const std::string & s); 106 gen gentypeerr(GIAC_CONTEXT0); 107 void gentypeerr(gen & g,GIAC_CONTEXT); 108 gen gensizeerr(GIAC_CONTEXT0); 109 void gensizeerr(gen & g,GIAC_CONTEXT); 110 gen gendimerr(GIAC_CONTEXT0); 111 void gendimerr(gen & g,GIAC_CONTEXT); 112 gen gentypeerr(const std::string & s); 113 void gentypeerr(const char * ch,gen & g); 114 gen gensizeerr(const std::string & s); 115 void gensizeerr(const char * ch,gen & g); 116 gen gendimerr(const std::string & s); 117 void gensizeerr(const char * ch,gen & g); 118 gen gendivisionby0err(const gen &,GIAC_CONTEXT0); 119 gen gencksignerr(const gen &,GIAC_CONTEXT0); 120 gen geninvalidserieserr(const std::string &,GIAC_CONTEXT0); 121 gen gentoofewargs(const std::string & s,GIAC_CONTEXT0); 122 gen gentoomanyargs(const std::string & s,GIAC_CONTEXT0); 123 gen genmaxordererr(GIAC_CONTEXT0); 124 gen genstabilityerr(GIAC_CONTEXT0); 125 126 // short integer arithmetic 127 int absint(int a); 128 double absdouble(double a); 129 int giacmin(int a,int b); 130 int giacmax(int a,int b); 131 int invmod(int n,int modulo); 132 unsigned invmod(unsigned a,int b); 133 int invmod(longlong a,int b); 134 longlong invmodll(longlong a,longlong b); 135 #ifdef INT128 136 int invmod(int128_t a,int b); smod(int128_t r,int m)137 inline int smod(int128_t r,int m){ 138 int R=r%m; 139 return smod(R,m); 140 } 141 #endif 142 int gcd(int a,int b); smod_adjust(int r,int m)143 inline int smod_adjust(int r,int m){ // precondition -m<r<m 144 r += (unsigned(r)>>31)*m; // make positive 145 return r-(unsigned((m>>1)-r)>>31)*m; 146 } 147 int smod(int a,int b); // where b is assumed to be positive 148 int smod(longlong a,int b); 149 longlong smodll(longlong res,longlong m); 150 int simplify(int & a,int & b); 151 152 struct ref_mpz_t { 153 volatile ref_count_t ref_count; 154 mpz_t z; ref_mpz_tref_mpz_t155 ref_mpz_t():ref_count(1) {mpz_init(z);} ref_mpz_tref_mpz_t156 ref_mpz_t(size_t nbits):ref_count(1) {mpz_init2(z,int(nbits));} ref_mpz_tref_mpz_t157 ref_mpz_t(const mpz_t & Z): ref_count(1) { mpz_init_set(z,Z); } ~ref_mpz_tref_mpz_t158 ~ref_mpz_t() { mpz_clear(z); } 159 }; 160 class identificateur; 161 struct ref_identificateur; // in identificateur.h 162 struct symbolic; 163 struct ref_symbolic; // in symbolic.h 164 class unary_function_eval; 165 struct unary_function_ptr; 166 typedef const unary_function_ptr * const_unary_function_ptr_ptr; 167 typedef const unary_function_eval * const_unary_function_eval_ptr; 168 struct ref_unary_function_ptr; // in unary.h 169 struct eqwdata; 170 struct ref_eqwdata ; // defined below after gen 171 struct ref_complex; 172 struct ref_algext; 173 struct ref_modulo; 174 // Graphic object 175 struct grob { 176 void (* grob_draw)(void); 177 int (* grob_handle) (int); 178 void * grob_data; 179 }; 180 struct ref_grob { 181 volatile ref_count_t ref_count; 182 grob g; ref_grobref_grob183 ref_grob(const grob & G):ref_count(1),g(G) {} 184 }; 185 class gen_user; 186 struct ref_gen_user ; // user defined type 187 struct ref_string { 188 volatile ref_count_t ref_count; 189 std::string s; ref_stringref_string190 ref_string(const std::string & S):ref_count(1),s(S) {} 191 }; 192 template <class T> class tensor; 193 194 typedef tensor<gen> polynome; 195 typedef std::vector< facteur< polynome > > factorization; 196 197 template<class T> class Tref_tensor; // in poly.h 198 typedef Tref_tensor<gen> ref_polynome; 199 typedef Tfraction<gen> fraction; 200 template<class T> class Tref_fraction; 201 typedef Tref_fraction<gen> ref_fraction; 202 203 struct ref_vecteur; 204 void delete_ref_vecteur(ref_vecteur * ptr); 205 ref_vecteur * new_ref_vecteur(const vecteur & v); 206 ref_symbolic * new_ref_symbolic(const symbolic & s); 207 208 template<class T> class Tref_fraction; // in fraction.h 209 struct ref_void_pointer { 210 volatile ref_count_t ref_count; 211 void * p; ref_void_pointerref_void_pointer212 ref_void_pointer(void * P):ref_count(1),p(P) {} 213 }; 214 215 216 struct monome; 217 // sparse polynomials: uncomment one of the 2 next lines 218 #ifdef DEBUG_SUPPORT 219 typedef dbgprint_vector<monome> sparse_poly1; // debugging support 220 #else 221 typedef std::vector<monome> sparse_poly1; // no debug. support 222 #endif 223 struct ref_sparse_poly1; 224 225 // arbitrary precision floats hierarchy (value or interval) 226 std::string printmpf_t(const mpf_t & inf); 227 class real_object { 228 public: 229 #ifdef HAVE_LIBMPFR 230 mpfr_t inf; 231 #else 232 mpf_t inf; 233 #endif 234 real_object(double d); 235 #ifdef HAVE_LIBMPFR 236 real_object(const mpfr_t & d); 237 real_object(const mpf_t & d); 238 #else 239 real_object(const mpf_t & d); 240 #endif 241 real_object(const gen & g); 242 real_object(const gen & g,unsigned int precision); 243 real_object() ; 244 virtual std::string print(GIAC_CONTEXT) const; dbgprint()245 const char * dbgprint() const { 246 static std::string s; 247 s=this->print(0); 248 #if 0 // ndef NSPIRE 249 CERR << s << '\n'; 250 #endif 251 return s.c_str(); 252 } ~real_object()253 virtual ~real_object() { 254 #ifdef HAVE_LIBMPFR 255 mpfr_clear(inf); 256 #else 257 mpf_clear(inf); 258 #endif 259 } 260 virtual real_object & operator = (const real_object & g); 261 real_object (const real_object & g) ; 262 virtual gen addition (const gen & g,GIAC_CONTEXT) const; 263 gen operator + (const gen & g) const; 264 virtual gen operator + (const real_object & g) const; 265 virtual gen multiply (const gen & g,GIAC_CONTEXT) const; 266 gen operator * (const gen & g) const; 267 virtual gen operator * (const real_object & g) const; 268 virtual gen divide (const gen & g,GIAC_CONTEXT) const; 269 gen operator / (const gen & g) const; 270 virtual gen substract (const gen & g,GIAC_CONTEXT) const; 271 virtual gen operator / (const real_object & g) const; 272 gen operator - (const gen & g) const; 273 virtual gen operator - (const real_object & g) const; 274 virtual gen operator -() const; 275 virtual gen inv() const; 276 virtual gen sqrt() const; 277 virtual gen abs() const; 278 virtual gen exp() const; 279 virtual gen log() const; 280 virtual gen sin() const; 281 virtual gen cos() const; 282 virtual gen tan() const; 283 virtual gen sinh() const; 284 virtual gen cosh() const; 285 virtual gen tanh() const; 286 virtual gen asin() const; 287 virtual gen acos() const; 288 virtual gen atan() const; 289 virtual gen asinh() const; 290 virtual gen acosh() const; 291 virtual gen atanh() const; 292 virtual bool is_zero() const; 293 virtual bool maybe_zero() const; 294 virtual bool is_inf() const; 295 virtual bool is_nan() const; 296 virtual int is_positive() const; 297 virtual double evalf_double() const; 298 }; 299 struct ref_real_object { 300 volatile ref_count_t ref_count; 301 real_object r; ref_real_objectref_real_object302 ref_real_object():ref_count(1) {} ref_real_objectref_real_object303 ref_real_object(const real_object & R):ref_count(1),r(R) {} 304 }; 305 gen real2int(const gen & g,GIAC_CONTEXT); 306 gen real2double(const gen & g); 307 class real_interval : public real_object { 308 public: 309 #ifdef HAVE_LIBMPFI 310 mpfi_t infsup; 311 #else 312 #ifdef HAVE_LIBMPFR 313 mpfr_t sup; 314 #else 315 mpf_t sup; 316 #endif 317 #endif real_interval()318 real_interval(){ 319 #ifdef HAVE_LIBMPFI 320 mpfi_init_set_fr(infsup,inf); 321 #else 322 #ifdef HAVE_LIBMPFR 323 mpfr_init_set(sup,inf,GMP_RNDN); 324 #else 325 mpf_init_set(sup,inf); 326 #endif 327 #endif 328 } 329 #ifdef HAVE_LIBMPFI 330 real_interval(const mpfi_t & interv); 331 #endif real_interval(const real_object & r)332 real_interval(const real_object & r):real_object(r) { 333 #ifdef HAVE_LIBMPFI 334 mpfi_init2(infsup,mpfr_get_prec(r.inf)); 335 mpfi_set_fr(infsup,r.inf); 336 #else 337 #ifdef HAVE_LIBMPFR 338 mpfr_init_set(sup,r.inf,GMP_RNDN); 339 #else 340 mpf_init_set(sup,r.inf); 341 #endif 342 #endif 343 } real_interval(const real_interval & r)344 real_interval(const real_interval & r):real_object(r) { 345 #ifdef HAVE_LIBMPFI 346 mpfi_init2(infsup,mpfi_get_prec(r.infsup)); 347 mpfi_set(infsup,r.infsup); 348 #else 349 #ifdef HAVE_LIBMPFR 350 mpfr_init_set(sup,r.sup,GMP_RNDN); 351 #else 352 mpf_init_set(sup,r.sup); 353 #endif 354 #endif 355 } ~real_interval()356 virtual ~real_interval() { 357 #ifdef HAVE_LIBMPFI 358 mpfi_clear(infsup); 359 #else 360 #ifdef HAVE_LIBMPFR 361 mpfr_clear(sup); 362 #else 363 mpf_clear(sup); 364 #endif 365 #endif 366 } 367 virtual real_object & operator = (const real_interval & g) ; 368 virtual real_object & operator = (const real_object & g) ; 369 virtual gen addition (const gen & g,GIAC_CONTEXT) const; 370 virtual gen operator + (const real_object & g) const; 371 virtual real_interval operator + (const real_interval & g) const; 372 virtual gen multiply (const gen & g,GIAC_CONTEXT) const; 373 virtual gen operator * (const real_object & g) const; 374 virtual real_interval operator * (const real_interval & g) const; 375 virtual gen divide (const gen & g,GIAC_CONTEXT) const; 376 virtual gen substract (const gen & g,GIAC_CONTEXT) const; 377 virtual gen operator - (const real_object & g) const; 378 virtual real_interval operator - (const real_interval & g) const ; 379 virtual gen operator -() const; 380 virtual bool is_zero () const ; 381 virtual bool maybe_zero () const ; 382 virtual int is_positive() const ; 383 virtual bool is_inf() const; 384 virtual bool is_nan() const; 385 virtual gen inv() const; 386 virtual gen sqrt() const; 387 virtual gen abs() const; 388 virtual gen exp() const; 389 virtual gen log() const; 390 virtual gen sin() const; 391 virtual gen cos() const; 392 virtual gen tan() const; 393 virtual gen sinh() const; 394 virtual gen cosh() const; 395 virtual gen tanh() const; 396 virtual gen asin() const; 397 virtual gen acos() const; 398 virtual gen atan() const; 399 virtual gen asinh() const; 400 virtual gen acosh() const; 401 virtual gen atanh() const; 402 }; 403 struct ref_real_interval { 404 volatile ref_count_t ref_count; 405 real_interval r; // assumes that storage of real_object inside real_interval is first ref_real_intervalref_real_interval406 ref_real_interval():ref_count(1) {} ref_real_intervalref_real_interval407 ref_real_interval(const real_interval & R):ref_count(1),r(R) {} 408 }; 409 std::string print_binary(const real_object & r); 410 gen read_binary(const std::string & s,unsigned int precision); 411 // Convert g to a real or complex object of precision nbits 412 gen accurate_evalf(const gen & g,int nbits); 413 vecteur accurate_evalf(const vecteur & v,int nbits); 414 std::string print_DOUBLE_(double d,GIAC_CONTEXT); 415 416 #if 1 // def NSPIRE 417 class comparegen { 418 public: 419 bool operator () (const gen & a,const gen & b) const; 420 }; 421 typedef std::map<gen,gen,comparegen> gen_map; 422 #else 423 typedef std::map<gen,gen,const std::pointer_to_binary_function < const gen &, const gen &, bool> > gen_map; 424 #endif 425 struct ref_gen_map; 426 427 class my_mpz; 428 429 #ifdef NO_UNARY_FUNCTION_COMPOSE 430 class unary_function_eval; 431 #else 432 class unary_function_abstract; 433 #endif 434 435 struct alias_unary_function_eval; 436 struct unary_function_ptr { 437 #ifdef NO_UNARY_FUNCTION_COMPOSE 438 // const unary_function_eval * _ptr; 439 size_t _ptr; 440 // int quoted; // will be used to avoid evaluation of args by eval 441 // constructors 442 // lexer_register is true to add dynamically the function name 443 // to the list of functions names recognized by the lexer unary_function_ptrunary_function_ptr444 unary_function_ptr():_ptr(0) {} ; unary_function_ptrunary_function_ptr445 unary_function_ptr(const unary_function_eval * myptr):_ptr((size_t)myptr) {} ; 446 // unary_function_ptr(const unary_function_eval * myptr,int parser_token); 447 unary_function_ptr(const unary_function_eval * myptr,int myquoted,int parser_token); 448 // unary_function_ptr(const alias_unary_function_eval * myptr,int parser_token); 449 unary_function_ptr(const alias_unary_function_eval * myptr,int myquoted,int parser_token); 450 #else // NO_UNARY_FUNCTION_COMPOSE 451 const unary_function_abstract * _ptr; 452 // long * ref_count; 453 // int quoted; // will be used to avoid evaluation of args by eval 454 // constructors 455 // lexer_register is true to add dynamically the function name 456 // to the list of functions names recognized by the lexer 457 // unary_function_ptr(const unary_function_abstract & myptr); 458 unary_function_ptr():_ptr(0) {} ; 459 unary_function_ptr(const unary_function_abstract * myptr):_ptr(myptr) {} ; 460 // unary_function_ptr(const unary_function_abstract * myptr,int parser_token) ; 461 // unary_function_ptr(const unary_function_abstract & myptr,int myquoted,int parser_token=0); 462 unary_function_ptr(const unary_function_abstract * myptr,int myquoted,int parser_token); 463 // unary_function_ptr(const unary_function_ptr & myptr); 464 // unary_function_ptr(const alias_unary_function_eval * myptr,int parser_token); 465 unary_function_ptr(const alias_unary_function_eval * myptr,int myquoted,int parser_token); 466 #endif // NO_UNARY_FUNCTION_COMPOSE 467 // ~unary_function_ptr(); 468 // unary_function_ptr & operator = (const unary_function_ptr & acopier); 469 gen operator () (const gen & arg,GIAC_CONTEXT) const; 470 #ifdef NO_UNARY_FUNCTION_COMPOSE ptrunary_function_ptr471 inline unary_function_eval * ptr() const { 472 return (unary_function_eval *) (((size_t) _ptr) & ~(uintptr_t)3); 473 #ifdef x86_64 474 //return (unary_function_eval *) (((ulonglong ) _ptr) & 0xfffffffffffffffc); 475 #else 476 //return (unary_function_eval *) (((size_t) _ptr) & 0xfffffffc); 477 #endif 478 } 479 #else // NO_UNARY_FUNCTION_COMPOSE ptrunary_function_ptr480 inline unary_function_abstract * ptr () const 481 { 482 return (unary_function_abstract *) (((ulonglong ) _ptr) & ~(uintptr_t)3); 483 #ifdef x86_64 484 return (unary_function_abstract *) (((ulonglong ) _ptr) & 0xfffffffffffffffc); 485 #else 486 return (unary_function_abstract *) (((size_t) _ptr) & 0xfffffffc); 487 #endif 488 } 489 #endif // NO_UNARY_FUNCTION_COMPOSE 490 bool quoted() const ; 491 inline bool operator ==(const unary_function_ptr & u) const { 492 // if (&u==this) return true; 493 return ((ulonglong)(_ptr) & ~(uintptr_t)3 ) == ((ulonglong)( u._ptr) & ~(uintptr_t)3 ); 494 #ifdef x86_64 495 //return ((ulonglong)(_ptr) & 0xfffffffffffffffc) == ((ulonglong)( u._ptr) & 0xfffffffffffffffc ); 496 #else 497 //return ((size_t)(_ptr) & 0xfffffffc) == ((size_t)(u._ptr) & 0xfffffffc); 498 #endif 499 } 500 inline bool operator !=(const unary_function_ptr & u) const { return !(*this==u); } 501 inline bool operator ==(const unary_function_ptr * u) const { 502 // if (&u==this) return true; 503 return u && ( ((ulonglong)(_ptr) & ~(uintptr_t)3 ) == ((ulonglong)(u->_ptr) & ~(uintptr_t)3) ); 504 #ifdef x86_64 505 //return u && ( ((ulonglong)(_ptr) & 0xfffffffffffffffc) == ((ulonglong)(u->_ptr) & 0xfffffffffffffffc) ); 506 #else 507 //return u && ( ((size_t)(_ptr) & 0xfffffffc) == ((size_t)(u->_ptr) & 0xfffffffc ) ); 508 #endif 509 } 510 inline bool operator !=(const unary_function_ptr * u) const { return !(*this==u); } 511 const char * dbgprint() const; 512 }; 513 514 void delete_ptr(signed char subtype,short int type_save,ref_mpz_t * ptr_save); 515 // FIXME: for little-endian check if type/unused/subtype order is correct! 516 class gen { 517 public: 518 #ifdef GIAC_TYPE_ON_8BITS 519 unsigned char type; // see dispatch.h 520 #else 521 unsigned char type:5; // 32 types is enough, keep 3 bits more for double 522 unsigned char type_unused:3; 523 #endif 524 signed char subtype; 525 unsigned short reserved; // used if SMARTPTR is defined on 64 bit CPU (16 bits for pointer val) 526 union { 527 // immediate types 528 int val; // immediate int (type _INT_) 529 #ifdef DOUBLEVAL 530 double _DOUBLE_val; // immediate float (type _DOUBLE_) 531 giac_float _FLOAT_val; 532 #endif 533 #ifndef SMARTPTR64 534 // pointer types 535 ref_mpz_t * __ZINTptr; // long int (type _ZINT) 536 ref_real_object * __REALptr; // extended double (type _REAL) 537 ref_complex * __CPLXptr ; // complex as an gen[2] array (type _CPLX) 538 ref_identificateur * __IDNTptr; // global name identifier (type _IDNT) 539 ref_symbolic * __SYMBptr; // for symbolic objects (type _SYMB) 540 ref_modulo * __MODptr; 541 ref_algext * __EXTptr; // 2 gens for alg. extension (type ext) 542 // alg ext: 1st gen is a std::vector or a fraction, 2nd gen is 543 // a/ a std::vector, the minimal monic polynomial (the roots are permutable) 544 // b/ a real_complex_rootof given by it's min poly and 545 // c/ another type meaning that the root is expressed in terms 546 // of another rootof, in this case ext_reduce should be called 547 // For 2nd order extension, X^2=d is used if d!=1 mod 4 548 // X is the positive solution 549 // if d=1 mod 4 the equation is X^2-X=(d-1)/4 550 Tref_fraction<gen> * __FRACptr; // fraction (type _FRAC) 551 Tref_tensor<gen> * __POLYptr ; // multidim. sparse polynomials (type poly) 552 // _VECTosite types (std::vector<>) 553 ref_vecteur * __VECTptr ; // vecteur: std::vectors & dense_POLY1 (type _VECT) 554 ref_sparse_poly1 * __SPOL1ptr ; // std::vector<monome>: sparse 1-d poly (type _SPOL1) 555 ref_string * __STRNGptr; 556 size_t _FUNC_; 557 // ref_unary_function_ptr * __FUNCptr; 558 ref_gen_user * __USERptr; 559 ref_gen_map * __MAPptr; 560 ref_eqwdata * __EQWptr; 561 ref_grob * __GROBptr; 562 ref_void_pointer * __POINTERptr; 563 #endif 564 }; ref_count()565 inline volatile ref_count_t & ref_count() const { 566 #ifdef SMARTPTR64 567 return ((ref_mpz_t *) ((* (ulonglong *) (this))>>16))->ref_count; 568 #else 569 return __ZINTptr->ref_count; 570 #endif 571 } 572 #ifdef SMARTPTR64 gen()573 gen() { 574 * ((ulonglong * ) this)=0; 575 #if defined COMPILE_FOR_STABILITY && !defined(POCKETCAS) 576 control_c(); 577 #endif 578 }; 579 #else gen()580 gen(): type(_INT_),subtype(0),val(0) { 581 #if defined COMPILE_FOR_STABILITY && !defined(POCKETCAS) 582 control_c(); 583 #endif 584 }; 585 #endif 586 #ifdef SMARTPTR64 gen(void * ptr,short int subt)587 gen(void *ptr,short int subt) { 588 #ifdef COMPILE_FOR_STABILITY 589 control_c(); 590 #endif 591 ulonglong __POINTERptr = (ulonglong ) new ref_void_pointer(ptr); 592 #ifndef NO_STDEXCEPT 593 if (__POINTERptr & 0xffff000000000000) 594 setsizeerr(gettext("Pointer out of range")); 595 #endif 596 * ((ulonglong *) this) = __POINTERptr << 16; 597 subtype=(signed char)subt; 598 type=_POINTER_; 599 }; 600 #else gen(void * ptr,short int subt)601 gen(void *ptr,short int subt): type(_POINTER_),subtype(char(subt)) { 602 #ifdef COMPILE_FOR_STABILITY 603 control_c(); 604 #endif 605 __POINTERptr=new ref_void_pointer(ptr); 606 }; 607 #endif 608 #ifdef SMARTPTR64 gen(int i)609 gen(int i) { 610 * ((ulonglong * ) this)=0; 611 val=i; 612 #ifdef COMPILE_FOR_STABILITY 613 control_c(); 614 #endif 615 }; gen(size_t i)616 gen(size_t i) { 617 * ((ulonglong * ) this)=0; 618 val=int(i); 619 #ifdef COMPILE_FOR_STABILITY 620 control_c(); 621 #endif 622 }; 623 #else gen(int i)624 gen(int i): type(_INT_),subtype(0),val(i) { 625 #if defined COMPILE_FOR_STABILITY && !defined(POCKETCAS) 626 control_c(); 627 #endif 628 }; gen(size_t i)629 gen(size_t i): type(_INT_),subtype(0),val((int)i) { 630 #if defined COMPILE_FOR_STABILITY && !defined(POCKETCAS) 631 control_c(); 632 #endif 633 }; 634 #endif 635 gen(long i); 636 gen(longlong i); 637 gen(longlong i,int nbits); 638 #ifdef INT128 639 gen(int128_t i); 640 #endif 641 gen(const mpz_t & m); 642 // WARNING coerce *mptr to an int if possible, in this case delete mptr 643 // Pls do not use this constructor unless you know exactly what you do!! 644 gen(ref_mpz_t * mptr); 645 #ifdef DOUBLEVAL gen(double d)646 gen(double d): type(_DOUBLE_),_DOUBLE_val(d) {}; 647 #else 648 // may not work on ia64 with -O2 649 gen(double d); 650 #endif 651 gen(const giac_float & f); 652 #ifdef BCD 653 gen(accurate_bcd_float * b); 654 #endif 655 // inline 656 double DOUBLE_val() const ; 657 giac_float FLOAT_val() const ; 658 gen(int a,int b); 659 gen(double a,double b); 660 gen(const gen & a,const gen & b); 661 gen(const std::complex<double> & c); 662 gen(const gen & e); 663 gen (const identificateur & s); 664 gen (ref_identificateur * sptr); 665 gen (const vecteur & v,short int s=0); 666 gen (ref_vecteur * vptr,short int s=0); 667 // vptr must be a pointer allocated by new, do not delete it explicitly 668 gen (const symbolic & s); 669 gen (ref_symbolic * sptr); 670 gen (const gen_user & g); 671 gen (ref_gen_user * sptr); 672 gen (const real_object & g); 673 gen (const real_interval & g); 674 // Pls do not use this constructor unless you know exactly what you do 675 gen (Tref_tensor<gen> * pptr); 676 gen (const polynome & p); 677 gen (const fraction & p); 678 gen (const std::string & s,GIAC_CONTEXT); 679 gen (const wchar_t * s,GIAC_CONTEXT); gen(const char * s,GIAC_CONTEXT)680 gen (const char * s,GIAC_CONTEXT){ type=0; *this=gen(std::string(s),contextptr); }; 681 gen (const sparse_poly1 & p); 682 gen (const unary_function_ptr & f,int nargs=1); 683 gen (const unary_function_ptr * f,int nargs=1); 684 gen (const gen_map & m); 685 gen (const eqwdata & ); 686 gen (const grob & ); 687 #ifdef HAVE_GMPXX_H 688 gen (const mpz_class &); 689 #endif 690 gen (const my_mpz &); 691 void delete_gen(); ~gen()692 ~gen(){ 693 if ( type>_DOUBLE_ && type!=_FLOAT_ 694 #if !defined SMARTPTR64 // || defined STATIC_BUILTIN_LEXER_FUNCTIONS 695 && type!=_FUNC 696 #endif 697 ){ 698 // optimization for ref_count access must be checked in multi-thread 699 ref_count_t * rc=(ref_count_t *) & ref_count(); 700 if (*rc!=-1 && !--*rc){ 701 delete_gen(); 702 } 703 } 704 } 705 706 bool in_eval(int level,gen & evaled,const context * contextptr) const; eval(int level,const context * contextptr)707 inline gen eval(int level,const context * contextptr) const{ 708 // CERR << "eval " << *this << " " << level << '\n'; 709 gen res; 710 // return in_eval(level,res,contextptr)?res:*this; 711 if (in_eval(level,res,contextptr)) 712 return res; 713 else 714 return *this; 715 } 716 // inline gen eval() const { return eval(DEFAULT_EVAL_LEVEL,context0); } 717 bool in_evalf(int level,gen & evaled,const context * contextptr) const; 718 gen evalf(int level,const context * contextptr) const; 719 // inline gen evalf() const { return evalf(DEFAULT_EVAL_LEVEL,context0); } 720 gen evalf_double(int level,const context * contextptr) const ; 721 gen evalf2double(int level,const context * contextptr) const; 722 #if defined SMARTPTR64 723 gen & operator = (const gen & a){ 724 ulonglong al=*((ulonglong *) &a); 725 unsigned char atype=al&0x1f; 726 ulonglong tl=*((ulonglong *) this); 727 // Copy before deleting because the target might be embedded in a 728 // with a ptr_val.ref_count of a equals to 1 729 // short int type_save=type; // short int subtype_save=subtype; 730 * ((ulonglong *) this) = al; 731 if (atype>_DOUBLE_ && atype!=_FLOAT_ 732 && (al >> 16) ){ 733 ref_count_t * rc=(ref_count_t *)& ((ref_mpz_t *)(al>>16) )->ref_count; 734 if (*rc!=-1) 735 ++(*rc); // increase ref count 736 } 737 // Now we delete the target 738 if ( (tl &0x1f)>_DOUBLE_) 739 delete_ptr( (signed char) ((tl&0xff00)>>8),(tl &0x1f),(ref_mpz_t *) (tl >> 16)); 740 return *this; 741 } 742 743 #else // SMARTPTR64 744 gen & operator = (const gen & a){ 745 register unsigned t=(type << _DECALAGE) | a.type; 746 if (!t){ 747 subtype=a.subtype; 748 val=a.val; 749 return *this; 750 } 751 if (a.type>_DOUBLE_ && a.type!=_FLOAT_ 752 && a.type!=_FUNC && a.__ZINTptr 753 ){ 754 ref_count_t * rc=(ref_count_t *)&a.ref_count(); 755 if (*rc!=-1) 756 ++(*rc); // increase ref count 757 } 758 // Copy before deleting because the target might be embedded in a 759 // with a ptr_val.ref_count of a equals to 1 760 short int type_save=type; // short int subtype_save=subtype; 761 ref_mpz_t * ptr_save = __ZINTptr; 762 #ifdef DOUBLEVAL 763 _DOUBLE_val = a._DOUBLE_val; 764 subtype=a.subtype; 765 #else 766 * ((ulonglong *) this) = *((ulonglong * ) &a); 767 #endif 768 __ZINTptr=a.__ZINTptr; 769 type=a.type; 770 // Now we delete the target 771 if ( type_save>_DOUBLE_ && type_save!=_FLOAT_ 772 && type_save!=_FUNC 773 ) 774 delete_ptr(subtype,type_save,ptr_save); 775 return *this; 776 } 777 #endif // SMARTPTR64 778 int to_int() const ; 779 double to_double(const context * contextptr) const; 780 bool is_vector_of_size(size_t n) const; 781 bool is_identificateur_with_name(const char * s) const; 782 bool is_real(GIAC_CONTEXT) const ; 783 bool is_cinteger() const ; 784 bool is_integer() const ; 785 bool is_constant() const; 786 std::string print(GIAC_CONTEXT) const; 787 // inline const char * printcharptr(GIAC_CONTEXT) const { return print(contextptr).c_str(); }; 788 // if sptr==0, return length required, otherwise print at end of *sptr 789 int sprint(std::string * sptr,GIAC_CONTEXT) const; 790 std::string print_universal(GIAC_CONTEXT) const; 791 std::string print() const; 792 //inline const char * printcharptr() const { return print().c_str(); }; 793 wchar_t * wprint(GIAC_CONTEXT) const ; 794 // print then convert to a malloc-ated wchar_t * modify(int i)795 void modify(int i) { *this =gen(i); }; 796 const char * dbgprint() const; 797 void uncoerce(size_t s=128) ; 798 gen conj(GIAC_CONTEXT) const; 799 gen re(GIAC_CONTEXT) const ; 800 gen im(GIAC_CONTEXT) const ; 801 gen inverse(GIAC_CONTEXT) const; 802 gen squarenorm(GIAC_CONTEXT) const; 803 int bindigits() const ; 804 gen operator [] (int i) const ; 805 gen operator [] (const gen & i) const; 806 gen operator_at(int i,GIAC_CONTEXT) const; 807 gen operator_at(const gen & i,GIAC_CONTEXT) const; 808 // gen & operator [] (int i) ; 809 // gen & operator [] (const gen & i) ; 810 gen operator () (const gen & i,GIAC_CONTEXT) const; 811 gen operator () (const gen & i,const gen & progname,GIAC_CONTEXT) const; 812 bool islesscomplexthan(const gen & other) const; 813 bool is_approx() const ; // true if double/real or cmplx with re/im 814 int symb_size() const; 815 gen change_subtype(int newsubtype); 816 bool is_symb_of_sommet(const unary_function_ptr & u) const ; 817 bool is_symb_of_sommet(const unary_function_ptr * u) const ; 818 gen makegen(int i) const; // make a gen of same type as this with integer i 819 // For compatibility with older versions 820 inline mpz_t * ref_ZINTptr() const ; 821 inline real_object * ref_REALptr() const ; 822 inline gen * ref_CPLXptr() const ; 823 inline identificateur * ref_IDNTptr() const ; 824 inline symbolic * ref_SYMBptr() const ; 825 inline gen * ref_MODptr () const ; 826 inline Tfraction<gen> * ref_FRACptr() const ; 827 inline gen * ref_EXTptr () const ; 828 inline polynome * ref_POLYptr() const ; 829 inline vecteur * ref_VECTptr() const ; 830 inline sparse_poly1 * ref_SPOL1ptr() const ; 831 inline std::string * ref_STRNGptr() const ; 832 inline unary_function_ptr * ref_FUNCptr() const ; 833 inline gen_user * ref_USERptr() const ; 834 inline gen_map * ref_MAPptr() const ; 835 inline eqwdata * ref_EQWptr() const ; 836 inline grob * ref_GROBptr() const ; 837 inline void * ref_POINTER_val() const ; 838 }; 839 840 bool ref_mpz_t2gen(ref_mpz_t * mptr,gen & g); // return true if mptr used in g 841 gen change_subtype(const gen &g,int newsubtype); 842 gen genfromstring(const std::string & s); 843 // pointer to an int describing display mode for complex numbers 844 int * complex_display_ptr(const gen & g); 845 // value==0 to cartesian, 1 to polar, 2 toggle, 3 count complex 846 // returns the number of complex 847 int adjust_complex_display(gen & res,int value); 848 849 #if defined(SMARTPTR64) 850 typedef ulonglong alias_gen; 851 #else 852 struct alias_gen { 853 unsigned char type; // see dispatch.h 854 signed char subtype; 855 unsigned short reserved; // not used 856 #ifdef DOUBLEVAL 857 longlong value; 858 #else 859 long value ; 860 #endif 861 }; 862 #endif 863 864 class vectpoly:public std::vector<polynome> { 865 public: vectpoly()866 vectpoly():std::vector<polynome>::vector() {}; vectpoly(size_t i,const polynome & p)867 vectpoly(size_t i,const polynome & p):std::vector<polynome>::vector(i,p) {}; dbgprint()868 const char * dbgprint(){ 869 #if !defined(NSPIRE) && !defined(FXCG) 870 CERR << *this << '\n'; 871 #endif 872 return "Done"; 873 } 874 }; 875 876 struct ref_gen_map { 877 volatile ref_count_t ref_count; 878 gen_map m; 879 #if 1 // def NSPIRE ref_gen_mapref_gen_map880 ref_gen_map(): ref_count(1),m() {} 881 #else ref_gen_mapref_gen_map882 ref_gen_map(const std::pointer_to_binary_function < const gen &, const gen &, bool> & p): ref_count(1),m(p) {} 883 #endif ref_gen_mapref_gen_map884 ref_gen_map(const gen_map & M):ref_count(1),m(M) {} 885 }; 886 887 struct alias_ref_fraction { ref_count_t ref_count; alias_gen num; alias_gen den; }; 888 struct alias_ref_complex { 889 ref_count_t ref_count; 890 int display; 891 alias_gen re,im; 892 }; 893 894 struct ref_vecteur { 895 volatile ref_count_t ref_count; 896 vecteur v; ref_vecteurref_vecteur897 ref_vecteur():ref_count(1) {} ref_vecteurref_vecteur898 ref_vecteur(unsigned s):ref_count(1),v(s) {} ref_vecteurref_vecteur899 ref_vecteur(unsigned s,const gen & g):ref_count(1),v(s,g) {} ref_vecteurref_vecteur900 ref_vecteur(const_iterateur it,const_iterateur itend):ref_count(1),v(it,itend) {} ref_vecteurref_vecteur901 ref_vecteur(const vecteur & w):ref_count(1),v(w) {} 902 }; 903 904 905 #ifdef SMARTPTR64 906 #define define_alias_gen(name,type,subtype,ptr) alias_gen name={(ulonglong(ptr) << 16) | (subtype << 8) | type }; 907 #define define_alias_ref_symbolic(name,sommet,type,subtype,ptr) alias_ref_symbolic name={-1,(unary_function_eval *)sommet,(ulonglong(ptr) << 16) | (subtype << 8) | type}; 908 #define define_alias_ref_fraction(name,numtype,numsubtype,numptr,dentype,densubtype,denptr) alias_ref_fraction name={-1,{(ulonglong(numptr) << 16) | (numsubtype << 8) | numtype },{(ulonglong(denptr) << 16) | (densubtype << 8) | dentype }}; 909 #define define_alias_ref_complex(name,retype,resubtype,reptr,imtype,imsubtype,imptr) alias_ref_complex name={-1,0,{(ulonglong(reptr) << 16) | (resubtype << 8) | retype },{(ulonglong(imptr) << 16) | (imsubtype << 8) | imtype }}; 910 #define define_tab2_alias_gen(name,retype,resubtype,reptr,imtype,imsubtype,imptr) alias_gen name[]={{(ulonglong(reptr) << 16) | (resubtype << 8) | retype },{(ulonglong(imptr) << 16) | (imsubtype << 8) | imtype }}; 911 #else // SMARTPTR64 912 #ifdef DOUBLEVAL 913 #define define_alias_gen(name,type,subtype,ptr) alias_gen name={type,subtype,0,ulonglong(ptr)}; 914 #define define_alias_ref_symbolic(name,sommet,type,subtype,ptr) alias_ref_symbolic name={-1,(unary_function_eval *)sommet,type,subtype,0,ulonglong(ptr)}; 915 #define define_alias_ref_fraction(name,numtype,numsubtype,numptr,dentype,densubtype,denptr) alias_ref_fraction name={-1,{numtype,numsubtype,0,ulonglong(numptr)},{dentype,densubtype,0,ulonglong(denptr)}}; 916 #define define_alias_ref_complex(name,retype,resubtype,reptr,imtype,imsubtype,imptr) alias_ref_complex name={-1,0,{retype,resubtype,0,ulonglong(reptr)},{imtype,imsubtype,0,ulonglong(imptr)}}; 917 #define define_tab2_alias_gen(name,retype,resubtype,reptr,imtype,imsubtype,imptr) alias_gen name[]={{retype,resubtype,0,ulonglong(reptr)},{imtype,imsubtype,0,ulonglong(imptr)}}; 918 #else // DOUBLEVAL 919 #define define_alias_gen(name,type,subtype,ptr) alias_gen name={type,subtype,0,long(ptr)}; 920 #define define_alias_ref_symbolic(name,sommet,type,subtype,ptr) alias_ref_symbolic name={-1,(unary_function_eval *)sommet,type,subtype,0,long(ptr)}; 921 #define define_alias_ref_fraction(name,numtype,numsubtype,numptr,dentype,densubtype,denptr) alias_ref_fraction name={-1,{numtype,numsubtype,0,long(numptr)},{dentype,densubtype,0,long(denptr)}}; 922 #define define_alias_ref_complex(name,retype,resubtype,reptr,imtype,imsubtype,imptr) alias_ref_complex name={-1,0,{retype,resubtype,0,long(reptr)},{imtype,imsubtype,0,long(imptr)}}; 923 #define define_tab2_alias_gen(name,retype,resubtype,reptr,imtype,imsubtype,imptr) alias_gen name[]={{retype,resubtype,0,long(reptr)},{imtype,imsubtype,0,long(imptr)}}; 924 #endif // DOUBLEVAL 925 #endif // SMARTPTR64 926 927 // ? #ifdef __GNUC__ 928 #ifdef IMMEDIATE_VECTOR 929 struct alias_ref_vecteur { ref_count_t ref_count; const int _taille; const alias_gen * begin_immediate_vect; const alias_gen * end_immediate_vect; void * ptr; }; 930 #define define_alias_ref_vecteur(name,b) alias_ref_vecteur name={-1,sizeof(b)/sizeof(gen),(const alias_gen *)b,(const alias_gen *)b+sizeof(b)/sizeof(gen),0}; 931 #define define_alias_ref_vecteur2(name,b) alias_ref_vecteur name={-1,2,&b[0],&b[2],0}; 932 #else 933 struct alias_ref_vecteur { ref_count_t ref_count; const alias_gen * begin; const alias_gen * end; const alias_gen * finish; void * ptr; }; 934 #define define_alias_ref_vecteur(name,b) alias_ref_vecteur name={-1,(const alias_gen *)b,(const alias_gen *)b+sizeof(b)/sizeof(gen),(const alias_gen *)b+sizeof(b)/sizeof(gen),0}; 935 #define define_alias_ref_vecteur2(name,b) alias_ref_vecteur name={-1,&b[0],&b[2],&b[2],0}; 936 #endif 937 938 struct ref_complex { 939 volatile ref_count_t ref_count; 940 int display; 941 gen re,im; ref_complexref_complex942 ref_complex(const std::complex<double> & c):ref_count(1),display(0),re(real(c)),im(imag(c)) {} ref_complexref_complex943 ref_complex(const gen & R,const gen & I):ref_count(1),display(0),re(R),im(I) {} ref_complexref_complex944 ref_complex(const gen & R,const gen & I,int display_mode):ref_count(1),display(display_mode),re(R),im(I) {} 945 }; 946 struct ref_modulo { 947 volatile ref_count_t ref_count; 948 gen n,modulo; ref_moduloref_modulo949 ref_modulo():ref_count(1) {} ref_moduloref_modulo950 ref_modulo(const gen &N,const gen &M):ref_count(1),n(N),modulo(M) {} 951 }; 952 struct ref_algext { 953 volatile ref_count_t ref_count; 954 gen P,Pmin,additional; ref_algextref_algext955 ref_algext():ref_count(1) {} 956 }; 957 958 bool poly_is_real(const polynome & p); 959 bool vect_is_real(const vecteur & v,GIAC_CONTEXT); 960 polynome addpoly(const polynome & p,const gen & c); 961 polynome subpoly(const polynome & p,const gen & c); 962 bool islesscomplexthanf(const gen & a,const gen & b); 963 void islesscomplexthanf_sort(iterateur it,iterateur itend); 964 void gen_sort_f(iterateur it,iterateur itend,bool (*f)(const gen &a,const gen &b)); 965 void gen_sort_f_context(iterateur it,iterateur itend,bool (*f)(const gen &a,const gen &b,GIAC_CONTEXT),GIAC_CONTEXT); 966 gen makemap(); // make a new map 967 gen chartab2gen(char * s,GIAC_CONTEXT); 968 969 970 bool is_zero(const gen & a,GIAC_CONTEXT0); 971 bool is_exactly_zero(const gen & a); 972 bool is_one(const gen & a); is_exactly_one(const gen & a)973 inline bool is_exactly_one(const gen & a){ return is_one(a); } 974 bool is_minus_one(const gen & a); 975 bool is_sq_minus_one(const gen & a); 976 bool is_inf(const gen & e); 977 bool is_undef(const gen & e); 978 bool is_undef(const polynome & p); 979 bool is_undef(const vecteur & v); 980 bool has_inf_or_undef(const gen & g); 981 bool is_undef(const sparse_poly1 & s); 982 bool is_zero__VECT(const vecteur & a,GIAC_CONTEXT); 983 bool has_denominator(const gen & n); 984 bool has_i(const gen & g); 985 986 // basic arithmetic 987 gen operator && (const gen & a,const gen & b); 988 gen operator || (const gen & a,const gen & b); 989 gen operator_plus (const gen & a,const gen & b,GIAC_CONTEXT); 990 gen operator_plus (const gen & a,const gen & b,unsigned t,GIAC_CONTEXT); 991 gen operator + (const gen & a,const gen & b); 992 gen & operator_plus_eq (gen & a,const gen & b,GIAC_CONTEXT); 993 inline gen & operator += (gen & a,const gen & b){ 994 return operator_plus_eq(a,b,context0); 995 } 996 Tfraction<gen> operator + (const Tfraction<gen> & a,const Tfraction<gen> & b); // specialization 997 gen sym_add (const gen & a,const gen & b,GIAC_CONTEXT); 998 gen & operator_minus_eq (gen & a,const gen & b,GIAC_CONTEXT); 999 inline gen & operator -= (gen & a,const gen & b){ 1000 return operator_minus_eq(a,b,context0); 1001 } 1002 gen operator_minus (const gen & a,const gen & b,GIAC_CONTEXT); 1003 gen operator - (const gen & a,const gen & b); 1004 gen operator - (const gen & a); 1005 gen sym_sub (const gen & a,const gen & b,GIAC_CONTEXT); 1006 gen operator_times (const gen & a,const gen & b,GIAC_CONTEXT); 1007 gen operator * (const gen & a,const gen & b); 1008 inline gen operator * (int a,const gen & b){ return gen(a)*b; } 1009 inline gen operator * (double a,const gen & b){ return gen(a)*b; } 1010 gen sym_mult (const gen & a,const gen & b,GIAC_CONTEXT); 1011 gen pow(const gen & base,const gen & exponent,GIAC_CONTEXT); 1012 gen giac_pow(const gen & base,const gen & exponent,GIAC_CONTEXT); 1013 gen iquo(const gen & a,const gen & b); // same 1014 gen irem(const gen & a,const gen & b,gen & q); // same 1015 gen smod(const gen & a,const gen & b); // same 1016 void smod(const vecteur & v,const gen & g,vecteur & w); 1017 vecteur smod(const vecteur & a,const gen & b); // same 1018 gen rdiv(const gen & a,const gen & b,GIAC_CONTEXT0); // rational division 1019 inline gen operator /(const gen & a,const gen & b){ return rdiv(a,b); }; 1020 gen operator %(const gen & a,const gen & b); // for int only 1021 bool is_multiple(const gen & a,const gen &b); 1022 // gen inv(const gen & a); 1023 gen inv(const gen & a,GIAC_CONTEXT); wprint(const gen & g,GIAC_CONTEXT)1024 inline wchar_t * wprint(const gen & g,GIAC_CONTEXT){ return g.wprint(contextptr); } 1025 swapgen(gen & a,gen & b)1026 inline void swapgen(gen & a,gen &b){ 1027 #ifdef SMARTPTR64 1028 std::swap(* (ulonglong *)&a,* (ulonglong *)&b); 1029 #else 1030 gen tmp=a; a=b; b=tmp; 1031 #endif 1032 } 1033 gen algebraic_EXTension(const gen & a,const gen & v); 1034 gen ext_reduce(const gen & a, const gen & v); 1035 gen maptoarray(const gen_map & m,GIAC_CONTEXT); 1036 gen evalf_VECT(const vecteur & v,int subtype,int level,const context * contextptr); 1037 gen m_gamma(int nbits); // Euler gamma constant precision nbits 1038 gen m_gamma(GIAC_CONTEXT); 1039 gen m_pi(int nbits); // pi precision nbits 1040 gen m_pi(GIAC_CONTEXT); 1041 1042 // a*b -> tmp, may modify tmp in place 1043 void type_operator_times(const gen & a,const gen &b,gen & tmp); 1044 // c += a*b, may modify c in place 1045 /* 1046 inline void type_operator_plus_times(const gen & a,const gen & b,gen & c){ 1047 gen g; 1048 type_operator_times(a,b,g); 1049 c += g; 1050 } 1051 */ 1052 void type_operator_plus_times(const gen & a,const gen & b,gen & c); 1053 void type_operator_minus_times(const gen & a,const gen & b,gen & c); 1054 type_operator_plus_times_reduce(const gen & a,const gen & b,gen & c,int reduce)1055 inline void type_operator_plus_times_reduce(const gen & a,const gen & b,gen & c,int reduce){ 1056 type_operator_plus_times(a,b,c); 1057 if (reduce) 1058 c=smod(c,reduce); 1059 } 1060 type_operator_reduce(const gen & a,const gen & b,gen & c,int reduce)1061 inline void type_operator_reduce(const gen & a,const gen & b,gen & c,int reduce){ 1062 type_operator_times(a,b,c); 1063 if (reduce) 1064 c=smod(c,reduce); 1065 } 1066 1067 bool operator ==(const gen & a,const gen & b); 1068 bool operator ==(const gen & a,const identificateur & b); 1069 bool operator_equal(const gen & a,const gen & b,GIAC_CONTEXT); 1070 bool operator !=(const gen & a,const gen & b); 1071 inline bool operator !=(const gen & a,const identificateur & b){ return !(a==b); } 1072 gen equal(const gen & a,const gen &b,GIAC_CONTEXT); 1073 gen equal2(const gen & a,const gen &b,GIAC_CONTEXT); 1074 1075 gen operator !(const gen & a); 1076 1077 int fastsign(const gen & a,GIAC_CONTEXT); // 0 if unknown, 1 if >0, -1 if <0 1078 gen sign(const gen & a,GIAC_CONTEXT); signint(int i)1079 inline int signint(int i){ return i?(i>0?1:-1):0;} 1080 1081 // Large tests if strictly not precised, if sign is unknown return false 1082 bool is_greater(const gen & a,const gen &b,GIAC_CONTEXT); 1083 bool is_strictly_greater(const gen & a,const gen &b,GIAC_CONTEXT); 1084 inline bool operator > (const gen & a,const gen & b){ 1085 return is_strictly_greater(a,b,context0); 1086 } 1087 inline bool operator < (const gen & a, const gen & b) { 1088 return is_strictly_greater (b, a, context0); 1089 } 1090 bool is_positive(const gen & a,GIAC_CONTEXT); 1091 bool is_strictly_positive(const gen & a,GIAC_CONTEXT); 1092 // Large tests if strictly not precised, if sign is unknown make an error 1093 bool ck_is_greater(const gen & a,const gen &b,GIAC_CONTEXT); 1094 bool ck_is_strictly_greater(const gen & a,const gen &b,GIAC_CONTEXT); 1095 bool ck_is_positive(const gen & a,GIAC_CONTEXT); 1096 bool ck_is_strictly_positive(const gen & a,GIAC_CONTEXT); 1097 gen superieur_strict(const gen & a,const gen & b,GIAC_CONTEXT); 1098 gen superieur_egal(const gen & a,const gen & b,GIAC_CONTEXT); 1099 gen inferieur_strict(const gen & a,const gen & b,GIAC_CONTEXT); 1100 gen inferieur_egal(const gen & a,const gen & b,GIAC_CONTEXT); 1101 bool symb_size_less(const gen & a,const gen & b); 1102 1103 gen min(const gen & a, const gen & b,GIAC_CONTEXT); 1104 gen max(const gen & a, const gen & b,GIAC_CONTEXT=context0); 1105 // default context0 is required for instantiation in poly.h 1106 gen factorial(unsigned long int i); 1107 gen comb(unsigned long int i,unsigned long j); 1108 gen perm(unsigned long int i,unsigned long j); 1109 gen pow(const gen & base, unsigned long int exponent); 1110 gen pow(const gen & base, int exponent); 1111 gen pow(unsigned long int base, unsigned long int exponent); 1112 1113 // more advanced arithmetic 1114 gen gcd(const gen & A,const gen & B,GIAC_CONTEXT); 1115 gen gcd(const gen & A,const gen & B); 1116 int iegcd(int a_,int b_,int &u,int & v); 1117 gen lcm(const gen & a,const gen & b); 1118 gen simplify(gen & n, gen & d); 1119 void egcd(const gen &a,const gen &b, gen & u,gen &v,gen &d ); 1120 gen ichinrem(const gen & a,const gen &b,const gen & amod, const gen & bmod); 1121 gen invmod(const gen & A,const gen & modulo); 1122 gen fracmod(const gen & a_orig,const gen & modulo); // -> p/q=a mod modulo 1123 bool fracmod(const gen & a_orig,const gen & modulo,gen & res); 1124 bool in_fracmod(const gen &m,const gen & a,mpz_t & d,mpz_t & d1,mpz_t & absd1,mpz_t &u,mpz_t & u1,mpz_t & ur,mpz_t & q,mpz_t & r,mpz_t &sqrtm,mpz_t & tmp,gen & num,gen & den); 1125 bool alloc_fracmod(const gen & a_orig,const gen & modulo,gen & res,mpz_t & d,mpz_t & d1,mpz_t & absd1,mpz_t &u,mpz_t & u1,mpz_t & ur,mpz_t & q,mpz_t & r,mpz_t &sqrtm,mpz_t & tmp); 1126 gen powmod(const gen &base,const gen & expo,const gen & modulo); 1127 gen isqrt(const gen & A); 1128 gen re(const gen & a,GIAC_CONTEXT); 1129 gen no_context_re(const gen & a); 1130 gen im(const gen & a,GIAC_CONTEXT); 1131 gen no_context_im(const gen & a); 1132 void reim(const gen & g,gen & r,gen & i,GIAC_CONTEXT); 1133 gen conj(const gen & a,GIAC_CONTEXT); 1134 gen no_context_conj(const gen & a); 1135 gen sq(const gen & a); 1136 gen abs(const gen & a,const context * contextptr=context0); 1137 // default context0 is required for instantiation in poly.h 1138 gen linfnorm(const gen & a,const context * contextptr=context0); 1139 // default context0 is required for instantiation in poly.h 1140 gen arg(const gen & a,GIAC_CONTEXT); 1141 gen arg_CPLX(const gen & a,GIAC_CONTEXT); 1142 int is_perfect_square(const gen & A); 1143 int is_probab_prime_p(const gen & A); 1144 gen nextprime(const gen & a); // more precisely next probably prime 1145 gen prevprime(const gen & a); // more precisely prev probably prime 1146 int jacobi(const gen & A, const gen &B); 1147 int legendre(const gen & A, const gen & B); 1148 vecteur pascal_next_line(const vecteur & v); 1149 vecteur pascal_nth_line(int n); 1150 // convert a __VECTOR__VECT vecteur to a normal vecteur 1151 gen vector2vecteur(const vecteur & v); 1152 1153 // if b is a _MOD, returns a as a b _MOD 1154 gen chkmod(const gen& a,const gen & b); 1155 // make a _MOD a%b 1156 gen makemod(const gen & a,const gen & b); 1157 // same without evaluating % 1158 gen makemodquoted(const gen & a,const gen & b); 1159 1160 // from a sum in x returns a list of [coeff monomial] 1161 // e.g. 5+2x+3*x*y -> [ [5 1] [2 x] [ 3 x*y] ] 1162 vecteur symbolique2liste(const gen & x,GIAC_CONTEXT); 1163 // v should be sorted and shrinked 1164 gen liste2symbolique(const vecteur & v); 1165 1166 bool is_atomic(const gen & e); 1167 gen _FRAC2_SYMB(const fraction & f); 1168 gen _FRAC2_SYMB(const gen & e); 1169 gen _FRAC2_SYMB(const gen & n,const gen & d); 1170 gen string2gen(const std::string & ss,bool remove_ss_quotes=true); 1171 // by default ss is assumed to be delimited by " and " 1172 std::complex<double> gen2complex_d(const gen & e); 1173 gen eval_VECT(const vecteur & v,int subtype,int level,const context * context_ptr ); 1174 // functional equivalent of gen methods eval(const gen & e,int level,const context * contextptr)1175 inline gen eval(const gen & e,int level,const context * contextptr){ return e.eval(level,contextptr); }; eval(const gen & e,const context * contextptr)1176 inline gen eval(const gen & e,const context * contextptr){ return e.eval(eval_level(contextptr),contextptr); }; 1177 gen no_context_evalf(const gen & e); 1178 gen evalf(const gen & e,int level,const context * contextptr ); 1179 gen evalf2bcd_nock(const gen & g0,int level,const context * contextptr); 1180 gen evalf2bcd(const gen & g0,int level,const context * contextptr); evalf_double(const gen & e,int level,const context * contextptr)1181 inline gen evalf_double(const gen & e,int level,const context * contextptr){ return e.evalf_double(level,contextptr); }; 1182 // return true if g can be converted to a double or real or complex 1183 bool has_evalf(const gen & g,gen & res,int level,const context * contextptr); print(const gen & e,context * contextptr)1184 inline std::string print(const gen & e,context * contextptr){ return e.print(contextptr); } is_real(const gen & g,GIAC_CONTEXT)1185 inline bool is_real(const gen & g,GIAC_CONTEXT){ return g.is_real(contextptr); } is_cinteger(const gen & g)1186 inline bool is_cinteger(const gen & g){ return g.is_cinteger();} ; is_integer(const gen & g)1187 inline bool is_integer(const gen & g){ return g.is_integer(); } ; 1188 double int2double(int i); is_constant(const gen & g)1189 inline bool is_constant(const gen & g){ return g.is_constant(); } ; is_approx(const gen & g)1190 inline bool is_approx(const gen & g){ return g.is_approx(); }; 1191 gen aplatir_fois_plus(const gen & g); 1192 gen collect(const gen & g,GIAC_CONTEXT); 1193 1194 class gen_user{ 1195 public: memory_alloc()1196 virtual gen_user * memory_alloc() const { gen_user * ptr = new gen_user(*this); return ptr; } ~gen_user()1197 virtual ~gen_user() {}; 1198 // redefine operations if it makes sense. 1199 // You can redefine gen_user + gen_user for speed 1200 virtual gen operator + (const gen &) const { return gensizeerr(gettext("+ not redefined")); } 1201 virtual gen operator + (const gen_user & a) const { return (*this) + gen(a); } 1202 virtual gen operator - (const gen &) const { return gensizeerr(gettext("Binary - not redefined")); } 1203 virtual gen operator - (const gen_user & a) const { return (*this) - gen(a); } 1204 virtual gen operator - () const { return gensizeerr(gettext("Unary - not redefined")); } 1205 virtual gen operator * (const gen &) const { return gensizeerr(gettext("Binary * not redefined")); } 1206 virtual gen operator * (const gen_user & a) const { return (*this) * gen(a); } 1207 virtual gen operator / (const gen_user & a) const { return (*this) * a.inv(); } 1208 virtual gen operator / (const gen & a) const { return gensizeerr(gettext("Binary / not redefined")); } is_zero()1209 virtual bool is_zero() const { 1210 #ifndef NO_STDEXCEPT 1211 setsizeerr(gettext("==0 not redefined")); 1212 #endif 1213 return false; 1214 } is_one()1215 virtual bool is_one() const { 1216 #ifndef NO_STDEXCEPT 1217 setsizeerr(gettext("==1 not redefined")); 1218 #endif 1219 return false; 1220 } is_minus_one()1221 virtual bool is_minus_one() const { 1222 #ifndef NO_STDEXCEPT 1223 setsizeerr(gettext("==-1 not redefined")); 1224 #endif 1225 return false; 1226 } inv()1227 virtual gen inv() const { return gensizeerr(gettext("Inv not redefined")); } conj(GIAC_CONTEXT)1228 virtual gen conj(GIAC_CONTEXT) const { return gensizeerr(gettext("Conj not redefined"));} re(GIAC_CONTEXT)1229 virtual gen re(GIAC_CONTEXT) const { return gensizeerr(gettext("Real part not redefined"));} im(GIAC_CONTEXT)1230 virtual gen im(GIAC_CONTEXT) const { return gensizeerr(gettext("Imaginary part not redefined")); } abs(GIAC_CONTEXT)1231 virtual gen abs(GIAC_CONTEXT) const { return gensizeerr(gettext("Abs not redefined"));} arg(GIAC_CONTEXT)1232 virtual gen arg(GIAC_CONTEXT) const { return gensizeerr(gettext("Arg not redefined")); } sqrt(GIAC_CONTEXT)1233 virtual gen sqrt(GIAC_CONTEXT) const { return gensizeerr(gettext("Sqrt not redefined")); } operator()1234 virtual gen operator () (const gen &,GIAC_CONTEXT) const { return gensizeerr(gettext("() not redefined")); } 1235 virtual gen operator [] (const gen &) { return gensizeerr(gettext("[] not redefined")); } 1236 virtual bool operator == (const gen &) const { 1237 #ifndef NO_STDEXCEPT 1238 setsizeerr(gettext("== not redefined")); 1239 #endif 1240 return false; 1241 } 1242 virtual bool operator == (const gen_user & a) const { return (*this) == gen(a); } 1243 // must redefine > AND <= since we do not have symetrical type arguments 1244 virtual gen operator > (const gen &) const { return gensizeerr(gettext("> not redefined")); } 1245 virtual gen operator > (const gen_user & a) const { return superieur_strict(*this, gen(a),0); } 1246 virtual gen operator <= (const gen &) const { return gensizeerr(gettext("<= not redefined")); } 1247 virtual gen operator <= (const gen_user & a) const { return inferieur_egal(*this, gen(a),0); } polygcd(const polynome &,const polynome &,polynome &)1248 virtual gen polygcd (const polynome &,const polynome &,polynome &) const { return gensizeerr(gettext("Polynomial gcd not redefined")); } polyfactor(const polynome & p,factorization & f)1249 virtual gen polyfactor (const polynome & p, 1250 factorization & f) const { 1251 return gensizeerr(gettext("Polynomial gcd not redefined")); 1252 } gcd(const gen &)1253 virtual gen gcd (const gen &) const { return gensizeerr(gettext("gcd not redefined")); } gcd(const gen_user & a)1254 virtual gen gcd (const gen_user & a) const { return gcd(gen(a)); } print(GIAC_CONTEXT)1255 virtual std::string print (GIAC_CONTEXT) const { return "Nothing_to_print";} dbgprint()1256 const char * dbgprint () const { 1257 static std::string s; 1258 s=this->print(0); 1259 #if !defined( NSPIRE) && !defined(FXCG) 1260 CERR << s << '\n'; 1261 #endif 1262 return s.c_str(); 1263 } texprint(GIAC_CONTEXT)1264 virtual std::string texprint (GIAC_CONTEXT) const { return "Nothing_to_print_tex"; } eval(int level,const context * contextptr)1265 virtual gen eval(int level,const context * contextptr) const {return *this;}; evalf(int level,const context * contextptr)1266 virtual gen evalf(int level,const context * contextptr) const {return *this;}; makegen(int i)1267 virtual gen makegen(int i) const { return string2gen("makegen not redefined"); } ; rand(GIAC_CONTEXT)1268 virtual gen rand(GIAC_CONTEXT) const { return string2gen("rand not redefined"); }; 1269 }; 1270 struct ref_gen_user { 1271 volatile ref_count_t ref_count; 1272 gen_user * u; ref_gen_userref_gen_user1273 ref_gen_user(const gen_user & U):ref_count(1),u(U.memory_alloc()) {} ref_gen_userref_gen_user1274 ref_gen_user(gen_user * U):ref_count(1),u(U) {} ~ref_gen_userref_gen_user1275 ~ref_gen_user() {delete u;} 1276 }; 1277 1278 std::string print_the_type(int val,GIAC_CONTEXT); 1279 1280 // I/O 1281 #ifdef KHICAS 1282 stdostream & operator << (stdostream & os,const gen & a); 1283 #endif 1284 #ifdef NSPIRE 1285 template<class T> nio::ios_base<T> & operator<<(nio::ios_base<T> & os,const gen & a){ 1286 return os << a.print(context0); 1287 } 1288 template<class T> nio::ios_base<T> & operator>>(nio::ios_base<T> & is,gen & a); 1289 #else 1290 std::ostream & operator << (std::ostream & os,const gen & a); 1291 std::istream & operator >> (std::istream & is,gen & a); 1292 #endif 1293 1294 #if defined(GIAC_GENERIC_CONSTANTS) // || (defined(VISUALC) && !defined(RTOS_THREADX)) || defined(x86_64) 1295 extern const gen zero; 1296 #else 1297 extern const gen & zero; 1298 #endif 1299 1300 struct monome { 1301 gen coeff; 1302 gen exponent; monomemonome1303 monome():coeff(0),exponent(0) {}; monomemonome1304 monome(const gen & mycoeff) : coeff(mycoeff),exponent(zero) {}; monomemonome1305 monome(const gen &mycoeff,const gen &myexponent) : coeff(mycoeff),exponent(myexponent) {}; 1306 // std::string print() const ; 1307 std::string print(GIAC_CONTEXT) const ; 1308 const char * dbgprint() const ; 1309 }; 1310 #if 0 // def KHICAS 1311 stdostream & operator<<(stdostream & os,const monome & m){ return os << m.print() ;} 1312 #endif 1313 #ifdef NSPIRE 1314 template<class T> nio::ios_base<T> & operator<<(nio::ios_base<T> & os,const monome & m){ return os << m.print() ;} 1315 #else 1316 std::ostream & operator << (std::ostream & os,const monome & m); 1317 #endif 1318 inline bool operator == (const monome & a,const monome & b){ return a.coeff==b.coeff && a.exponent==b.exponent; } 1319 inline bool operator != (const monome & a,const monome & b){ return a.coeff!=b.coeff || a.exponent!=b.exponent; } 1320 polynome apply( const polynome & p, const context * contextptr, gen (* f) (const gen &, const context *)); 1321 1322 const char * printi(GIAC_CONTEXT); 1323 std::string hexa_print_ZINT(const mpz_t & a); 1324 std::string octal_print_ZINT(const mpz_t & a); 1325 std::string binary_print_ZINT(const mpz_t & a); 1326 std::string print_ZINT(const mpz_t & a); 1327 std::string printinner_VECT(const vecteur & v, int subtype,GIAC_CONTEXT); 1328 std::string & add_printinner_VECT(std::string & s,const vecteur &v,int subtype,GIAC_CONTEXT); 1329 std::string begin_VECT_string(int subtype,bool tex,GIAC_CONTEXT); 1330 std::string end_VECT_string(int subtype,bool tex,GIAC_CONTEXT); 1331 std::string print_VECT(const vecteur & v,int subtype,GIAC_CONTEXT); // subtype was 0 by default 1332 std::string print_SPOL1(const sparse_poly1 & p,GIAC_CONTEXT); 1333 std::string print_STRNG(const std::string & s); 1334 std::string printint32(int val,int subtype,GIAC_CONTEXT); 1335 std::string print_FLOAT_(const giac_float & f,GIAC_CONTEXT); 1336 // find closing or opening () [] {} 1337 bool matchpos(const std::string & s,int & pos); 1338 std::string cut_string(const std::string & chaine,int nchar,std::vector<int> & ligne_end) ; 1339 std::string calc_endlines_positions(const vecteur & history_in,const vecteur & history_out,int nchar,std::vector<int> & endlines,std::vector<int> & positions); 1340 bool is_operator_char(char c); 1341 void increase_selection(const std::string & s,int & pos1,int& pos2); 1342 void decrease_selection(const std::string & s,int & pos1,int& pos2); 1343 void move_selection_right(const std::string & s,int & pos1, int & pos2); 1344 void move_selection_left(const std::string & s,int & pos1, int & pos2); 1345 std::string remove_extension(const std::string & chaine); 1346 1347 1348 // This type collects global variables to enable threading 1349 struct environment { 1350 gen modulo; // characteristic 1351 bool moduloon; // Set to false if non modular arithmetic required 1352 bool complexe; // true if working on Z/pZ[i] 1353 gen pn; // cardinal of the field, 0 means equal to modulo 1354 gen coeff; // exemple of coeff, so that we can call coeff.makegen environmentenvironment1355 environment(){ 1356 modulo=13; 1357 moduloon=false; 1358 complexe=false; 1359 coeff=pn=0; 1360 } 1361 }; 1362 1363 struct ref_sparse_poly1 { 1364 volatile ref_count_t ref_count; 1365 sparse_poly1 s; ref_sparse_poly1ref_sparse_poly11366 ref_sparse_poly1(const sparse_poly1 & S):ref_count(1),s(S) {} 1367 }; 1368 1369 1370 // extern environment * env; 1371 1372 struct attributs { 1373 short int fontsize; 1374 unsigned short int background; 1375 unsigned short int text_color; attributsattributs1376 attributs(int f,int b,int t): fontsize(f),background(b),text_color(t) {}; attributsattributs1377 attributs():fontsize(0),background(0),text_color(0) {}; 1378 }; 1379 1380 // Terminal data for EQW display 1381 struct eqwdata { 1382 gen g; 1383 #if defined KHICAS || defined FXCG 1384 short int x,y,dx,dy; 1385 short int baseline; 1386 #else 1387 int x,y,dx,dy; 1388 int baseline; 1389 #endif 1390 bool selected; 1391 bool active; 1392 bool hasbaseline; 1393 bool modifiable; 1394 attributs eqw_attributs; eqwdataeqwdata1395 eqwdata(int dxx,int dyy,int xx, int yy,const attributs & a,const gen& gg):g(gg),eqw_attributs(a),x(xx),y(yy),dx(dxx),dy(dyy),selected(false),active(false),hasbaseline(false),modifiable(true),baseline(0) {}; eqwdataeqwdata1396 eqwdata(int dxx,int dyy,int xx, int yy,const attributs & a,const gen& gg,int mybaseline):g(gg),eqw_attributs(a),x(xx),y(yy),dx(dxx),dy(dyy),selected(false),active(false),hasbaseline(true),modifiable(true),baseline(mybaseline) {}; dbgprinteqwdata1397 const char * dbgprint(){ 1398 #if !defined( NSPIRE) && !defined(FXCG) 1399 CERR << g << ":" << dx<< ","<< dy<< "+"<<x <<","<< y<< "," << baseline << "," << eqw_attributs.fontsize << "," << eqw_attributs.background << "," << eqw_attributs.text_color << '\n'; 1400 #endif 1401 return "Done"; 1402 } 1403 }; 1404 struct ref_eqwdata { 1405 volatile ref_count_t ref_count; 1406 eqwdata e; ref_eqwdataref_eqwdata1407 ref_eqwdata(const eqwdata & E): ref_count(1),e(E) {} 1408 }; 1409 1410 1411 class identificateur { 1412 public: 1413 int * ref_count; 1414 gen * value; 1415 // std::string * name; 1416 const char * id_name; 1417 vecteur * localvalue; 1418 // value / localvalue might be an assumption if it's a vecteur 1419 // of subtype _ASSUME__VECT 1420 // The first gen of an assumption vecteur is the type (_FRAC for rational) 1421 // If the type is _REAL, the vecteur has 2 other elements 1422 // * an interval or a _SET_VECT of intervals 1423 // where interval=vecteur of length 2 of subtype _LINE__VECT 1424 // * a list of excluded particular values 1425 // If the type is _DOUBLE_ the variable will be evalf-ed but not eval-ed 1426 // This is useful in geometry to make figures and get exact results 1427 // If the type is _INT_ it 1428 short int * quoted; 1429 identificateur(); 1430 explicit identificateur(const std::string & s); 1431 explicit identificateur(const char * s); 1432 #ifdef GIAC_HAS_STO_38 1433 explicit identificateur(const char * s, bool StringIsNowYours); // creates identifier. if StringIsNowYours, then the string will be freed when id is destroyed... 1434 #endif 1435 explicit identificateur(const char * s,const gen & e); 1436 identificateur(const std::string & s,const gen & e); 1437 identificateur(const identificateur & s); 1438 ~identificateur(); 1439 identificateur & operator =(const identificateur & s); 1440 gen eval(int level,const gen & orig,const context * context_ptr) ; 1441 bool in_eval(int level,const gen & orig,gen & evaled,const context * context_ptr, bool No38Lookup=false); // if No38Lookup, does not check if HP38 knows about this name... 1442 const char * print(const context * context_ptr) const ; name()1443 std::string name() const { return id_name; } dbgprint()1444 const char * dbgprint() const { 1445 static std::string s; 1446 s=this->print(context0); 1447 #if 0 // ndef NSPIRE 1448 COUT << s; 1449 #endif 1450 return s.c_str(); 1451 } 1452 void unassign() ; 1453 void push(int protection,const gen & e); 1454 bool operator ==(const identificateur & i); 1455 bool operator ==(const gen & i); 1456 inline bool operator !=(const identificateur & i){ return !(*this==i); } 1457 inline bool operator !=(const gen & i){ return !(*this==i);} 1458 void MakeCopyOfNameIfNotLocal(); ///< if the name is not dynamicaly allocated, create a copy for that id. 1459 }; 1460 struct ref_identificateur { 1461 volatile ref_count_t ref_count; 1462 identificateur i; ref_identificateurref_identificateur1463 ref_identificateur(const char * s):ref_count(1),i(s){} ref_identificateurref_identificateur1464 ref_identificateur(const std::string & s):ref_count(1),i(s){} ref_identificateurref_identificateur1465 ref_identificateur(const identificateur & s):ref_count(1),i(s){} 1466 }; 1467 struct alias_ref_identificateur { 1468 ref_count_t i; 1469 int * ref_count; 1470 gen * value; 1471 const char * id_name; 1472 vecteur * localvalue; 1473 short int * quoted; 1474 }; 1475 1476 struct ref_unary_function_ptr { 1477 volatile ref_count_t ref_count; 1478 unary_function_ptr u; ref_unary_function_ptrref_unary_function_ptr1479 ref_unary_function_ptr(const unary_function_ptr & U):ref_count(1),u(U) {} ref_unary_function_ptrref_unary_function_ptr1480 ref_unary_function_ptr(const unary_function_ptr * U):ref_count(1),u(*U) {} 1481 }; 1482 struct symbolic { 1483 unary_function_ptr sommet; 1484 gen feuille; symbolicsymbolic1485 symbolic(const unary_function_ptr & o,const gen & e): sommet(o),feuille(e){}; symbolicsymbolic1486 symbolic(const unary_function_ptr & o,const gen & e1,const gen &e2): sommet(o), feuille(makevecteur(e1,e2)) {}; symbolicsymbolic1487 symbolic(const unary_function_ptr & o,const gen & e1,const gen &e2,const gen & e3): sommet(o), feuille(makevecteur(e1,e2,e3)) {}; symbolicsymbolic1488 symbolic(const unary_function_ptr & o,const gen & e1,const gen &e2,const gen & e3,const gen & e4): sommet(o), feuille(makevecteur(e1,e2,e3,e4)) {}; symbolicsymbolic1489 symbolic(const unary_function_ptr * o,const gen & e): sommet(*o),feuille(e){}; symbolicsymbolic1490 symbolic(const unary_function_ptr * o,const gen & e1,const gen &e2): sommet(*o), feuille(makevecteur(e1,e2)) {}; symbolicsymbolic1491 symbolic(const unary_function_ptr * o,const gen & e1,const gen &e2,const gen & e3): sommet(*o), feuille(makevecteur(e1,e2,e3)) {}; symbolicsymbolic1492 symbolic(const unary_function_ptr * o,const gen & e1,const gen &e2,const gen & e3,const gen & e4): sommet(*o), feuille(makevecteur(e1,e2,e3,e4)) {}; symbolicsymbolic1493 symbolic(const symbolic & mys) : sommet(mys.sommet),feuille(mys.feuille) {}; 1494 symbolic(const symbolic & mys,const gen & e); 1495 symbolic(const gen & a,const unary_function_ptr & o,const gen & b); 1496 symbolic(const gen & a,const unary_function_ptr * o,const gen & b); 1497 std::string print(GIAC_CONTEXT) const; dbgprintsymbolic1498 const char * dbgprint() const { 1499 static std::string s; 1500 s=this->print(context0); 1501 #if 0 // ndef NSPIRE 1502 COUT << s << '\n'; 1503 #endif 1504 return s.c_str(); 1505 } 1506 gen eval(int level,const context * context_ptr) const; 1507 gen evalf(int level,const context * context_ptr) const; 1508 int size() const; 1509 }; 1510 1511 struct ref_symbolic { 1512 volatile ref_count_t ref_count; 1513 symbolic s; ref_symbolicref_symbolic1514 ref_symbolic(const symbolic & S):ref_count(1),s(S) {} 1515 }; 1516 #ifdef SMARTPTR64 1517 struct alias_ref_symbolic { 1518 ref_count_t ref_count; 1519 unary_function_eval * sommet; 1520 ulonglong feuille; 1521 }; 1522 #else 1523 struct alias_ref_symbolic { 1524 ref_count_t ref_count; 1525 unary_function_eval * sommet; 1526 unsigned char type; // see dispatch.h 1527 signed char subtype; 1528 unsigned short reserved; // not used 1529 #ifdef DOUBLEVAL 1530 longlong value; 1531 #else 1532 long value ; 1533 #endif 1534 }; 1535 #endif 1536 1537 #ifdef SMARTPTR64 ref_ZINTptr()1538 inline mpz_t * gen::ref_ZINTptr() const { return & ((ref_mpz_t *) (* (ulonglong *) this >> 16))->z ; } ref_REALptr()1539 inline real_object * gen::ref_REALptr() const { return & ((ref_real_object *) (* (ulonglong *) this >> 16)) ->r; } ref_CPLXptr()1540 inline gen * gen::ref_CPLXptr() const { return & ((ref_complex *)(* (ulonglong *) this >> 16))->re; } ref_MODptr()1541 inline gen * gen::ref_MODptr () const { return & ((ref_modulo *)(* (ulonglong *) this >> 16))->n; } ref_EXTptr()1542 inline gen * gen::ref_EXTptr () const { return & ((ref_algext *)(* (ulonglong *) this >> 16))->P; } ref_VECTptr()1543 inline vecteur * gen::ref_VECTptr() const { return &((ref_vecteur*)(* (ulonglong *) this >> 16))->v; } ref_SPOL1ptr()1544 inline sparse_poly1 * gen::ref_SPOL1ptr() const { return &((ref_sparse_poly1*)(* (ulonglong *) this >> 16))->s; } ref_STRNGptr()1545 inline std::string * gen::ref_STRNGptr() const { return &((ref_string*)(* (ulonglong *) this >> 16))->s; } ref_USERptr()1546 inline gen_user * gen::ref_USERptr() const { return ((ref_gen_user*)(* (ulonglong *) this >> 16))->u; } ref_MAPptr()1547 inline gen_map * gen::ref_MAPptr() const { return &((ref_gen_map*)(* (ulonglong *) this >> 16))->m; } ref_EQWptr()1548 inline eqwdata * gen::ref_EQWptr() const { return &((ref_eqwdata*)(* (ulonglong *) this >> 16))->e; } ref_GROBptr()1549 inline grob * gen::ref_GROBptr() const { return &((ref_grob*)(* (ulonglong *) this >> 16))->g; } ref_POINTER_val()1550 inline void * gen::ref_POINTER_val() const { return ((ref_void_pointer*)(* (ulonglong *) this >> 16))->p; } ref_FRACptr()1551 inline Tfraction<gen> * gen::ref_FRACptr() const { return &((ref_fraction *)(* (ulonglong *) this >> 16))->f; } ref_POLYptr()1552 inline polynome * gen::ref_POLYptr() const { return &((ref_polynome*)(* (ulonglong *) this >> 16))->t; } ref_IDNTptr()1553 inline identificateur * gen::ref_IDNTptr() const {return &((ref_identificateur*)(* (ulonglong *) this >> 16))->i; } ref_SYMBptr()1554 inline symbolic * gen::ref_SYMBptr() const { return &((ref_symbolic*)(* (ulonglong *) this >> 16))->s; } ref_FUNCptr()1555 inline unary_function_ptr * gen::ref_FUNCptr() const { return &((ref_unary_function_ptr*)(* (ulonglong *) this >> 16))->u; } 1556 #else // SMARTPTR64 ref_ZINTptr()1557 inline mpz_t * gen::ref_ZINTptr() const { return &__ZINTptr->z; } ref_REALptr()1558 inline real_object * gen::ref_REALptr() const { return &__REALptr->r; } ref_CPLXptr()1559 inline gen * gen::ref_CPLXptr() const { return &__CPLXptr->re; } ref_MODptr()1560 inline gen * gen::ref_MODptr () const { return &__MODptr->n; } ref_EXTptr()1561 inline gen * gen::ref_EXTptr () const { return &__EXTptr->P; } ref_VECTptr()1562 inline vecteur * gen::ref_VECTptr() const { return &__VECTptr->v; } ref_SPOL1ptr()1563 inline sparse_poly1 * gen::ref_SPOL1ptr() const { return &__SPOL1ptr->s; } ref_STRNGptr()1564 inline std::string * gen::ref_STRNGptr() const { return &__STRNGptr->s; } ref_USERptr()1565 inline gen_user * gen::ref_USERptr() const { return __USERptr->u; } ref_MAPptr()1566 inline gen_map * gen::ref_MAPptr() const { return &__MAPptr->m; } ref_EQWptr()1567 inline eqwdata * gen::ref_EQWptr() const { return &__EQWptr->e; } ref_GROBptr()1568 inline grob * gen::ref_GROBptr() const { return &__GROBptr->g; } ref_POINTER_val()1569 inline void * gen::ref_POINTER_val() const { return __POINTERptr->p; } ref_FRACptr()1570 inline Tfraction<gen> * gen::ref_FRACptr() const { return &__FRACptr->f; } ref_POLYptr()1571 inline polynome * gen::ref_POLYptr() const { return &__POLYptr->t; } ref_IDNTptr()1572 inline identificateur * gen::ref_IDNTptr() const {return &__IDNTptr->i; } ref_SYMBptr()1573 inline symbolic * gen::ref_SYMBptr() const { return &__SYMBptr->s; } 1574 // inline unary_function_ptr * gen::ref_FUNCptr() const { return &__FUNCptr->u; } ref_FUNCptr()1575 inline unary_function_ptr * gen::ref_FUNCptr() const { return (unary_function_ptr*) &_FUNC_; } 1576 #endif // SMARTPTR64 1577 1578 #ifndef DOUBLEVAL 1579 #define _DOUBLE_val DOUBLE_val() 1580 #define _FLOAT_val FLOAT_val() 1581 #endif // DOUBLEVAL 1582 #define _ZINTptr ref_ZINTptr() 1583 #define _REALptr ref_REALptr() 1584 #define _CPLXptr ref_CPLXptr() 1585 #define _IDNTptr ref_IDNTptr() 1586 #define _SYMBptr ref_SYMBptr() 1587 #define _MODptr ref_MODptr() 1588 #define _FRACptr ref_FRACptr() 1589 #define _EXTptr ref_EXTptr() 1590 #define _POLYptr ref_POLYptr () 1591 #define _VECTptr ref_VECTptr() 1592 #define _SPOL1ptr ref_SPOL1ptr() 1593 #define _STRNGptr ref_STRNGptr() 1594 #define _FUNCptr ref_FUNCptr() 1595 #define _ROOTptr ref_ROOTptr() 1596 #define _USERptr ref_USERptr() 1597 #define _MAPptr ref_MAPptr() 1598 #define _EQWptr ref_EQWptr() 1599 #define _GROBptr ref_GROBptr() 1600 #define _POINTER_val ref_POINTER_val() 1601 1602 // function that are indexed 1603 extern const alias_type alias_at_plus; 1604 extern const alias_type alias_at_neg; 1605 extern const alias_type alias_at_binary_minus; 1606 extern const alias_type alias_at_prod; 1607 extern const alias_type alias_at_division; 1608 extern const alias_type alias_at_inv; 1609 extern const alias_type alias_at_pow; 1610 extern const alias_type alias_at_exp; 1611 extern const alias_type alias_at_ln; 1612 extern const alias_type alias_at_abs; 1613 extern const alias_type alias_at_arg; 1614 extern const alias_type alias_at_pnt; 1615 extern const alias_type alias_at_point; 1616 extern const alias_type alias_at_segment; 1617 extern const alias_type alias_at_sto; 1618 extern const alias_type alias_at_sin; 1619 extern const alias_type alias_at_cos; 1620 extern const alias_type alias_at_tan; 1621 extern const alias_type alias_at_asin; 1622 extern const alias_type alias_at_acos; 1623 extern const alias_type alias_at_atan; 1624 extern const alias_type alias_at_sinh; 1625 extern const alias_type alias_at_cosh; 1626 extern const alias_type alias_at_tanh; 1627 extern const alias_type alias_at_asinh; 1628 extern const alias_type alias_at_acosh; 1629 extern const alias_type alias_at_atanh; 1630 extern const alias_type alias_at_interval; 1631 extern const alias_type alias_at_union; 1632 extern const alias_type alias_at_minus; 1633 extern const alias_type alias_at_intersect; 1634 extern const alias_type alias_at_not; 1635 extern const alias_type alias_at_and; 1636 extern const alias_type alias_at_ou; 1637 extern const alias_type alias_at_inferieur_strict; 1638 extern const alias_type alias_at_inferieur_egal; 1639 extern const alias_type alias_at_superieur_strict; 1640 extern const alias_type alias_at_superieur_egal; 1641 extern const alias_type alias_at_different; 1642 extern const alias_type alias_at_equal; 1643 extern const alias_type alias_at_equal2; 1644 extern const alias_type alias_at_rpn_prog; 1645 extern const alias_type alias_at_local; 1646 extern const alias_type alias_at_return; 1647 extern const alias_type alias_at_Dialog; 1648 extern const alias_type alias_at_double_deux_points; 1649 extern const alias_type alias_at_pointprod; 1650 extern const alias_type alias_at_pointdivision; 1651 extern const alias_type alias_at_pointpow; 1652 extern const alias_type alias_at_hash; 1653 extern const alias_type alias_at_pourcent; 1654 extern const alias_type alias_at_tilocal; 1655 extern const alias_type alias_at_break; 1656 extern const alias_type alias_at_continue; 1657 extern const alias_type alias_at_ampersand_times; 1658 extern const alias_type alias_at_maple_lib; 1659 extern const alias_type alias_at_unit; 1660 extern const alias_type alias_at_plot_style; 1661 extern const alias_type alias_at_xor; 1662 extern const alias_type alias_at_check_type; 1663 extern const alias_type alias_at_quote_pow; 1664 extern const alias_type alias_at_case; 1665 extern const alias_type alias_at_dollar; 1666 extern const alias_type alias_at_IFTE; 1667 extern const alias_type alias_at_RPN_CASE; 1668 extern const alias_type alias_at_RPN_LOCAL; 1669 extern const alias_type alias_at_RPN_FOR; 1670 extern const alias_type alias_at_RPN_WHILE; 1671 extern const alias_type alias_at_NOP; 1672 extern const alias_type alias_at_unit; 1673 extern const alias_type alias_at_ifte; 1674 extern const alias_type alias_at_for; 1675 extern const alias_type alias_at_bloc; 1676 extern const alias_type alias_at_program; 1677 extern const alias_type alias_at_same; 1678 extern const alias_type alias_at_increment; 1679 extern const alias_type alias_at_decrement; 1680 extern const alias_type alias_at_multcrement; 1681 extern const alias_type alias_at_divcrement; 1682 extern const alias_type alias_at_sq; 1683 extern const alias_type alias_at_display; 1684 extern const alias_type alias_at_of; 1685 extern const alias_type alias_at_at; 1686 extern const alias_type alias_at_normalmod; 1687 extern const alias_type alias_at_pointplus; 1688 extern const alias_type alias_at_pointminus; 1689 extern const alias_type alias_at_struct_dot; 1690 extern const alias_type alias_at_try_catch; 1691 1692 #ifdef BCD ck_gentobcd(const gen & g,accurate_bcd_float * bcdptr)1693 inline bool ck_gentobcd(const gen & g,accurate_bcd_float * bcdptr){ 1694 if (g.type!=_FLOAT_) 1695 return false; 1696 fExpand(g._FLOAT_val.f,bcdptr); 1697 return true; 1698 } gentobcd(const gen & g,accurate_bcd_float * bcdptr)1699 inline accurate_bcd_float * gentobcd(const gen & g,accurate_bcd_float * bcdptr){ 1700 return fExpand(g._FLOAT_val.f,bcdptr); 1701 } 1702 #endif 1703 1704 // should be in input_lexer.h 1705 // return true/false to tell if s is recognized. return the appropriate gen if true 1706 bool CasIsBuildInFunction(char const *s, gen &g); 1707 1708 void sprintfdouble(char *,const char *,double d); 1709 1710 extern "C" const char * caseval(const char *); 1711 1712 // Alloca proposal by Cyrille to make it work on every compiler. 1713 #ifndef ALLOCA 1714 // alloca versions... 1715 #if defined(FREERTOS) 1716 // for systems that do not support alloca or s[size] syntaxes 1717 class Calloca { public: 1718 void *ram; Calloca(size_t s)1719 Calloca(size_t s): ram(malloc(s)) { } ~Calloca()1720 ~Calloca() { free(ram); } 1721 }; 1722 #define ALLOCA(type, var, size) Calloca alloca##var(size); type *var= (type*)(alloca##var.ram) 1723 #else 1724 #if defined( VISUALC ) || defined( BESTA_OS ) 1725 #define ALLOCA(type, var, size) type *var= (type*)alloca(size) 1726 #else 1727 #define ALLOCA(type, var, size) type var[size] 1728 #endif 1729 #endif 1730 #endif 1731 1732 #ifndef NO_NAMESPACE_GIAC 1733 } // namespace giac 1734 #endif // ndef NO_NAMESPACE_GIAC 1735 1736 #endif // _GIAC_GEN_H 1737