From kreckel at thep.physik.uni-mainz.de Fri Nov 2 15:25:13 2001 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Fri, 2 Nov 2001 15:25:13 +0100 (CET) Subject: templates and builtin functions In-Reply-To: <20011102061140.4420086a.02906@nifty.ne.jp> Message-ID: Dear Masaharu, On Fri, 2 Nov 2001, Masaharu Goto wrote: > 1. Do you really need to compile above template function? > 2. Or can you accept that this one being interpreted? > > In case of 1. , it is unfortunate I see no solution. In case of 2. > I think it is as simple as to load template source file at run time. > > Or do I still miss something? If so, I will review your message again. > I spent only a few minutes reading it... No, you are not missing something. I probably was. Having this interpreted rather than precompiled is obviously the Right Thing (tm). Thanks for your clarifying comments. Now, given a header file containing only the definition template inline const GiNaC::function cosh(const T1 &p1) { return GiNaC::function(GiNaC::function_index_cosh, GiNaC::ex(p1)); } in the GiNaC-Cint interface I can write: Welcome to ginaccint V1.0.1 (GiNaC V0.9.9, Cint V5.15.10) __, _______ GiNaC: (C) 1999-2001 Johannes Gutenberg University Mainz, (__) * | Germany. Cint C/C++ interpreter: (C) 1995-2001 Masaharu ._) i N a C | Goto and Agilent Technologies, Japan. This is free software <-------------' with ABSOLUTELY NO WARRANTY. For details, type `.warranty' Type `.help' for help. >> #include "testheader_cintfunction.h" >> //ginaccint.function next expression can be a function definition >> ex EulerNumber(unsigned n) > { > const symbol xi; > const ex generator = pow(cosh(xi),-1); > return generator.diff(xi,n).subs(xi==0); > } creating file /tmp/ginacbt5aGZ >> cout << EulerNumber(60) << endl; 18108911496579230496545807741652158688733487349236314106008095454231325 >> quit; removing file /tmp/ginacbt5aGZ I am almost happy. There are just the following problems left: 1) I cannot just #include and , where such things are declared. This is because Cint doesn't really seem to be #including them. Probably because it has already done so while ginaccint was compiled and the include guards of these header files are still active. I think I can work around this problem by simply #undef'ing the include guards and reloading those two headers in some automatic way. First attempts look promising... 2) ...but resolution of the proper function is still not correct in Cint! Consider cosh as above, but now sitting in namespace GiNaC: >> cout << GiNaC::cosh(1) << endl; // this is clear cosh(1) >> cout << cosh(1) << endl; // one could say this should be ambigous 1.54308 >> using GiNaC::cosh; >> cout << cosh(1) << endl; // now it should be clear, but it really called... 1.54308 >> cout << std::cosh(1) << endl; // ...this one. :-( 1.54308 Could using declarations like the above one be properly supported by Cint?!? As an aside, why does G__cpp_whatever.h #include ? Is this really needed? (I seem to be able to just delete it prior to comiling G__cpp_whatever.cpp). Regards -richy. -- Richard Kreckel From gregod at cs.rpi.edu Fri Nov 2 22:17:19 2001 From: gregod at cs.rpi.edu (Douglas Gregor) Date: Fri, 2 Nov 2001 16:17:19 -0500 Subject: Infinity and Undefined Message-ID: <200111022119.fA2LJ1F23256@mailout6.nyroc.rr.com> Hello all, I'm currently extending GiNaC to be used for symbolic range propagation. While the specifics of the extensions are likely not interesting to most users, I do find that I need to handle both Infinite and Undefined values in a sensible manner. I'll describe the approach I've taken thus far and would appreciate feedback. Including Infinity and Undefined within GiNaC seems to weed its way into many areas of the code. For instance, when we have two expair's x and y, we assume that if x->rest == y->rest we can combine the coefficients. Clearly this doesn't hold when we consider Infinity or Undefined, so we end up with a large number of special-case branches when we see Infinity or Undefined in an expression. This happens in quite a few places. My current approach is to defined GiNaC::constant values for Infinity and Undefined, and include functions to quickly check if an expression is the Infinity or Undefined constant. From there we just need to find all of the required special cases... Again, and feedback would be appreciated. I've only been using GiNaC for a short while, and perhaps there are tricks that could make this addition go more smoothly. Doug Gregor gregod at cs.rpi.edu From kreckel at thep.physik.uni-mainz.de Sat Nov 3 15:06:47 2001 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Sat, 3 Nov 2001 15:06:47 +0100 (CET) Subject: Infinity and Undefined In-Reply-To: <200111022119.fA2LJ1F23256@mailout6.nyroc.rr.com> Message-ID: On Fri, 2 Nov 2001, Douglas Gregor wrote: > I'm currently extending GiNaC to be used for symbolic range propagation. > While the specifics of the extensions are likely not interesting to most > users, I do find that I need to handle both Infinite and Undefined values in > a sensible manner. I'll describe the approach I've taken thus far and would > appreciate feedback. > > Including Infinity and Undefined within GiNaC seems to weed its way into > many areas of the code. For instance, when we have two expair's x and y, we > assume that if x->rest == y->rest we can combine the coefficients. Clearly > this doesn't hold when we consider Infinity or Undefined, so we end up with a > large number of special-case branches when we see Infinity or Undefined in an > expression. This happens in quite a few places. > > My current approach is to defined GiNaC::constant values for Infinity and > Undefined, and include functions to quickly check if an expression is the > Infinity or Undefined constant. From there we just need to find all of the > required special cases... > > Again, and feedback would be appreciated. I've only been using GiNaC for a > short while, and perhaps there are tricks that could make this addition go > more smoothly. Cool, you understand and appreciate the problem. So, what advice could we give you? ;-) It is clear that those two constants can easily be introduced but there is some amount of work to be done to make them behave consistently, like Infinity+Infinity -> Infinity, but Infinity-Infinity -> Undefined (or fail?). May I suggest to also include CInfinity (like Mma's ComplexInfinity)? That would be very useful for poles in the complex domain. Also, I don't know if class constant is appropiate for this. They expect to be evalf()'ed at some point, don't they? Perhaps adding a special class for each of them would be more appropiate? I really don't know right now... My main concern is that one has to take some care when wiring that into expairseq, add, mul, power, etc. When the logic is inserted at the wrong place this could lead to a performance downgrade that is too large to be acceptable. Many calculations don't need these constants and we do not want to penalize them. I am sure it can be done in a performant way. Happy hacking -richy. -- Richard B. Kreckel From gregod at cs.rpi.edu Sat Nov 3 21:45:44 2001 From: gregod at cs.rpi.edu (Douglas Gregor) Date: Sat, 3 Nov 2001 15:45:44 -0500 Subject: Infinity and Undefined In-Reply-To: References: Message-ID: <01110315454402.00714@dhcp-181-221> > Cool, you understand and appreciate the problem. So, what advice could we > give you? ;-) > > It is clear that those two constants can easily be introduced but there is > some amount of work to be done to make them behave consistently, like > Infinity+Infinity -> Infinity, but Infinity-Infinity -> Undefined (or > fail?). Precisely the case that has caused me the most problems :). There are annoying little subcases as well, like Infinity + Pi*Infinity -> Infinity. Here we're stuck calling evalf() on the constant Pi to determine that it is positive. > May I suggest to also include CInfinity (like Mma's > ComplexInfinity)? That would be very useful for poles in the complex > domain. Perhaps I'll just pave the way with Infinity and Undefined. I've never actually dealt with complex infinity, so I'm sure someone more familiar with the concept would do this better. > Also, I don't know if class constant is appropiate for this. They expect > to be evalf()'ed at some point, don't they? Perhaps adding a special > class for each of them would be more appropiate? I really don't know > right now... Yes, I believe adding a special class for each would be the best option. If nothing else, it will eliminate a dynamic_cast and an integer comparison when testing for Infinity or Undefined. > My main concern is that one has to take some care when wiring that into > expairseq, add, mul, power, etc. When the logic is inserted at the wrong > place this could lead to a performance downgrade that is too large to be > acceptable. Many calculations don't need these constants and we do not > want to penalize them. I am sure it can be done in a performant way. I expected this comment :) I'll do whatever I can to ensure that this addition does not cause a sizeable performance degradation. Doug From pearu at cens.ioc.ee Sun Nov 4 11:43:14 2001 From: pearu at cens.ioc.ee (Pearu Peterson) Date: Sun, 4 Nov 2001 12:43:14 +0200 (EET) Subject: Infinity and Undefined In-Reply-To: <01110315454402.00714@dhcp-181-221> Message-ID: Hi, On Sat, 3 Nov 2001, Douglas Gregor wrote: > > May I suggest to also include CInfinity (like Mma's > > ComplexInfinity)? That would be very useful for poles in the complex > > domain. > > Perhaps I'll just pave the way with Infinity and Undefined. I've never > actually dealt with complex infinity, so I'm sure someone more familiar with > the concept would do this better. In past I tried to introduce the Infinity and Undefined concepts to GMP in its Python layer (gmpy). I also tried to avoid complex infinity stuff but it is not quite possible. For example, how would you deal with * Infinity? Another confusing stuff is arithmetics with Infinities. For example, consider 2 * Infinity + sqrt(-1) * Infinity How would you simplify such expression? There are many seemingly reasonable approaches that, unfortuantely, lead to different results. E.g. 2 * Infinity + sqrt(-1) * Infinity -> (2 + sqrt(-1)) * Infinity or Infinity + sqrt(-1) * Infinity -> (1 + sqrt(-1)) * Infinity. And both results may be incorrect as Infinities may have different weights. There are many approaches possible for introducing Infinity and Undefined "number" types. Each have their advantages and disadvantages depending on the application. My friendly suggestion for you would be to first study these different approaches and propose a complete specification of the extended number model before trying to actually implement its support for GiNaC. This specification should include at least the following tables: | | Infinity | Undefined -------------------------------------------------------- | | | Infinity | ... Undefined | ... where s are +,-,*,/,**,elementary functions. These table may have more rows (e.g. PlusInfinity, MinusInfinity, ComplexInfinity, SignInfinity, ImaginaryUnit, ComplexNumber, ImaginaryNumber, FieldNumber, etc) depending on the approach. If you are able to produce such tables and you get some consensus for different applications, then the next questions are implementation issues but I consider them rather trivial when compared with the problem of proposing a solid number model with Infinities and Undefined (or Notdetermined) concepts. You may copy these models from Mathematica or Maple or whatever, but even they have different solutions and not always suitable for all applications. I hope that I was not too negative about the problem. I think it would be very useful if GiNaC could deal with Infinities and Undefined results. I am certainly interested in such a feature that I am willing to help in anyway I can in this project. Best regards, Pearu From kreckel at thep.physik.uni-mainz.de Tue Nov 6 19:21:34 2001 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Tue, 6 Nov 2001 19:21:34 +0100 (CET) Subject: Breaking News Message-ID: MAINZ, Germany, November 6, 2001 (for immediate release) The GiNaC hackers, the leading providers of advanced mathematical software solutions for research and industrial applications, loudly announce the availability of GiNaC version 1.0. GiNaC stands for "GiNaC is not a CAS", i.e. not a Computer Algebra System. This is reminiscent to the term GNU, which stands for "GNU is not Unix", yet GNU systems widely define Unix today. It is a C++ class-library that allows certain common symbolic manipulations to be expressed directly in that language. "This release is going to change a whole lot of things" says Richard Kreckel, vice president of GiNaC's PR department. "Competing closed-source systems like Mathematica and Maple must be considered obsolete now and will surely soon fall into oblivion -- Macsyma already has." Asked whether GiNaC can really compete with all the fancy features and gimmicks found in those systems he replied: "Hey, there is always room for version 2.0 and the next generation!" Alexander Frink, vice president of GiNaC's sales department, could not be reached for a statement. He was reckoned to be busy encashing donations from millions of joyous users overwhelmed with enthusiasm. GiNaC is free software and licensed under the GNU general public license (GPL). "Having a truly scalable symbolic system is going to solve many of todays problems" says Christian Bauer, vice president of the research and development department. "Applications range from pure maths and physics over geological surveys, long-term stock options and wheather forecasts to such fields as wine-making and Japanese cuisine." The newly released version 1.0 contains "absolutely no significant changes relative to the last version whatsoever" according to Bauer. Asked how he sees further development he crypticly proclaimed "We are simply going to do what we did with the Macintosh: We emulate all other systems, including their bugs." Instructions how to download and install GiNaC on a computer system can be found at . Also, it comes pre-bundled with several distributions of the popular Linux operating system as well as with FreeBSD. Because of this dominant position on the consumers' computer desktops the US department of justice (DOJ) is considering filing an antitrust law-suit. "Okay, Microsoft got away with this practice, but we are not going to tolerate imitators", said DOJ attorney general John Ashcroft at a meeting with press. Germany's foreign minister Joschka Fischer delayed his trip to meet Palestinian president Jassir Arafat to stop in Mainz and congratulate the GiNaC folks for their release on behalf of Germany's chancellor Gerhard Schroeder. IT-industry friendly Mr. Schroeder was said to be busy "getting the beast installed" on his PC. "This new release is going to have a tremendous impact on global stability" Mr. Fischer said. "We have observed how politicians and suspected terrorists alike have become addicted to GiNaC and been converted to coding machines -- in a noble sense. Wherever they find a PC they start emitting mesmeric steams and then the miracle of code generation happens." From kreckel at thep.physik.uni-mainz.de Sat Nov 10 16:12:37 2001 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Sat, 10 Nov 2001 16:12:37 +0100 (CET) Subject: Infinity and Undefined In-Reply-To: Message-ID: On Sun, 4 Nov 2001, Pearu Peterson wrote: [...] > > Perhaps I'll just pave the way with Infinity and Undefined. I've never > > actually dealt with complex infinity, so I'm sure someone more familiar with > > the concept would do this better. > > In past I tried to introduce the Infinity and Undefined concepts to GMP > in its Python layer (gmpy). I also tried to avoid complex infinity stuff > but it is not quite possible. For example, how would you deal with > * Infinity? > > Another confusing stuff is arithmetics with Infinities. For example, > consider > 2 * Infinity + sqrt(-1) * Infinity > How would you simplify such expression? There are many seemingly > reasonable approaches that, unfortuantely, lead to different results. E.g. > 2 * Infinity + sqrt(-1) * Infinity -> > (2 + sqrt(-1)) * Infinity > or > Infinity + sqrt(-1) * Infinity -> (1 + sqrt(-1)) * Infinity. > And both results may be incorrect as Infinities may have different > weights. This is a very valid example and in my opinion the only way out of this is to return Undefined if the coefficients are not either on the real axis alone or the imaginary axis alone. They also need to have the same sign, of course. Doesn't the example fall into the same category as (Infinity - Infinity), which should be Undefined, too? [...] > My friendly suggestion for you would be to first study these different > approaches and propose a complete specification of the extended number > model before trying to actually implement its support for GiNaC. This > specification should include at least the following tables: > | | Infinity | Undefined > -------------------------------------------------------- > | | | > Infinity | ... > Undefined | ... > where s are +,-,*,/,**,elementary functions. > These table may have more rows (e.g. PlusInfinity, MinusInfinity, > ComplexInfinity, SignInfinity, ImaginaryUnit, ComplexNumber, > ImaginaryNumber, FieldNumber, etc) depending on the approach. Uh, oh, while such a table would be helpful in understanding the issues involved, I think we shouldn't bother with all of the rows you are suggesting. BTW, what's a FieldNumber? Regards -richy. -- Richard B. Kreckel From gregod at cs.rpi.edu Wed Nov 14 15:44:43 2001 From: gregod at cs.rpi.edu (Douglas Gregor) Date: Wed, 14 Nov 2001 09:44:43 -0500 Subject: relational::operator bool() Message-ID: <200111141444.fAEEiXh27269@mailout5.nyroc.rr.com> Hello, This is just a C++ nitpick, but operator bool() is often considered harmful because of the plethora of implicit conversions (bool->int being the worst of these implicit conversions, IMHO). I'm not suggesting that operator bool() be removed from relational, but instead replace it with a safer construct. Within the Boost C++ libraries (http://www.boost.org), we've adopted a "safe_bool" conversion using of a pointer-to-member function. The trick can be illustrated concisely: // Add to class relational private: struct dummy { void nonnull() {}; }; typedef void (dummy::*safe_bool)(); safe_bool make_safe_bool(bool cond) const { return cond? &dummy::nonnull : 0; } Then in relational::operator safe_bool() const, whereever there is a "return ", it should be replaced with "return make_safe_bool()". The use of the pointer-to-member function eliminates implicit conversions, but the relational class can still be used in a boolean context (since it is evaluated as "is the pointer-to-member function null?"). All meaningless operations that are allowed by a "bool" conversion except for == and != are eleminated by this "safe_bool". I can submit a patch against CVS if needed. Doug Gregor gregod at cs.rpi.edu From kreckel at thep.physik.uni-mainz.de Wed Nov 14 16:38:49 2001 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Wed, 14 Nov 2001 16:38:49 +0100 (CET) Subject: relational::operator bool() In-Reply-To: <200111141444.fAEEiXh27269@mailout5.nyroc.rr.com> Message-ID: On Wed, 14 Nov 2001, Douglas Gregor wrote: > Hello, > This is just a C++ nitpick, but operator bool() is often considered harmful > because of the plethora of implicit conversions (bool->int being the worst of > these implicit conversions, IMHO). I'm not suggesting that operator bool() be > removed from relational, but instead replace it with a safer construct. > Within the Boost C++ libraries (http://www.boost.org), we've adopted a > "safe_bool" conversion using of a pointer-to-member function. The trick can > be illustrated concisely: > > // Add to class relational > private: > struct dummy { > void nonnull() {}; > }; > > typedef void (dummy::*safe_bool)(); > > safe_bool make_safe_bool(bool cond) const > { return cond? &dummy::nonnull : 0; } > > Then in relational::operator safe_bool() const, whereever there is a > "return ", it should be replaced with > "return make_safe_bool()". > > The use of the pointer-to-member function eliminates implicit conversions, > but the relational class can still be used in a boolean context (since it is > evaluated as "is the pointer-to-member function null?"). All meaningless > operations that are allowed by a "bool" conversion except for == and != are > eleminated by this "safe_bool". > > I can submit a patch against CVS if needed. Can you please email that patch? (I'm still trying to grok whether this breaks compatibilities. Binary yes, I guess.) Regards -richy. -- Richard Kreckel From gregod at cs.rpi.edu Wed Nov 14 18:46:54 2001 From: gregod at cs.rpi.edu (Douglas Gregor) Date: Wed, 14 Nov 2001 12:46:54 -0500 Subject: relational::operator bool() In-Reply-To: References: Message-ID: <200111141746.fAEHkkh08521@mailout5.nyroc.rr.com> On Wednesday 14 November 2001 10:38 am, you wrote: > Can you please email that patch? (I'm still trying to grok whether this > breaks compatibilities. Binary yes, I guess.) I've attached the patch against current CVS. It will break binary compatibility on some platforms. There is also a source compatibility break if one uses: relation r = ...; if (r == true) ... If that's a concern, it can be fixed with a few overloads of operator== and operator!= for (relation,bool) and (bool,relation). Doug -------------- next part -------------- ? GiNaC.spec ? Makefile ? Makefile.in ? aclocal.m4 ? config.h ? config.h.in ? config.log ? config.status ? configure ? ginac-config ? ginac-config.1 ? libtool ? stamp-h ? stamp-h.in ? stamp-h1 ? check/.deps ? check/.libs ? check/Makefile ? check/Makefile.in ? check/checks ? check/checks.out ? check/exam.gar ? check/exams ? check/exams.out ? check/times ? check/times.out ? doc/Makefile ? doc/Makefile.in ? doc/reference/Makefile ? doc/reference/Makefile.in ? doc/tutorial/Makefile ? doc/tutorial/Makefile.in ? ginac/.deps ? ginac/.libs ? ginac/Makefile ? ginac/Makefile.in ? ginac/exprseq.cpp ? ginac/exprseq.h ? ginac/function.cpp ? ginac/function.h ? ginac/input_lexer.cc ? ginac/input_parser.cc ? ginac/input_parser.h ? ginac/libginac.la ? ginac/lst.cpp ? ginac/lst.h ? ginac/version.h ? ginsh/.deps ? ginsh/Makefile ? ginsh/Makefile.in ? ginsh/ginsh.1 ? ginsh/ginsh_fcn_help.h ? ginsh/ginsh_op_help.h ? ginsh/ginsh_parser.cc ? ginsh/ginsh_parser.h ? tools/.deps ? tools/Makefile ? tools/Makefile.in ? tools/viewgar.1 Index: ginac/relational.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/relational.cpp,v retrieving revision 1.40 diff -c -3 -p -r1.40 relational.cpp *** ginac/relational.cpp 2001/10/27 16:18:57 1.40 --- ginac/relational.cpp 2001/11/14 17:39:56 *************** ex relational::rhs(void) const *** 233,263 **** // non-virtual functions in this class ////////// /** Cast the relational into a boolean, mainly for evaluation within an * if-statement. Note that (a=b) == true in * the general symbolic case. A false result means the comparison is either * false or undecidable (except of course for !=, where true means either * unequal or undecidable). */ ! relational::operator bool() const { const ex df = lh-rh; if (!is_ex_exactly_of_type(df,numeric)) // cannot decide on non-numerical results ! return o==not_equal ? true : false; switch (o) { case equal: ! return ex_to(df).is_zero(); case not_equal: ! return !ex_to(df).is_zero(); case less: ! return ex_to(df)<_num0; case less_or_equal: ! return ex_to(df)<=_num0; case greater: ! return ex_to(df)>_num0; case greater_or_equal: ! return ex_to(df)>=_num0; default: throw(std::logic_error("invalid relational operator")); } --- 233,270 ---- // non-virtual functions in this class ////////// + relational::safe_bool relational::make_safe_bool(bool cond) const + { + return cond? &safe_bool_helper::nonnull + : 0; + } + /** Cast the relational into a boolean, mainly for evaluation within an * if-statement. Note that (a=b) == true in * the general symbolic case. A false result means the comparison is either * false or undecidable (except of course for !=, where true means either * unequal or undecidable). */ ! relational::operator relational::safe_bool() const { const ex df = lh-rh; if (!is_ex_exactly_of_type(df,numeric)) // cannot decide on non-numerical results ! return o==not_equal ? make_safe_bool(true) ! : make_safe_bool(false); switch (o) { case equal: ! return make_safe_bool(ex_to(df).is_zero()); case not_equal: ! return make_safe_bool(!ex_to(df).is_zero()); case less: ! return make_safe_bool(ex_to(df)<_num0); case less_or_equal: ! return make_safe_bool(ex_to(df)<=_num0); case greater: ! return make_safe_bool(ex_to(df)>_num0); case greater_or_equal: ! return make_safe_bool(ex_to(df)>=_num0); default: throw(std::logic_error("invalid relational operator")); } Index: ginac/relational.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/relational.h,v retrieving revision 1.33 diff -c -3 -p -r1.33 relational.h *** ginac/relational.h 2001/08/22 16:11:51 1.33 --- ginac/relational.h 2001/11/14 17:39:56 *************** public: *** 70,78 **** virtual ex rhs(void) const; // non-virtual functions in this class public: ! operator bool(void) const; ! // member variables protected: --- 70,93 ---- virtual ex rhs(void) const; // non-virtual functions in this class + + private: + // for conversions to boolean, as would be used in an if conditional, + // implicit conversions from bool to int have a large number of + // undesirable side effects. The following safe_bool type enables + // use of relational objects in conditionals without those side effects + struct safe_bool_helper { + void nonnull() {}; + }; + + typedef void (safe_bool_helper::*safe_bool)(); + + safe_bool make_safe_bool(bool) const; + public: ! operator safe_bool(void) const; ! safe_bool operator!(void) const; ! // member variables protected: *************** protected: *** 87,92 **** --- 102,113 ---- template<> inline bool is_exactly_a(const basic & obj) { return obj.tinfo()==TINFO_relational; + } + + // inlined functions for efficiency + inline relational::safe_bool relational::operator!() const + { + return make_safe_bool(!static_cast(*this)); } } // namespace GiNaC From pearu at cens.ioc.ee Thu Nov 15 11:25:22 2001 From: pearu at cens.ioc.ee (Pearu Peterson) Date: Thu, 15 Nov 2001 12:25:22 +0200 (EET) Subject: Infinity and Undefined In-Reply-To: Message-ID: On Sat, 10 Nov 2001, Richard B. Kreckel wrote: > On Sun, 4 Nov 2001, Pearu Peterson wrote: > > Another confusing stuff is arithmetics with Infinities. For example, > > consider > > 2 * Infinity + sqrt(-1) * Infinity > > How would you simplify such expression? There are many seemingly > > reasonable approaches that, unfortuantely, lead to different results. E.g. > > 2 * Infinity + sqrt(-1) * Infinity -> > > (2 + sqrt(-1)) * Infinity > > or > > Infinity + sqrt(-1) * Infinity -> (1 + sqrt(-1)) * Infinity. > > And both results may be incorrect as Infinities may have different > > weights. > > This is a very valid example and in my opinion the only way out of this is > to return Undefined if the coefficients are not either on the real axis > alone or the imaginary axis alone. They also need to have the same sign, > of course. Doesn't the example fall into the same category as > (Infinity - Infinity), which should be Undefined, too? Sure. However one could extend your rule to: a*Inf + b*Inf -> (a+b)*Inf iff a,b are complex numbers with Arg(a)==Arg(b) -> Undefined in all other cases. > [...] > > My friendly suggestion for you would be to first study these different > > approaches and propose a complete specification of the extended number > > model before trying to actually implement its support for GiNaC. This > > specification should include at least the following tables: > > | | Infinity | Undefined > > -------------------------------------------------------- > > | | | > > Infinity | ... > > Undefined | ... > > where s are +,-,*,/,**,elementary functions. > > These table may have more rows (e.g. PlusInfinity, MinusInfinity, > > ComplexInfinity, SignInfinity, ImaginaryUnit, ComplexNumber, > > ImaginaryNumber, FieldNumber, etc) depending on the approach. > > Uh, oh, while such a table would be helpful in understanding the issues > involved, I think we shouldn't bother with all of the rows you are > suggesting. Absolutely right. The contents of rows depends on the approach one chooses. > BTW, what's a FieldNumber? I was thinking of quaternions (though they form skew field). However introducing such objects to GiNaC may not be simple. And I am not sure if you are interested in such an extension. Regards, Pearu From kreckel at thep.physik.uni-mainz.de Thu Nov 15 12:44:32 2001 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Thu, 15 Nov 2001 12:44:32 +0100 (CET) Subject: Infinity and Undefined In-Reply-To: Message-ID: On Thu, 15 Nov 2001, Pearu Peterson wrote: > > BTW, what's a FieldNumber? > > I was thinking of quaternions (though they form skew field). However > introducing such objects to GiNaC may not be simple. And I am not sure if > you are interested in such an extension. Hmm, quaternions would just be another indexed object, I think. You certainly don't want to use an explicit 2x2 matrix representation, would you? On the other hand, it would probably be more reasonable implementing Pauli matrices in a fashion completely analogous to class color. Then, the quaternions i, j and k are just related with these by sigma_x = I*i, sigma_y = I*j, sigma_z = I*k, together with the unity sigma_ONE. Cheers -richy. -- Richard B. Kreckel From kreckel at thep.physik.uni-mainz.de Fri Nov 16 17:46:32 2001 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Fri, 16 Nov 2001 17:46:32 +0100 (CET) Subject: relational::operator bool() In-Reply-To: <200111141746.fAEHkkh08521@mailout5.nyroc.rr.com> Message-ID: On Wed, 14 Nov 2001, Douglas Gregor wrote: > I've attached the patch against current CVS. It will break binary > compatibility on some platforms. What's the criterion for such a platform? (It sure breaks on Linux-x86/GCC.) Cheers -richy. -- Richard B. Kreckel From gregod at cs.rpi.edu Fri Nov 16 19:34:38 2001 From: gregod at cs.rpi.edu (Douglas Gregor) Date: Fri, 16 Nov 2001 13:34:38 -0500 Subject: relational::operator bool() In-Reply-To: References: Message-ID: <200111161834.fAGIYPm10709@mailout6.nyroc.rr.com> On Friday 16 November 2001 11:46 am, you wrote: > On Wed, 14 Nov 2001, Douglas Gregor wrote: > > I've attached the patch against current CVS. It will break binary > > compatibility on some platforms. > > What's the criterion for such a platform? (It sure breaks on > Linux-x86/GCC.) I can guess at what the criterion would be for it to _not_ break on a given platform: 1) sizeof(bool) == sizeof(pointer-to-member-function) 2) a NULL pointer-to-member has integral value 0 I would guess that the first condition does not hold for Linux-x86/GCC. I seem to recall that pointers-to-members of polymorphic classes are "fat", because they need to carry some run-time type information with them to deal with the possibilities of multiple/virtual inheritance. Doug From kreckel at thep.physik.uni-mainz.de Fri Nov 16 21:03:07 2001 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Fri, 16 Nov 2001 21:03:07 +0100 (CET) Subject: relational::operator bool() In-Reply-To: <200111161834.fAGIYPm10709@mailout6.nyroc.rr.com> Message-ID: On Fri, 16 Nov 2001, Douglas Gregor wrote: > I can guess at what the criterion would be for it to _not_ break on a given > platform: > 1) sizeof(bool) == sizeof(pointer-to-member-function) > 2) a NULL pointer-to-member has integral value 0 > > I would guess that the first condition does not hold for Linux-x86/GCC. I > seem to recall that pointers-to-members of polymorphic classes are "fat", > because they need to carry some run-time type information with them to deal > with the possibilities of multiple/virtual inheritance. Questions of sizeof() aside, I guess it can't work at all because binaries want `GiNaC::relational::operator bool(void) const' which the poor linker cannt whip up fast enough... :-) Cheers -richy. -- Richard B. Kreckel From pearu at cens.ioc.ee Tue Nov 20 23:33:41 2001 From: pearu at cens.ioc.ee (Pearu Peterson) Date: Wed, 21 Nov 2001 00:33:41 +0200 (EET) Subject: Is relational::is_equal patch needed? Message-ID: Hi, I have noticed that relational(a,b,==).is_equal(relational(b,a,==)) returns 0 Is this expected behaviour for GiNaC internals? I just want to know whether it is worth to write a patch such that a==b .is_equal(b==a) -> 1 aa) -> 1 etc. that should be implemented in the method relational::is_equal_same_type right? Regards, Pearu Pearu Peterson , PhD, Researcher Department of Mechanics and Applied Mathematics http://cens.ioc.ee/~pearu/ Institute of Cybernetics at Tallinn Technical University Phone: (+372) 6204168 Akadeemia Rd. 21, 12618 Tallinn ESTONIA Fax: (+372) 6204161 *** the nonvalidity of rigorous causality is necessary and not just consistently possible (Heisenberg, 1925) *** From kreckel at thep.physik.uni-mainz.de Wed Nov 21 14:18:58 2001 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Wed, 21 Nov 2001 14:18:58 +0100 (CET) Subject: Is relational::is_equal patch needed? In-Reply-To: Message-ID: Hi, On Wed, 21 Nov 2001, Pearu Peterson wrote: > I have noticed that > relational(a,b,==).is_equal(relational(b,a,==)) > returns > 0 > > Is this expected behaviour for GiNaC internals? I just want to know > whether it is worth to write a patch such that > a==b .is_equal(b==a) -> 1 > aa) -> 1 > etc. > that should be implemented in the method > relational::is_equal_same_type > right? Sounds good to me. Can you send a patch? I am planning to put out 1.0.1 tomorrow. Cheers -richy. -- Richard B. Kreckel From pearu at cens.ioc.ee Wed Nov 21 14:21:10 2001 From: pearu at cens.ioc.ee (Pearu Peterson) Date: Wed, 21 Nov 2001 15:21:10 +0200 (EET) Subject: bug(?): psi() Aborts Message-ID: Hi, Notice that the following program #include #include using namespace std; using namespace GiNaC; int main() { numeric x("2"); cout << "psi("<sin, it runs fine). Does it happen to you? I am using ginac-1.0.0 (from a week old CVS) cln-1.1.3 gmp-3.1.1, gcc version 2.95.4 20011006 (Debian prerelease) on woody debian. Any ideas what is wrong with calling psi? Btw, when when running `make ginac.html' in tutorial, it just generates ginac directory but not the file ginac.html. Pearu From kreckel at thep.physik.uni-mainz.de Wed Nov 21 14:46:02 2001 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Wed, 21 Nov 2001 14:46:02 +0100 (CET) Subject: bug(?): psi() Aborts In-Reply-To: Message-ID: Hi, On Wed, 21 Nov 2001, Pearu Peterson wrote: > #include > #include > using namespace std; > using namespace GiNaC; > > int main() > { > numeric x("2"); > cout << "psi("< return 0; > } > > just Aborts when running it (when replacing psi->sin, it runs fine). Does > it happen to you? I am using > ginac-1.0.0 (from a week old CVS) > cln-1.1.3 > gmp-3.1.1, > gcc version 2.95.4 20011006 (Debian prerelease) > on woody debian. > > Any ideas what is wrong with calling psi? The problem is that psi(numeric) is overloaded because we thought we could just implement tgamma(x), lgamma(x), psi(x), zeta(x), zeta(n,x) and so forth. This was a bit naive, though, and up to now only Li2(), i.e. the dilogarithm, is implemented. So, when you call psi(2) you end up calling template inline const GiNaC::function psi(const T1 & p1) { return function(function_index_psi1, ex(p1)); } with T1 being a plain int. It thus is equivalent to calling psi(const ex &) which ends up in psi1_eval(). In contrast, looking into numeric.cpp, we see the stub const numeric psi(const numeric &x) { throw dunno(); } which explains why your program aborts. That dunno class is meant to signal (possibly partial) unimplemented behaviour and if you look at psi1_evalf() you'll see that class dunno is caught there. Bottom line: we are currently stuck with the somewhat irritating fact that evalf(psi(2)) correctly returns 0.42278 because it just evalf(1-Euler) while psi(numeric(2)) sets your PC on fire. :-( Cheers -richy. -- Richard Kreckel From pearu at cens.ioc.ee Wed Nov 21 18:45:57 2001 From: pearu at cens.ioc.ee (Pearu Peterson) Date: Wed, 21 Nov 2001 19:45:57 +0200 (EET) Subject: Is relational::is_equal patch needed? In-Reply-To: Message-ID: On Wed, 21 Nov 2001, Richard B. Kreckel wrote: > Can you send a patch? I am planning to put out 1.0.1 tomorrow. You can find patches attached. Features include (aa) -> true (a==b).is_equal(b==a) -> true etc. Note that I had to introduce also relational::calchash such that hash(a < b) == hash(b > a) hash(a == b) == hash(b == a) etc. in order to relational::is_equal_same_type will acctually called on (aa) Earlier aa had different hash values and basic::is_equal used to return false on such cases. I run also `make check' to ensure that I didn't broke anything. All tests passed fine. Regards, Pearu -------------- next part -------------- --- relational.h.orig Wed Nov 21 14:35:32 2001 +++ relational.h Wed Nov 21 17:13:57 2001 @@ -63,6 +63,8 @@ bool match_same_type(const basic & other) const; unsigned return_type(void) const; unsigned return_type_tinfo(void) const; + bool is_equal_same_type(const basic & other) const; + unsigned calchash(void) const; // new virtual functions which can be overridden by derived classes public: -------------- next part -------------- --- relational.cpp.orig Wed Nov 21 14:29:35 2001 +++ relational.cpp Wed Nov 21 18:09:23 2001 @@ -229,6 +229,70 @@ return rh; } +unsigned relational::calchash(void) const +{ + unsigned v = golden_ratio_hash(tinfo()); + unsigned lhash = lh.gethash(); + unsigned rhash = rh.gethash(); + + v = rotate_left_31(v); + switch(o) { + case equal: ; + case not_equal: + if (lhash>rhash) { v ^= lhash; lhash = rhash; } + else v ^= rhash; + break; + case less: ; + case less_or_equal: + v ^= rhash; + break; + case greater: ; + case greater_or_equal: + v ^= lhash; lhash = rhash; + break; + } + v = rotate_left_31(v); + v ^= lhash; + + // mask out numeric hashes: + v &= 0x7FFFFFFFU; + + // store calculated hash value only if object is already evaluated + if (flags & status_flags::evaluated) { + setflag(status_flags::hash_calculated); + hashvalue = v; + } + + return v; +} + +bool relational::is_equal_same_type(const basic & other) const +{ + GINAC_ASSERT(is_a(other)); + relational const &oth = static_cast(other); + if (o == oth.o && lh.is_equal(oth.lh) && rh.is_equal(oth.rh)) + return true; + switch (o) { + case equal: ; + case not_equal: + if (oth.o!=o) return false; + break; + case less: + if (oth.o!=greater) return false; + break; + case less_or_equal: + if (oth.o!=greater_or_equal) return false; + break; + case greater: + if (oth.o!=less) return false; + break; + case greater_or_equal: + if (oth.o!=less_or_equal) return false; + break; + } + return lh.is_equal(oth.rh) && rh.is_equal(oth.lh); +} + ////////// // non-virtual functions in this class ////////// From keith.briggs at bt.com Thu Nov 22 14:05:01 2001 From: keith.briggs at bt.com (keith.briggs at bt.com) Date: Thu, 22 Nov 2001 13:05:01 -0000 Subject: cln? Message-ID: Dear GiNaC people, I wanted to install ginac1 so I had to upgrade my cln to the latest version (I used older version ok). But it would not compile on my redhat6 system. (see the attachment) Any ideas? I know you are not the cln authors, but maybe you have experience with this. Thank you, Keith <> Dr. Keith M. Briggs Senior Mathematician, Complexity Research, BTexact Technologies email: Keith.Briggs at bt.com phone: +44(0)1473 work: 641 911 home (new!): 610 517 fax: 647 410 web: www.btexact.com/people/briggsk2/ mail: Keith Briggs, Antares 2pp5, Adastral Park, Martlesham, Suffolk IP5 3RE, UK BTexact Technologies is a trademark of British Telecommunications plc Registered office: 81 Newgate Street London EC1A 7AJ Registered in England no. 1800000 This electronic message contains information from British Telecommunications plc which may be privileged or confidential. The information is intended to be for the use of the individual(s) or entity named above. If you are not the intended recipient be aware that any disclosure, copying, distribution or use of the contents of this information is prohibited. If you have received this electronic message in error, please notify us by telephone or email (to the numbers or address above) immediately. -------------- next part -------------- A non-text attachment was scrubbed... Name: cln-probs Type: application/octet-stream Size: 2428 bytes Desc: not available URL: From pearu at cens.ioc.ee Thu Nov 22 14:21:30 2001 From: pearu at cens.ioc.ee (Pearu Peterson) Date: Thu, 22 Nov 2001 15:21:30 +0200 (EET) Subject: invalid expression in content|unit|...() Message-ID: Hi, While unit-testing pyginac, I found the following inconsistency: 1) define a = symbol("a") b = symbol("b") c = constant("c") 2) observe content(2,a) -> 0 (ok) content(2*a + 4*c,a) -> 2 (ok) content(a*c,a) -> exception 'invalid expression in unit()' ?! content(a*b,a) -> b (ok) 3) similar behaviour can be observed also for other functions like unit,.. The question is: Is it possible to unify the behaviour of the relevant functions? That is, to extend them to accept other objects in addition to symbol, numeric, add, etc. Or, to raise an exception whenever there are alien object in expressions. (Though, constants should not be alien when comparing them with symbols.) My argument to consider this inconsistency as a problem is that this behaviour is confusing and could lead to difficult-to-find bugs. Thanks, Pearu From kreckel at thep.physik.uni-mainz.de Thu Nov 22 14:58:23 2001 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Thu, 22 Nov 2001 14:58:23 +0100 (CET) Subject: cln? In-Reply-To: Message-ID: On Thu, 22 Nov 2001 keith.briggs at bt.com wrote: > I wanted to install ginac1 so I had to upgrade my cln to the latest version > (I used older version ok). But it would not compile on my redhat6 system. > (see the attachment) > Any ideas? I know you are not the cln authors, but maybe you have > experience with this. > [...] > mkdir .libs > c++ -O exam.o exam_I.o exam_RA.o exam_SF.o exam_FF.o exam_DF.o exam_LF.o exam_I_gcd.o exam_I_sqrtp.o -o .libs/exam ../src/ .libs/libcln.so -lm -Wl,--rpath -Wl,/usr/local/lib > exam_I.o: In function `test_integer_plus(void)': > exam_I.o(.text+0xc1): undefined reference to `default_print_flags' > exam_I.o(.text+0xf0): undefined reference to `default_print_flags' > exam_I.o: In function `test_integer_minus(void)': > exam_I.o(.text+0x30a): undefined reference to `default_print_flags' > exam_I.o(.text+0x339): undefined reference to `default_print_flags' > exam_I.o: In function `test_integer_mul(void)': > exam_I.o(.text+0x54a): undefined reference to `default_print_flags' > exam_I.o(.text+0x579): more undefined references to `default_print_flags' follow > ../src/.libs/libcln.so: undefined reference to `cl_class_gvector_integer' > ../src/.libs/libcln.so: undefined reference to `__gmpn_add_n' > ../src/.libs/libcln.so: undefined reference to `__gmpn_addmul_1' [...] My guess is that the build-process was screwed by some improper reconfiguration. Observe that the symbol `__gmpn_add_n' should have been provided by GMP, but there is no -lgmp on the compiler command line. The other missing symbols are probably explained also by some mishap while reconfiguring. Please delete everything, unpack again, configure, make, make check, make install in that order. Does this help? Please set optimization to `-O', `-O1', `-O2' or maybe `-O2 -fno-exceptions' but *never* to `-O0' or `-O3' while compiling the library proper. The latter two do not work with the automatic module ordering scheme. Though it appears that you set `-O', which should be okay. Regards -richy. -- Richard Kreckel From cbauer at student.physik.uni-mainz.de Thu Nov 22 15:39:10 2001 From: cbauer at student.physik.uni-mainz.de (Christian Bauer) Date: Thu, 22 Nov 2001 15:39:10 +0100 Subject: invalid expression in content|unit|...() In-Reply-To: References: Message-ID: <20011122153910.A10427@student.physik.uni-mainz.de> Hi! On Thu, Nov 22, 2001 at 03:21:30PM +0200, Pearu Peterson wrote: > content(a*c,a) -> exception 'invalid expression in unit()' ?! Well, all these functions are designed to be used with polynomials with (at least) rational coefficients and the intended use for the "constant" class in GiNaC is non-rational numbers like Pi. There's always to_rational() to work around this limitation. Maybe the polynomial handling functions in GiNaC should always treat constants like symbols but this would require changing get_first_symbol() and everything that depends on it, a non-trivial change. Seeing that a constant is just a global symbol with a special evalf() behavior, maybe these two classes should be integrated better... Bye, Christian -- / Coding on PowerPC and proud of it \/ http://www.uni-mainz.de/~bauec002/ From kreckel at thep.physik.uni-mainz.de Thu Nov 22 17:38:14 2001 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Thu, 22 Nov 2001 17:38:14 +0100 (CET) Subject: Is relational::is_equal patch needed? In-Reply-To: Message-ID: On Wed, 21 Nov 2001, Pearu Peterson wrote: > > Can you send a patch? I am planning to put out 1.0.1 tomorrow. > > You can find patches attached. Features include > (aa) -> true > (a==b).is_equal(b==a) -> true > etc. > > Note that I had to introduce also > relational::calchash > such that > hash(a < b) == hash(b > a) > hash(a == b) == hash(b == a) > etc. > in order to relational::is_equal_same_type will acctually called on > (aa) > Earlier aa had different hash values and basic::is_equal used to > return false on such cases. Right, the patch looks okay. There is one minor tidbit, however: The method relational::compare_same_type() should also incorporate logic along the lines of what you did in relational::is_equal_same_type(). I have added this now and am spinning the release. Thanks a lot -richy. -- Richard B. Kreckel From kreckel at thep.physik.uni-mainz.de Thu Nov 22 18:30:59 2001 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Thu, 22 Nov 2001 18:30:59 +0100 (CET) Subject: Release 1.0.1 just hit the shelves Message-ID: Okay, before heading off to Japan with Christian we spun version 1.0.1, which fixes a few things: * Function sqrfree() handles a few more cases now. * Class relational supports real canonical ordering now (thanks to Pearu). * Handle obscene libreadline version numbers when building ginsh. This release is compatible with version 1.0.0 where compatibility is defined as on the interface and binary levels. Some computational results might differ, though, as for instance sqrfree(-y*z*x+z*x^2+z^2*x-y*z^2) will now fully factorize to z*(z+x)*(-y+x) and not get stuck with (z^2+x*z)*(x-y). Remember that we are gone for the next twelve days, so don't bother reporting bugs. IOW: We officially declare this version bug-free till then. Happy hacking -richy. -- Richard B. Kreckel From pearu at cens.ioc.ee Thu Nov 22 18:36:51 2001 From: pearu at cens.ioc.ee (Pearu Peterson) Date: Thu, 22 Nov 2001 19:36:51 +0200 (EET) Subject: invalid expression in content|unit|...() In-Reply-To: <20011122153910.A10427@student.physik.uni-mainz.de> Message-ID: On Thu, 22 Nov 2001, Christian Bauer wrote: > On Thu, Nov 22, 2001 at 03:21:30PM +0200, Pearu Peterson wrote: > > content(a*c,a) -> exception 'invalid expression in unit()' ?! > Seeing that a constant is just a global symbol with a special evalf() > behavior, maybe these two classes should be integrated better... Indeed, while wrapping GiNaC to Python, I also noticed that this is the only relevant difference. That is, in addition diff() returns always 0. I went ahead and derived constant from symbol. It was quite simple, I just had to remove some constant methods that were almost identical with the corresponding methods in symbol (there were some stylistic differences). Right now I am running checks, and if they pass, I will send patches if you are interested in. Currently it looks like with these changes GiNaC will be also backward compatible. Pearu From kreckel at thep.physik.uni-mainz.de Thu Nov 22 18:46:53 2001 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Thu, 22 Nov 2001 18:46:53 +0100 (CET) Subject: invalid expression in content|unit|...() In-Reply-To: Message-ID: Hi Pearu, On Thu, 22 Nov 2001, Pearu Peterson wrote: > On Thu, 22 Nov 2001, Christian Bauer wrote: > > > On Thu, Nov 22, 2001 at 03:21:30PM +0200, Pearu Peterson wrote: > > > content(a*c,a) -> exception 'invalid expression in unit()' ?! > > > > Seeing that a constant is just a global symbol with a special evalf() > > behavior, maybe these two classes should be integrated better... > > Indeed, while wrapping GiNaC to Python, I also noticed that this is the > only relevant difference. That is, in addition diff() returns > always 0. > > I went ahead and derived constant from symbol. It was quite simple, I just > had to remove some constant methods that were almost identical with the > corresponding methods in symbol (there were some stylistic differences). > Right now I am running checks, and if they pass, I will send patches if > you are interested in. Currently it looks like with these changes > GiNaC will be also backward compatible. We had this layout already where constant was derived from symbol and we changed it because it turned out to produce all kinds of weird problems. That seems to have been before 0.4.0, though, since I can't find it in the archives right now. Generally it is considered problematic to have a concrete class for use by folks and derive another concrete class from it. Scott Meyers discusses this in his books to some extend. >From a design perspective, I would much rather have an intermediate class derived from basic from wich both constant and numeric are derived. This class could then provide everything these two have in common. Regards -richy. -- Richard B. Kreckel From pearu at cens.ioc.ee Thu Nov 22 19:10:56 2001 From: pearu at cens.ioc.ee (Pearu Peterson) Date: Thu, 22 Nov 2001 20:10:56 +0200 (EET) Subject: invalid expression in content|unit|...() In-Reply-To: Message-ID: On Thu, 22 Nov 2001, Richard B. Kreckel wrote: > We had this layout already where constant was derived from symbol and we > changed it because it turned out to produce all kinds of weird problems. > That seems to have been before 0.4.0, though, since I can't find it in the > archives right now. Generally it is considered problematic to have a > concrete class for use by folks and derive another concrete class from it. > Scott Meyers discusses this in his books to some extend. > > >From a design perspective, I would much rather have an intermediate class > derived from basic from wich both constant and numeric are derived. This > class could then provide everything these two have in common. Ok then, but how about the following solution: remove constant class altogether and put its current initnumber/efun stuff into symbol class. Is there any reasons not to take this approach other than it would be rather radical one (and broke some codes that use constants)? Btw, there was one failure in checks caused by deriving constant from symbol. Here are relevant messages: examining indexed objects........ failed simplify_indexed(p.i^2*q.j^2-p.n^2*q.j^2)-0 erroneously returned p.i^2*q.j^2-q.i^2*p.j^2 instead of 0 Other tests passed fine. Regards, Pearu From cbauer at student.physik.uni-mainz.de Thu Nov 22 19:33:02 2001 From: cbauer at student.physik.uni-mainz.de (Christian Bauer) Date: Thu, 22 Nov 2001 19:33:02 +0100 Subject: invalid expression in content|unit|...() In-Reply-To: References: Message-ID: <20011122193302.A12756@student.physik.uni-mainz.de> Hi! On Thu, Nov 22, 2001 at 08:10:56PM +0200, Pearu Peterson wrote: > Ok then, but how about the following solution: remove constant > class altogether and put its current initnumber/efun stuff into symbol > class. This is what I had in mind. > simplify_indexed(p.i^2*q.j^2-p.n^2*q.j^2)-0 erroneously returned > p.i^2*q.j^2-q.i^2*p.j^2 instead of 0 Interesting. Maybe this is one of those checks that were never guaranteed to always work... :-) Bye, Christian -- / Coding on PowerPC and proud of it \/ http://www.uni-mainz.de/~bauec002/ From pearu at cens.ioc.ee Sun Nov 25 13:21:44 2001 From: pearu at cens.ioc.ee (Pearu Peterson) Date: Sun, 25 Nov 2001 14:21:44 +0200 (EET) Subject: Bug?: (a^b).unit(a) -> SIGSEGV Message-ID: Hi, Notice that (a^b).unit(a) leads to Segmentation fault. I have failed to track down the source of this fault in GiNaC --- I would expect that this expression should throw an exception "invalid expression in unit()", but something gets wrong elsewhere. Any ideas? Pearu For your convinience, here is a sample program: #include #include using namespace std; using namespace GiNaC; int main() { symbol a("a"),b("b"); ex e = power(a,b); cout << "e="<>> p=((x+2)**4).expand().series(x==2,3) >>> (p**2).series(x==2,4) 65536+131072*(-2+x)+114688*(-2+x)**2+Order((-2+x)**3) >>> ((p+1)**2).series(x==2,4) 66049+131584*(-2+x)+114880*(-2+x)**2+49152*(-2+x)**3+Order((-2+x)**4) which is really odd (though it can easily be a bug in pyginac...). Regards, Pearu