From kreckel at ginac.de Tue Sep 4 20:23:27 2007 From: kreckel at ginac.de (Richard B. Kreckel) Date: Tue, 04 Sep 2007 20:23:27 +0200 Subject: [GiNaC-devel] GiNaC release 1.4.0 In-Reply-To: <46D85457.1090503@physik.uni-wuppertal.de> References: <46D85457.1090503@physik.uni-wuppertal.de> Message-ID: <46DDA29F.5020402@ginac.de> Hi! Jens Vollinga wrote: > - Added programming examples in doc/examples While polishing the Debian packaging I noticed that not all CVS files in that directory made it into the released package. A minor nitpick: is it useful to provide texinfo documentation for the examples? It's not clear where to put it in a system-wide info hierarchy and if examples are ever installed into /usr/share/doc/ginac/examples/, then the info file should go there too. But info won't find there. So, a plain .txt file would suffice, IMHO. (I stumbled across this because I found ginac-examples.info in my .deb archives.) -richy. PS: Anyway, have you remembered to open the champagne? -- Richard B. Kreckel From vollinga at physik.uni-wuppertal.de Tue Sep 4 20:44:35 2007 From: vollinga at physik.uni-wuppertal.de (Jens Vollinga) Date: Tue, 04 Sep 2007 20:44:35 +0200 Subject: [GiNaC-devel] GiNaC release 1.4.0 In-Reply-To: <46DDA29F.5020402@ginac.de> References: <46D85457.1090503@physik.uni-wuppertal.de> <46DDA29F.5020402@ginac.de> Message-ID: <46DDA793.200@physik.uni-wuppertal.de> Hi, Richard B. Kreckel schrieb: > While polishing the Debian packaging I noticed that not all CVS files in > that directory made it into the released package. oh, now I checked and yes, the whole debian dir is missing! I've no explanation for that at the moment. make distcheck doesn't cover that, obviously. I will repair that. A new release shouldn't be nescessary, I think. I will just re-package the tar file. > A minor nitpick: is it useful to provide texinfo documentation for the > examples? It's not clear where to put it in a system-wide info hierarchy No, not useful. > and if examples are ever installed into /usr/share/doc/ginac/examples/, > then the info file should go there too. But info won't find there. So, a > plain .txt file would suffice, IMHO. (I stumbled across this because I > found ginac-examples.info in my .deb archives.) Good point. I will change that in CVS for the next release. > PS: Anyway, have you remembered to open the champagne? Yes, of course. But maybe should remove that step from the release procedure. That stupid bottle just sits there next to all the other bottles and does nothing! What's the point?!? Regards, Jens From vollinga at physik.uni-wuppertal.de Tue Sep 4 20:48:35 2007 From: vollinga at physik.uni-wuppertal.de (Jens Vollinga) Date: Tue, 04 Sep 2007 20:48:35 +0200 Subject: [GiNaC-devel] GiNaC release 1.4.0 In-Reply-To: <46DDA793.200@physik.uni-wuppertal.de> References: <46D85457.1090503@physik.uni-wuppertal.de> <46DDA29F.5020402@ginac.de> <46DDA793.200@physik.uni-wuppertal.de> Message-ID: <46DDA883.70806@physik.uni-wuppertal.de> Hi again, the explanation for the missing files is: I did an VPATH build! This does not go well with make distcheck ... Regards, Jens From vollinga at physik.uni-wuppertal.de Tue Sep 4 21:34:14 2007 From: vollinga at physik.uni-wuppertal.de (Jens Vollinga) Date: Tue, 04 Sep 2007 21:34:14 +0200 Subject: [GiNaC-devel] GiNaC release 1.4.0 In-Reply-To: <46DDA29F.5020402@ginac.de> References: <46D85457.1090503@physik.uni-wuppertal.de> <46DDA29F.5020402@ginac.de> Message-ID: <46DDB336.9040909@physik.uni-wuppertal.de> Hi once again, Richard B. Kreckel schrieb: > Jens Vollinga wrote: >> - Added programming examples in doc/examples > > While polishing the Debian packaging I noticed that not all CVS files in > that directory made it into the released package. ok, forget my last two emails, I completely misunderstood the thing. I added the examples now to CVS. What do you recommend: a new version number? just re-packaging? Regards, Jens From kreckel at ginac.de Tue Sep 4 22:09:04 2007 From: kreckel at ginac.de (Richard B. Kreckel) Date: Tue, 04 Sep 2007 22:09:04 +0200 Subject: [GiNaC-devel] GiNaC release 1.4.0 In-Reply-To: <46DDB336.9040909@physik.uni-wuppertal.de> References: <46D85457.1090503@physik.uni-wuppertal.de> <46DDA29F.5020402@ginac.de> <46DDB336.9040909@physik.uni-wuppertal.de> Message-ID: <46DDBB60.3040900@ginac.de> Jens Vollinga wrote: > ok, forget my last two emails, I completely misunderstood the thing. I > added the examples now to CVS. Phew! > What do you recommend: a new version number? just re-packaging? Uhm, I do dislike repackaging without changing the version number. One never knows what ways that tarball took in the meanwhile (it could've been sitting in the Debian archives already) and diffs have a potential to cause confusion later on. And I don't think missing example files warrant a new release anyway. Can the issue just be ignored until the next release is rolled anyway? Cheers -richy. PS: I think we should meet and talk about that bottle. -- Richard B. Kreckel From varg at theor.jinr.ru Wed Sep 5 07:52:05 2007 From: varg at theor.jinr.ru (Alexei Sheplyakov) Date: Wed, 5 Sep 2007 09:52:05 +0400 Subject: [GiNaC-devel] [PATCH] INSTALL: do not mention nonexisting autogen.sh Message-ID: <20070905055205.GA25433@theor.jinr.ru> That file was removed a long time ago, so... --- INSTALL | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/INSTALL b/INSTALL index 2c60d2d..1fda652 100644 --- a/INSTALL +++ b/INSTALL @@ -60,9 +60,8 @@ library works correctly you can use $ make check -The "configure" script (and "autogen.sh", which invokes "configure") can be -given a number of options to enable and disable various features. For a -complete list, type: +The "configure" script can be given a number of options to enable and +disable various features. For a complete list, type: $ ./configure --help -- 1.4.4.4 Best regards, Alexei -- All science is either physics or stamp collecting. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 827 bytes Desc: Digital signature URL: From varg at theor.jinr.ru Wed Sep 5 08:52:57 2007 From: varg at theor.jinr.ru (Alexei Sheplyakov) Date: Wed, 5 Sep 2007 10:52:57 +0400 Subject: [GiNaC-devel] [PATCH] Add self-contained example of a GiNaC class. Message-ID: <20070905065257.GA28224@theor.jinr.ru> Hello! Some people claim that extending GiNaC is "unnecessary complex" (see e.g. http://www.ginac.de/pipermail/ginac-list/2006-July/000882.html). So I think it is good idea to provide self-contained, minimalistic example of a GiNaC class. The actual code is copy/pasted from the tutorial. --- doc/examples/Makefile.am | 3 +- doc/examples/mystring.cpp | 104 +++++++++++++++++++++++++++++++++++++++++++++ doc/tutorial/ginac.texi | 3 +- 3 files changed, 108 insertions(+), 2 deletions(-) diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am index 5ee2c5d..e63da35 100644 --- a/doc/examples/Makefile.am +++ b/doc/examples/Makefile.am @@ -1,6 +1,7 @@ ## Process this file with automake to produce Makefile.in -EXFILES = archive1.cpp compile1.cpp compile2.cpp compile3.cpp lanczos.cpp +EXFILES = archive1.cpp compile1.cpp compile2.cpp compile3.cpp lanczos.cpp \ + mystring.cpp TEXI = ginac-examples.texi diff --git a/doc/examples/mystring.cpp b/doc/examples/mystring.cpp new file mode 100644 index 0000000..cf0d8a2 --- /dev/null +++ b/doc/examples/mystring.cpp @@ -0,0 +1,104 @@ +/** + * @file mystring.cpp Example of extending GiNaC: writing new classes + */ +#include +#include +#include +using namespace std; + +#include +using namespace GiNaC; + +class mystring : public basic +{ + GINAC_DECLARE_REGISTERED_CLASS(mystring, basic) + +public: + mystring(const string &s); + mystring(const char *s); + ex eval(int level) const; + +private: + string str; + +protected: + void do_print(const print_context &c, unsigned level = 0) const; + +}; + +GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(mystring, basic, + print_func(&mystring::do_print)) + +// ctors +mystring::mystring() : inherited(&mystring::tinfo_static) { } +mystring::mystring(const string &s) : inherited(&mystring::tinfo_static), str(s) { } +mystring::mystring(const char *s) : inherited(&mystring::tinfo_static), str(s) { } + +// comparison +int mystring::compare_same_type(const basic &other) const +{ + const mystring &o = static_cast(other); + int cmpval = str.compare(o.str); + if (cmpval == 0) + return 0; + else if (cmpval < 0) + return -1; + else + return 1; +} + +// archiving/unarchiving +mystring::mystring(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst) +{ + n.find_string("string", str); +} + +void mystring::archive(archive_node &n) const +{ + inherited::archive(n); + n.add_string("string", str); +} + +ex mystring::unarchive(const archive_node &n, lst &sym_lst) +{ + return (new mystring(n, sym_lst))->setflag(status_flags::dynallocated); +} + +// printing +void mystring::do_print(const print_context &c, unsigned level) const +{ + // print_context::s is a reference to an ostream + c.s << '\"' << str << '\"'; +} + +/** + * evaluation: all strings automatically converted to lowercase with + * non-alphabetic characters stripped, and empty strings removed + */ +ex mystring::eval(int level) const +{ + string new_str; + for (size_t i=0; i= 'A' && c <= 'Z') + new_str += tolower(c); + else if (c >= 'a' && c <= 'z') + new_str += c; + } + + if (new_str.length() == 0) + return 0; + else + return mystring(new_str).hold(); +} + +int main(int argc, char** argv) +{ + ex e = mystring("Hello, world!"); + cout << is_a(e) << endl; + cout << ex_to(e).class_name() << endl; + cout << e << endl; + ex another = pow(mystring("One string"), 2*sin(Pi-mystring("Another string"))); + cout << another << endl; + return 0; +} diff --git a/doc/tutorial/ginac.texi b/doc/tutorial/ginac.texi index a6befad..b2038db 100644 --- a/doc/tutorial/ginac.texi +++ b/doc/tutorial/ginac.texi @@ -7823,7 +7823,8 @@ Now we will start implementing a new class @code{mystring} that allows placing character strings in algebraic expressions (this is not very useful, but it's just an example). This class will be a direct subclass of @code{basic}. You can use this sample implementation as a starting point -for your own classes. +for your own classes @footnote{The self-contained source for this example is +included in GiNaC, see the @file{doc/examples/mystring.cpp} file.}. The code snippets given here assume that you have included some header files as follows: -- 1.4.4.4 Best regards, Alexei -- All science is either physics or stamp collecting. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 827 bytes Desc: Digital signature URL: From varg at theor.jinr.ru Wed Sep 5 09:30:32 2007 From: varg at theor.jinr.ru (Alexei Sheplyakov) Date: Wed, 5 Sep 2007 11:30:32 +0400 Subject: [GiNaC-devel] [PATCH] improved CLN C++ code output Message-ID: <20070905073032.GA425@theor.jinr.ru> * small integers are printed as int (not as cl_I) * no more ugly x+-y output * powers always printed using cln::expt function. Please note: this patch is for development branch only, since it breaks binary compatibility (due to power::do_print_csrc_cl_N). I'll post patches for GiNaC 1.[34] later. --- ginac/add.cpp | 34 +++++++++++++++------------------- ginac/numeric.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++----- ginac/power.cpp | 35 +++++++++++++++++++++-------------- ginac/power.h | 1 + 4 files changed, 83 insertions(+), 38 deletions(-) diff --git a/ginac/add.cpp b/ginac/add.cpp index b37ab79..98e8c79 100644 --- a/ginac/add.cpp +++ b/ginac/add.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "add.h" #include "mul.h" @@ -172,37 +173,32 @@ void add::do_print_csrc(const print_csrc & c, unsigned level) const if (precedence() <= level) c.s << "("; - // Print arguments, separated by "+" + // Print arguments, separated by "+" or "-" epvector::const_iterator it = seq.begin(), itend = seq.end(); + char separator = ' '; while (it != itend) { - // If the coefficient is -1, it is replaced by a single minus sign - if (it->coeff.is_equal(_ex1)) { + // If the coefficient is negative, separator is "-" + if (it->coeff.is_equal(_ex_1) || + ex_to(it->coeff).numer().is_equal(*_num_1_p)) + separator = '-'; + c.s << separator; + if (it->coeff.is_equal(_ex1) || it->coeff.is_equal(_ex_1)) { it->rest.print(c, precedence()); - } else if (it->coeff.is_equal(_ex_1)) { - c.s << "-"; + } else if (ex_to(it->coeff).numer().is_equal(*_num1_p) || + ex_to(it->coeff).numer().is_equal(*_num_1_p)) + { it->rest.print(c, precedence()); - } else if (ex_to(it->coeff).numer().is_equal(*_num1_p)) { - it->rest.print(c, precedence()); - c.s << "/"; - ex_to(it->coeff).denom().print(c, precedence()); - } else if (ex_to(it->coeff).numer().is_equal(*_num_1_p)) { - c.s << "-"; - it->rest.print(c, precedence()); - c.s << "/"; + c.s << '/'; ex_to(it->coeff).denom().print(c, precedence()); } else { it->coeff.print(c, precedence()); - c.s << "*"; + c.s << '*'; it->rest.print(c, precedence()); } - // Separator is "+", except if the following expression would have a leading minus sign or the sign is sitting in parenthesis (as in a ctor) ++it; - if (it != itend - && (is_a(c) || !it->coeff.info(info_flags::real) // sign inside ctor arguments - || !(it->coeff.info(info_flags::negative) || (it->coeff.is_equal(*_num1_p) && is_exactly_a(it->rest) && it->rest.info(info_flags::negative))))) - c.s << "+"; + separator = '+'; } if (!overall_coeff.is_zero()) { diff --git a/ginac/numeric.cpp b/ginac/numeric.cpp index ef61ce7..74f0e50 100644 --- a/ginac/numeric.cpp +++ b/ginac/numeric.cpp @@ -399,6 +399,38 @@ static void print_real_csrc(const print_context & c, const cln::cl_R & x) } } +template +static inline bool coerce(T1& dst, const T2& arg); + +/** + * @brief Check if CLN integer can be converted into int + * + * @sa http://www.ginac.de/pipermail/cln-list/2006-October/000248.html + */ +template<> static inline bool +coerce(int& dst, const cln::cl_I& arg) { + static const cln::cl_I cl_max_int = + (cln::cl_I)(long)(std::numeric_limits::max()); + static const cln::cl_I cl_min_int = + (cln::cl_I)(long)(std::numeric_limits::min()); + if ((arg >= cl_min_int) && (arg <= cl_max_int)) { + dst = cl_I_to_int(arg); + return true; + } + return false; +} + +template<> static inline bool +coerce(unsigned int& dst, const cln::cl_I& arg) { + static const cln::cl_I cl_max_uint = + (cln::cl_I)(unsigned long)(std::numeric_limits::max()); + if ((! minusp(arg)) && (arg <= cl_max_uint)) { + dst = cl_I_to_uint(arg); + return true; + } + return false; +} + /** Helper function to print real number in C++ source format using cl_N types. * * @see numeric::print() */ @@ -406,11 +438,20 @@ static void print_real_cl_N(const print_context & c, const cln::cl_R & x) { if (cln::instanceof(x, cln::cl_I_ring)) { - // Integer number - c.s << "cln::cl_I(\""; - print_real_number(c, x); - c.s << "\")"; - + int dst; + // fixnum + if (coerce(dst, cln::the(x))) { + // can be converted to native int + if (dst < 0) + c.s << "(-" << dst << ")"; + else + c.s << dst; + } else { + // bignum + c.s << "cln::cl_I(\""; + print_real_number(c, x); + c.s << "\")"; + } } else if (cln::instanceof(x, cln::cl_RA_ring)) { // Rational number diff --git a/ginac/power.cpp b/ginac/power.cpp index faa0d05..68bec71 100644 --- a/ginac/power.cpp +++ b/ginac/power.cpp @@ -50,7 +50,8 @@ GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(power, basic, print_func(&power::do_print_latex). print_func(&power::do_print_csrc). print_func(&power::do_print_python). - print_func(&power::do_print_python_repr)) + print_func(&power::do_print_python_repr). + print_func(&power::do_print_csrc_cl_N)) typedef std::vector intvector; @@ -162,6 +163,21 @@ static void print_sym_pow(const print_context & c, const symbol &x, int exp) } } +void power::do_print_csrc_cl_N(const print_csrc_cl_N& c, unsigned level) const +{ + if (exponent.is_equal(_ex_1)) { + c.s << "recip("; + basis.print(c); + c.s << ')'; + return; + } + c.s << "expt("; + basis.print(c); + c.s << ", "; + exponent.print(c); + c.s << ')'; +} + void power::do_print_csrc(const print_csrc & c, unsigned level) const { // Integer powers of symbols are printed in a special, optimized way @@ -172,29 +188,20 @@ void power::do_print_csrc(const print_csrc & c, unsigned level) const c.s << '('; else { exp = -exp; - if (is_a(c)) - c.s << "recip("; - else - c.s << "1.0/("; + c.s << "1.0/("; } print_sym_pow(c, ex_to(basis), exp); c.s << ')'; // ^-1 is printed as "1.0/" or with the recip() function of CLN } else if (exponent.is_equal(_ex_1)) { - if (is_a(c)) - c.s << "recip("; - else - c.s << "1.0/("; + c.s << "1.0/("; basis.print(c); c.s << ')'; - // Otherwise, use the pow() or expt() (CLN) functions + // Otherwise, use the pow() function } else { - if (is_a(c)) - c.s << "expt("; - else - c.s << "pow("; + c.s << "pow("; basis.print(c); c.s << ','; exponent.print(c); diff --git a/ginac/power.h b/ginac/power.h index f5e65d6..3375040 100644 --- a/ginac/power.h +++ b/ginac/power.h @@ -88,6 +88,7 @@ protected: void do_print_csrc(const print_csrc & c, unsigned level) const; void do_print_python(const print_python & c, unsigned level) const; void do_print_python_repr(const print_python_repr & c, unsigned level) const; + void do_print_csrc_cl_N(const print_csrc_cl_N & c, unsigned level) const; ex expand_add(const add & a, int n, unsigned options) const; ex expand_add_2(const add & a, unsigned options) const; -- 1.4.4.4 Best regards, Alexei -- All science is either physics or stamp collecting. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 827 bytes Desc: Digital signature URL: From varg at theor.jinr.ru Wed Sep 5 10:41:51 2007 From: varg at theor.jinr.ru (Alexei Sheplyakov) Date: Wed, 5 Sep 2007 12:41:51 +0400 Subject: [GiNaC-devel] [PATCH] Improved CLN C++ code output (print_csrc_cln), for GiNaC 1.4 In-Reply-To: <20070905073032.GA425@theor.jinr.ru> Message-ID: <20070905084151.GA6743@theor.jinr.ru> * small integers are printed as int (not as cl_I) * no more ugly x+-y output * powers always printed using cln::expt function. --- ginac/add.cpp | 34 +++++++++++++++------------------- ginac/numeric.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++----- ginac/power.cpp | 32 +++++++++++++++++++------------- 3 files changed, 80 insertions(+), 37 deletions(-) diff --git a/ginac/add.cpp b/ginac/add.cpp index b37ab79..98e8c79 100644 --- a/ginac/add.cpp +++ b/ginac/add.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "add.h" #include "mul.h" @@ -172,37 +173,32 @@ void add::do_print_csrc(const print_csrc & c, unsigned level) const if (precedence() <= level) c.s << "("; - // Print arguments, separated by "+" + // Print arguments, separated by "+" or "-" epvector::const_iterator it = seq.begin(), itend = seq.end(); + char separator = ' '; while (it != itend) { - // If the coefficient is -1, it is replaced by a single minus sign - if (it->coeff.is_equal(_ex1)) { + // If the coefficient is negative, separator is "-" + if (it->coeff.is_equal(_ex_1) || + ex_to(it->coeff).numer().is_equal(*_num_1_p)) + separator = '-'; + c.s << separator; + if (it->coeff.is_equal(_ex1) || it->coeff.is_equal(_ex_1)) { it->rest.print(c, precedence()); - } else if (it->coeff.is_equal(_ex_1)) { - c.s << "-"; + } else if (ex_to(it->coeff).numer().is_equal(*_num1_p) || + ex_to(it->coeff).numer().is_equal(*_num_1_p)) + { it->rest.print(c, precedence()); - } else if (ex_to(it->coeff).numer().is_equal(*_num1_p)) { - it->rest.print(c, precedence()); - c.s << "/"; - ex_to(it->coeff).denom().print(c, precedence()); - } else if (ex_to(it->coeff).numer().is_equal(*_num_1_p)) { - c.s << "-"; - it->rest.print(c, precedence()); - c.s << "/"; + c.s << '/'; ex_to(it->coeff).denom().print(c, precedence()); } else { it->coeff.print(c, precedence()); - c.s << "*"; + c.s << '*'; it->rest.print(c, precedence()); } - // Separator is "+", except if the following expression would have a leading minus sign or the sign is sitting in parenthesis (as in a ctor) ++it; - if (it != itend - && (is_a(c) || !it->coeff.info(info_flags::real) // sign inside ctor arguments - || !(it->coeff.info(info_flags::negative) || (it->coeff.is_equal(*_num1_p) && is_exactly_a(it->rest) && it->rest.info(info_flags::negative))))) - c.s << "+"; + separator = '+'; } if (!overall_coeff.is_zero()) { diff --git a/ginac/numeric.cpp b/ginac/numeric.cpp index ef61ce7..74f0e50 100644 --- a/ginac/numeric.cpp +++ b/ginac/numeric.cpp @@ -399,6 +399,38 @@ static void print_real_csrc(const print_context & c, const cln::cl_R & x) } } +template +static inline bool coerce(T1& dst, const T2& arg); + +/** + * @brief Check if CLN integer can be converted into int + * + * @sa http://www.ginac.de/pipermail/cln-list/2006-October/000248.html + */ +template<> static inline bool +coerce(int& dst, const cln::cl_I& arg) { + static const cln::cl_I cl_max_int = + (cln::cl_I)(long)(std::numeric_limits::max()); + static const cln::cl_I cl_min_int = + (cln::cl_I)(long)(std::numeric_limits::min()); + if ((arg >= cl_min_int) && (arg <= cl_max_int)) { + dst = cl_I_to_int(arg); + return true; + } + return false; +} + +template<> static inline bool +coerce(unsigned int& dst, const cln::cl_I& arg) { + static const cln::cl_I cl_max_uint = + (cln::cl_I)(unsigned long)(std::numeric_limits::max()); + if ((! minusp(arg)) && (arg <= cl_max_uint)) { + dst = cl_I_to_uint(arg); + return true; + } + return false; +} + /** Helper function to print real number in C++ source format using cl_N types. * * @see numeric::print() */ @@ -406,11 +438,20 @@ static void print_real_cl_N(const print_context & c, const cln::cl_R & x) { if (cln::instanceof(x, cln::cl_I_ring)) { - // Integer number - c.s << "cln::cl_I(\""; - print_real_number(c, x); - c.s << "\")"; - + int dst; + // fixnum + if (coerce(dst, cln::the(x))) { + // can be converted to native int + if (dst < 0) + c.s << "(-" << dst << ")"; + else + c.s << dst; + } else { + // bignum + c.s << "cln::cl_I(\""; + print_real_number(c, x); + c.s << "\")"; + } } else if (cln::instanceof(x, cln::cl_RA_ring)) { // Rational number diff --git a/ginac/power.cpp b/ginac/power.cpp index faa0d05..b490b8c 100644 --- a/ginac/power.cpp +++ b/ginac/power.cpp @@ -164,6 +164,21 @@ static void print_sym_pow(const print_context & c, const symbol &x, int exp) void power::do_print_csrc(const print_csrc & c, unsigned level) const { + if (is_a(c)) { + if (exponent.is_equal(_ex_1)) { + c.s << "recip("; + basis.print(c); + c.s << ')'; + return; + } + c.s << "expt("; + basis.print(c); + c.s << ", "; + exponent.print(c); + c.s << ')'; + return; + } + // Integer powers of symbols are printed in a special, optimized way if (exponent.info(info_flags::integer) && (is_a(basis) || is_a(basis))) { @@ -172,29 +187,20 @@ void power::do_print_csrc(const print_csrc & c, unsigned level) const c.s << '('; else { exp = -exp; - if (is_a(c)) - c.s << "recip("; - else - c.s << "1.0/("; + c.s << "1.0/("; } print_sym_pow(c, ex_to(basis), exp); c.s << ')'; // ^-1 is printed as "1.0/" or with the recip() function of CLN } else if (exponent.is_equal(_ex_1)) { - if (is_a(c)) - c.s << "recip("; - else - c.s << "1.0/("; + c.s << "1.0/("; basis.print(c); c.s << ')'; - // Otherwise, use the pow() or expt() (CLN) functions + // Otherwise, use the pow() function } else { - if (is_a(c)) - c.s << "expt("; - else - c.s << "pow("; + c.s << "pow("; basis.print(c); c.s << ','; exponent.print(c); -- 1.4.4.4 Best regards, Alexei -- All science is either physics or stamp collecting. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 827 bytes Desc: Digital signature URL: From varg at theor.jinr.ru Wed Sep 5 10:43:06 2007 From: varg at theor.jinr.ru (Alexei Sheplyakov) Date: Wed, 5 Sep 2007 12:43:06 +0400 Subject: [GiNaC-devel] [PATCH] Improved CLN C++ code output (print_csrc_cln) for GiNaC 1.3 In-Reply-To: <20070905073032.GA425@theor.jinr.ru> Message-ID: <20070905084306.GA7007@theor.jinr.ru> * small integers are printed as int (not as cl_I) * no more ugly x+-y output * powers always printed using cln::expt function. --- ginac/add.cpp | 34 +++++++++++++++------------------- ginac/numeric.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++----- ginac/power.cpp | 32 +++++++++++++++++++------------- 3 files changed, 80 insertions(+), 37 deletions(-) diff --git a/ginac/add.cpp b/ginac/add.cpp index 067f9bf..4fd10d9 100644 --- a/ginac/add.cpp +++ b/ginac/add.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "add.h" #include "mul.h" @@ -170,37 +171,32 @@ void add::do_print_csrc(const print_csrc & c, unsigned level) const if (precedence() <= level) c.s << "("; - // Print arguments, separated by "+" + // Print arguments, separated by "+" or "-" epvector::const_iterator it = seq.begin(), itend = seq.end(); + char separator = ' '; while (it != itend) { - // If the coefficient is -1, it is replaced by a single minus sign - if (it->coeff.is_equal(_ex1)) { + // If the coefficient is negative, separator is "-" + if (it->coeff.is_equal(_ex_1) || + ex_to(it->coeff).numer().is_equal(*_num_1_p)) + separator = '-'; + c.s << separator; + if (it->coeff.is_equal(_ex1) || it->coeff.is_equal(_ex_1)) { it->rest.print(c, precedence()); - } else if (it->coeff.is_equal(_ex_1)) { - c.s << "-"; + } else if (ex_to(it->coeff).numer().is_equal(*_num1_p) || + ex_to(it->coeff).numer().is_equal(*_num_1_p)) + { it->rest.print(c, precedence()); - } else if (ex_to(it->coeff).numer().is_equal(*_num1_p)) { - it->rest.print(c, precedence()); - c.s << "/"; - ex_to(it->coeff).denom().print(c, precedence()); - } else if (ex_to(it->coeff).numer().is_equal(*_num_1_p)) { - c.s << "-"; - it->rest.print(c, precedence()); - c.s << "/"; + c.s << '/'; ex_to(it->coeff).denom().print(c, precedence()); } else { it->coeff.print(c, precedence()); - c.s << "*"; + c.s << '*'; it->rest.print(c, precedence()); } - // Separator is "+", except if the following expression would have a leading minus sign or the sign is sitting in parenthesis (as in a ctor) ++it; - if (it != itend - && (is_a(c) || !it->coeff.info(info_flags::real) // sign inside ctor arguments - || !(it->coeff.info(info_flags::negative) || (it->coeff.is_equal(*_num1_p) && is_exactly_a(it->rest) && it->rest.info(info_flags::negative))))) - c.s << "+"; + separator = '+'; } if (!overall_coeff.is_zero()) { diff --git a/ginac/numeric.cpp b/ginac/numeric.cpp index 208a89c..7640670 100644 --- a/ginac/numeric.cpp +++ b/ginac/numeric.cpp @@ -399,6 +399,38 @@ static void print_real_csrc(const print_context & c, const cln::cl_R & x) } } +template +static inline bool coerce(T1& dst, const T2& arg); + +/** + * @brief Check if CLN integer can be converted into int + * + * @sa http://www.ginac.de/pipermail/cln-list/2006-October/000248.html + */ +template<> static inline bool +coerce(int& dst, const cln::cl_I& arg) { + static const cln::cl_I cl_max_int = + (cln::cl_I)(long)(std::numeric_limits::max()); + static const cln::cl_I cl_min_int = + (cln::cl_I)(long)(std::numeric_limits::min()); + if ((arg >= cl_min_int) && (arg <= cl_max_int)) { + dst = cl_I_to_int(arg); + return true; + } + return false; +} + +template<> static inline bool +coerce(unsigned int& dst, const cln::cl_I& arg) { + static const cln::cl_I cl_max_uint = + (cln::cl_I)(unsigned long)(std::numeric_limits::max()); + if ((! minusp(arg)) && (arg <= cl_max_uint)) { + dst = cl_I_to_uint(arg); + return true; + } + return false; +} + /** Helper function to print real number in C++ source format using cl_N types. * * @see numeric::print() */ @@ -406,11 +438,20 @@ static void print_real_cl_N(const print_context & c, const cln::cl_R & x) { if (cln::instanceof(x, cln::cl_I_ring)) { - // Integer number - c.s << "cln::cl_I(\""; - print_real_number(c, x); - c.s << "\")"; - + int dst; + // fixnum + if (coerce(dst, cln::the(x))) { + // can be converted to native int + if (dst < 0) + c.s << "(-" << dst << ")"; + else + c.s << dst; + } else { + // bignum + c.s << "cln::cl_I(\""; + print_real_number(c, x); + c.s << "\")"; + } } else if (cln::instanceof(x, cln::cl_RA_ring)) { // Rational number diff --git a/ginac/power.cpp b/ginac/power.cpp index 4ebf0ac..f243147 100644 --- a/ginac/power.cpp +++ b/ginac/power.cpp @@ -164,6 +164,21 @@ static void print_sym_pow(const print_context & c, const symbol &x, int exp) void power::do_print_csrc(const print_csrc & c, unsigned level) const { + if (is_a(c)) { + if (exponent.is_equal(_ex_1)) { + c.s << "recip("; + basis.print(c); + c.s << ')'; + return; + } + c.s << "expt("; + basis.print(c); + c.s << ", "; + exponent.print(c); + c.s << ')'; + return; + } + // Integer powers of symbols are printed in a special, optimized way if (exponent.info(info_flags::integer) && (is_a(basis) || is_a(basis))) { @@ -172,29 +187,20 @@ void power::do_print_csrc(const print_csrc & c, unsigned level) const c.s << '('; else { exp = -exp; - if (is_a(c)) - c.s << "recip("; - else - c.s << "1.0/("; + c.s << "1.0/("; } print_sym_pow(c, ex_to(basis), exp); c.s << ')'; // ^-1 is printed as "1.0/" or with the recip() function of CLN } else if (exponent.is_equal(_ex_1)) { - if (is_a(c)) - c.s << "recip("; - else - c.s << "1.0/("; + c.s << "1.0/("; basis.print(c); c.s << ')'; - // Otherwise, use the pow() or expt() (CLN) functions + // Otherwise, use the pow() function } else { - if (is_a(c)) - c.s << "expt("; - else - c.s << "pow("; + c.s << "pow("; basis.print(c); c.s << ','; exponent.print(c); -- 1.4.4.4 Best regards, Alexei -- All science is either physics or stamp collecting. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 827 bytes Desc: Digital signature URL: From varg at theor.jinr.ru Wed Sep 5 15:07:36 2007 From: varg at theor.jinr.ru (Sheplyakov Alexei) Date: Wed, 5 Sep 2007 17:07:36 +0400 Subject: [GiNaC-devel] Volunteer to continue the work on NTL factorisation bindings In-Reply-To: <200708281802.09118.R.Bloemen@student.utwente.nl> References: <200708281802.09118.R.Bloemen@student.utwente.nl> Message-ID: <20070905130736.GA25958@theor.jinr.ru> Hello! On Tue, Aug 28, 2007 at 06:02:08PM +0200, Remco Bloemen wrote: > I have created a simple factorisation for polynomials in Q[x] with real roots > (source attached, based on [2]) but it's really slow. I _think_ there are two reasons for that. First, GiNaC::add and GiNaC::mul are way to abstract to repersent polynomials (especially univariate ones) efficiently. For example, this snippet of code > if(is_exactly_a(poly)) > { > ex result = 0; > for (size_t i=0; i < poly.nops(); i++) > { > result += polymod2n(poly.op(i), n); > } > return result; > } involves N = poly.nops() calls to add.eval(), each of them is O(N). poly.op(i) is O(N) too. So, you'd better use std::vector to represent univariate polynomials: void mod2n(std::vector& result, std::vector& poly, const unsigned int n) { result.reserve(poly.size()); cln::cl_modint_ring R(cln::cl_I(1) << n); for (std::size_t i = 0; i < poly.size(); ++i) result.push_back(R.canonhom(poly[i])); } Secondly, your implementation of mod 2^n arithmetic is really far from optimal. > numeric mod2n(const numeric &p, const int n) > { > numeric modulus = pow(numeric(2), numeric(n)); > return mod(p, modulus); > } Operations on mod 2^n integers and polynomials can (and should) be done using bit shifts (a very fast operation). Actually this is why yacas (and some other software) use them in first place. So, it should be static inline const cln::cl_MI mod2n(const cln::cl_I& p, const unsigned int n) { cln::cl_modint_ring R(cln::cl_I(1) << n); return R.canonhom(p); } > Creating a reasonable implementation would require much work. Sure. > An NTL based implementation would be very powerfull and feasible, as said in > [1]. I would like to volunteer to continue this work. IMHO, using two different bignum libraries and converting expressions (and numbers) between them is a bad idea. Much better option is to port NTL's algorithms to CLN. Best regards, Alexei -- All science is either physics or stamp collecting. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 827 bytes Desc: Digital signature URL: From remco.bloemen at gmail.com Thu Sep 6 14:20:08 2007 From: remco.bloemen at gmail.com (Remco Bloemen) Date: Thu, 6 Sep 2007 14:20:08 +0200 Subject: [GiNaC-devel] Volunteer to continue the work on NTL factorisation bindings In-Reply-To: <20070905130736.GA25958@theor.jinr.ru> References: <200708281802.09118.R.Bloemen@student.utwente.nl> <20070905130736.GA25958@theor.jinr.ru> Message-ID: <200709061420.08784.R.Bloemen@student.utwente.nl> Alexei, First of all, thank you very much for looking at my code and giving good pointers! It really makes a newcomer feel appreciated. On Wednesday 05 September 2007 15:07:36 Sheplyakov Alexei wrote: > On Tue, Aug 28, 2007 at 06:02:08PM +0200, Remco Bloemen wrote: > > I have created a simple factorisation for polynomials in Q[x] with real > > roots (source attached, based on [2]) but it's really slow. > > I _think_ there are two reasons for that. First, GiNaC::add and GiNaC::mul > are way to abstract to repersent polynomials (especially univariate ones) > efficiently. Your suggestion of using std::vector was already on my mind, I will certainly implement it. It's just that I wanted to evaluate the NTL way before I would spent time improving my own humble factorizer. > Secondly, your implementation of mod 2^n arithmetic is really > far from optimal. Yes, I am aware of that. I wrote the *2n functions as a temporary solution, mainly because I did not know how to do it efficiently using CLN. Your examples teach me that this can be easily done. > > An NTL based implementation would be very powerfull and feasible, as said > > in [1]. I would like to volunteer to continue this work. > > IMHO, using two different bignum libraries and converting expressions (and > numbers) between them is a bad idea. Much better option is to port NTL's > algorithms to CLN. I also looked at Singular and I came to the same conclusion that it would be best to port the algorithms. The main reasons was that NTL only supports univariate integer factorization and that is only a fairly small (though performance-wise important) part of full multivariate polynomial factorization over extension fields. Kind regards, Remco From varg at theor.jinr.ru Mon Sep 17 15:15:03 2007 From: varg at theor.jinr.ru (Alexei Sheplyakov) Date: Mon, 17 Sep 2007 17:15:03 +0400 Subject: [GiNaC-devel] Restore the speed of polynomial operations. Message-ID: Hello! These patches commit 0633ed8082961673eedc092689e06fa39d6bc322 Author: Jens Vollinga Date: Thu May 19 18:10:40 2005 +0000 Fixed bug in expanding expressions containing dummy indices. [V.Kisil] (see ) commit 6b1b11264fe4872132fef8cb8b22cb983ba01736 Author: Chris Dams Date: Thu Jul 13 20:02:38 2006 +0000 Needed to call get_all_dummy_indices_safely more often. (see http://www.ginac.de/pipermail/ginac-cvs/2006-July/001780.html) commit 4cf53676d7823ec3c55a90df7723f7f1492a95b2 Author: Chris Dams Date: Mon Jul 24 16:47:43 2006 +0000 Improved dummy index renaming. (see http://www.ginac.de/pipermail/ginac-cvs/2006-July/001782.html) made polynomial operations (in particular expand()) substantially slower. For example, Fateman's polynomial expanding benchark degraded from 32sec. to 80sec. My own code which uses multivariate GCD (which in turn uses .expand() extensively) become 4x slower. I'll post 4 patches which address the issue in reply to this message. Comments, questions, suggestions, etc. are wellcome. Best regards, Alexei -- All science is either physics or stamp collecting. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 827 bytes Desc: Digital signature URL: From varg at theor.jinr.ru Mon Sep 17 15:18:24 2007 From: varg at theor.jinr.ru (Alexei Sheplyakov) Date: Mon, 17 Sep 2007 17:18:24 +0400 Subject: [GiNaC-devel] [PATCH 1/4] Improve info(info_flags::has_indices), introduce flags to cache the result. In-Reply-To: References: Message-ID: info(info_flags::has_indices) now works for sums and products. It returns true if the expression has indices (no matter dummy or free), and false otherwise. --- ginac/expairseq.cpp | 23 +++++++++++++++++++++-- ginac/flags.h | 4 +++- ginac/idx.cpp | 7 +++++-- ginac/power.cpp | 15 +++++++++++++++ ginac/symbol.cpp | 35 +++++++++++++++++++---------------- 5 files changed, 63 insertions(+), 21 deletions(-) diff --git a/ginac/expairseq.cpp b/ginac/expairseq.cpp index 757f3c3..79c741a 100644 --- a/ginac/expairseq.cpp +++ b/ginac/expairseq.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "expairseq.h" #include "lst.h" @@ -267,8 +268,26 @@ void expairseq::do_print_tree(const print_tree & c, unsigned level) const bool expairseq::info(unsigned inf) const { - if (inf == info_flags::expanded) - return (flags & status_flags::expanded); + switch(inf) { + case info_flags::expanded: + return (flags & status_flags::expanded); + case info_flags::has_indices: { + if (flags & status_flags::has_indices) + return true; + else if (flags & status_flags::has_no_indices) + return false; + for (epvector::const_iterator i = seq.begin(); i != seq.end(); ++i) { + if (i->rest.info(info_flags::has_indices)) { + this->setflag(status_flags::has_indices); + this->clearflag(status_flags::has_no_indices); + return true; + } + } + this->clearflag(status_flags::has_indices); + this->setflag(status_flags::has_no_indices); + return false; + } + } return inherited::info(inf); } diff --git a/ginac/flags.h b/ginac/flags.h index 86d8238..372b899 100644 --- a/ginac/flags.h +++ b/ginac/flags.h @@ -193,7 +193,9 @@ public: evaluated = 0x0002, ///< .eval() has already done its job expanded = 0x0004, ///< .expand(0) has already done its job (other expand() options ignore this flag) hash_calculated = 0x0008, ///< .calchash() has already done its job - not_shareable = 0x0010 ///< don't share instances of this object between different expressions unless explicitly asked to (used by ex::compare()) + not_shareable = 0x0010, ///< don't share instances of this object between different expressions unless explicitly asked to (used by ex::compare()) + has_indices = 0x0020, + has_no_indices = 0x0040 // ! (has_indices || has_no_indices) means "don't know" }; }; diff --git a/ginac/idx.cpp b/ginac/idx.cpp index 3e17569..e966b14 100644 --- a/ginac/idx.cpp +++ b/ginac/idx.cpp @@ -234,8 +234,11 @@ void spinidx::do_print_tree(const print_tree & c, unsigned level) const bool idx::info(unsigned inf) const { - if (inf == info_flags::idx) - return true; + switch(inf) { + case info_flags::idx: + case info_flags::has_indices: + return true; + } return inherited::info(inf); } diff --git a/ginac/power.cpp b/ginac/power.cpp index b490b8c..fe7132a 100644 --- a/ginac/power.cpp +++ b/ginac/power.cpp @@ -240,6 +240,21 @@ bool power::info(unsigned inf) const basis.info(inf); case info_flags::expanded: return (flags & status_flags::expanded); + case info_flags::has_indices: { + if (flags & status_flags::has_indices) + return true; + else if (flags & status_flags::has_no_indices) + return false; + else if (basis.info(info_flags::has_indices)) { + setflag(status_flags::has_indices); + clearflag(status_flags::has_no_indices); + return true; + } else { + clearflag(status_flags::has_indices); + setflag(status_flags::has_no_indices); + return false; + } + } } return inherited::info(inf); } diff --git a/ginac/symbol.cpp b/ginac/symbol.cpp index 9f3b1c6..b68fed8 100644 --- a/ginac/symbol.cpp +++ b/ginac/symbol.cpp @@ -207,22 +207,25 @@ void symbol::do_print_python_repr(const print_python_repr & c, unsigned level) c bool symbol::info(unsigned inf) const { - if (inf == info_flags::symbol) - return true; - if (inf == info_flags::polynomial || - inf == info_flags::integer_polynomial || - inf == info_flags::cinteger_polynomial || - inf == info_flags::rational_polynomial || - inf == info_flags::crational_polynomial || - inf == info_flags::rational_function || - inf == info_flags::expanded) - return true; - if (inf == info_flags::real) - return domain==domain::real || domain==domain::positive; - if (inf == info_flags::positive || inf == info_flags::nonnegative) - return domain == domain::positive; - else - return inherited::info(inf); + switch (inf) { + case info_flags::symbol: + case info_flags::polynomial: + case info_flags::integer_polynomial: + case info_flags::cinteger_polynomial: + case info_flags::rational_polynomial: + case info_flags::crational_polynomial: + case info_flags::rational_function: + case info_flags::expanded: + return true; + case info_flags::real: + return domain == domain::real || domain == domain::positive; + case info_flags::positive: + case info_flags::nonnegative: + return domain == domain::positive; + case info_flags::has_indices: + return false; + } + return inherited::info(inf); } ex symbol::eval(int level) const -- 1.5.2.4 Best regards, Alexei -- All science is either physics or stamp collecting. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 827 bytes Desc: Digital signature URL: From varg at theor.jinr.ru Mon Sep 17 15:19:40 2007 From: varg at theor.jinr.ru (Alexei Sheplyakov) Date: Mon, 17 Sep 2007 17:19:40 +0400 Subject: [GiNaC-devel] [PATCH 2/4] Tell mul::expand() to not rename_indices_... if object has no indices at all. In-Reply-To: References: Message-ID: <6770460ca07bbe2af9d49d6d1c2f8a17237f791e.1190034683.git.varg@theor.jinr.ru> Patially solves performance regression in expand(), gcd(), etc. --- ginac/mul.cpp | 56 ++++++++++++++++++++++++++++++++++---------------------- 1 files changed, 34 insertions(+), 22 deletions(-) diff --git a/ginac/mul.cpp b/ginac/mul.cpp index 9ed27c6..db8b9f1 100644 --- a/ginac/mul.cpp +++ b/ginac/mul.cpp @@ -992,6 +992,7 @@ bool mul::can_be_further_expanded(const ex & e) ex mul::expand(unsigned options) const { + const bool skip_idx_rename = ! info(info_flags::has_indices); // First, expand the children std::auto_ptr expanded_seqp = expandchildren(options); const epvector & expanded_seq = (expanded_seqp.get() ? *expanded_seqp : seq); @@ -1047,28 +1048,34 @@ ex mul::expand(unsigned options) const ex tmp_accu = (new add(distrseq, add1.overall_coeff*add2.overall_coeff))->setflag(status_flags::dynallocated); exvector add1_dummy_indices, add2_dummy_indices, add_indices; + lst dummy_subs; - for (epvector::const_iterator i=add1begin; i!=add1end; ++i) { - add_indices = get_all_dummy_indices_safely(i->rest); - add1_dummy_indices.insert(add1_dummy_indices.end(), add_indices.begin(), add_indices.end()); - } - for (epvector::const_iterator i=add2begin; i!=add2end; ++i) { - add_indices = get_all_dummy_indices_safely(i->rest); - add2_dummy_indices.insert(add2_dummy_indices.end(), add_indices.begin(), add_indices.end()); - } + if (!skip_idx_rename) { + for (epvector::const_iterator i=add1begin; i!=add1end; ++i) { + add_indices = get_all_dummy_indices_safely(i->rest); + add1_dummy_indices.insert(add1_dummy_indices.end(), add_indices.begin(), add_indices.end()); + } + for (epvector::const_iterator i=add2begin; i!=add2end; ++i) { + add_indices = get_all_dummy_indices_safely(i->rest); + add2_dummy_indices.insert(add2_dummy_indices.end(), add_indices.begin(), add_indices.end()); + } - sort(add1_dummy_indices.begin(), add1_dummy_indices.end(), ex_is_less()); - sort(add2_dummy_indices.begin(), add2_dummy_indices.end(), ex_is_less()); - lst dummy_subs = rename_dummy_indices_uniquely(add1_dummy_indices, add2_dummy_indices); + sort(add1_dummy_indices.begin(), add1_dummy_indices.end(), ex_is_less()); + sort(add2_dummy_indices.begin(), add2_dummy_indices.end(), ex_is_less()); + dummy_subs = rename_dummy_indices_uniquely(add1_dummy_indices, add2_dummy_indices); + } // Multiply explicitly all non-numeric terms of add1 and add2: for (epvector::const_iterator i2=add2begin; i2!=add2end; ++i2) { // We really have to combine terms here in order to compactify // the result. Otherwise it would become waayy tooo bigg. - numeric oc; - distrseq.clear(); - ex i2_new = (dummy_subs.op(0).nops()>0? - i2->rest.subs((lst)dummy_subs.op(0), (lst)dummy_subs.op(1), subs_options::no_pattern) : i2->rest); + numeric oc(*_num0_p); + epvector distrseq2; + distrseq2.reserve(add1.seq.size()); + const ex i2_new = (skip_idx_rename || (dummy_subs.op(0).nops() == 0) ? + i2->rest : + i2->rest.subs(ex_to(dummy_subs.op(0)), + ex_to(dummy_subs.op(1)), subs_options::no_pattern)); for (epvector::const_iterator i1=add1begin; i1!=add1end; ++i1) { // Don't push_back expairs which might have a rest that evaluates to a numeric, // since that would violate an invariant of expairseq: @@ -1076,13 +1083,12 @@ ex mul::expand(unsigned options) const if (is_exactly_a(rest)) { oc += ex_to(rest).mul(ex_to(i1->coeff).mul(ex_to(i2->coeff))); } else { - distrseq.push_back(expair(rest, ex_to(i1->coeff).mul_dyn(ex_to(i2->coeff)))); + distrseq2.push_back(expair(rest, ex_to(i1->coeff).mul_dyn(ex_to(i2->coeff)))); } } - tmp_accu += (new add(distrseq, oc))->setflag(status_flags::dynallocated); - } + tmp_accu += (new add(distrseq2, oc))->setflag(status_flags::dynallocated); + } last_expanded = tmp_accu; - } else { if (!last_expanded.is_equal(_ex1)) non_adds.push_back(split_ex_to_pair(last_expanded)); @@ -1100,12 +1106,18 @@ ex mul::expand(unsigned options) const size_t n = last_expanded.nops(); exvector distrseq; distrseq.reserve(n); - exvector va = get_all_dummy_indices_safely(mul(non_adds)); - sort(va.begin(), va.end(), ex_is_less()); + exvector va; + if (! skip_idx_rename) { + va = get_all_dummy_indices_safely(mul(non_adds)); + sort(va.begin(), va.end(), ex_is_less()); + } for (size_t i=0; isetflag(status_flags::dynallocated); if (can_be_further_expanded(term)) { distrseq.push_back(term.expand()); -- 1.5.2.4 Best regards, Alexei -- All science is either physics or stamp collecting. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 827 bytes Desc: Digital signature URL: From varg at theor.jinr.ru Mon Sep 17 15:21:42 2007 From: varg at theor.jinr.ru (Alexei Sheplyakov) Date: Mon, 17 Sep 2007 17:21:42 +0400 Subject: [GiNaC-devel] [PATCH 3/4] {mul, power}::expand: expand monomials faster. In-Reply-To: References: Message-ID: <8678cf40b17a9fffcadeb20b7b60154461b78968.1190034683.git.varg@theor.jinr.ru> Apparently, in ~ 30% of calls to mul::expand the expression is monomial. Expanding monomials should be done as fast as possible. --- ginac/mul.cpp | 10 ++++++++++ ginac/power.cpp | 3 +++ 2 files changed, 13 insertions(+), 0 deletions(-) diff --git a/ginac/mul.cpp b/ginac/mul.cpp index db8b9f1..298715b 100644 --- a/ginac/mul.cpp +++ b/ginac/mul.cpp @@ -34,6 +34,7 @@ #include "lst.h" #include "archive.h" #include "utils.h" +#include "symbol.h" #include "compiler.h" namespace GiNaC { @@ -992,6 +993,15 @@ bool mul::can_be_further_expanded(const ex & e) ex mul::expand(unsigned options) const { + { + // trivial case: expanding the monomial (~ 30% of all calls) + epvector::const_iterator i = seq.begin(), seq_end = seq.end(); + while ((i != seq.end()) && is_a(i->rest) && i->coeff.info(info_flags::integer)) + ++i; + if (i == seq_end) + return (new mul(*this))->setflag(status_flags::dynallocated | status_flags::expanded); + } + const bool skip_idx_rename = ! info(info_flags::has_indices); // First, expand the children std::auto_ptr expanded_seqp = expandchildren(options); diff --git a/ginac/power.cpp b/ginac/power.cpp index fe7132a..cc003bc 100644 --- a/ginac/power.cpp +++ b/ginac/power.cpp @@ -771,6 +771,9 @@ tinfo_t power::return_type_tinfo() const ex power::expand(unsigned options) const { + if (is_a(basis) && exponent.info(info_flags::integer)) + return (new power(*this))->setflag(status_flags::dynallocated | status_flags::expanded); + if (options == 0 && (flags & status_flags::expanded)) return *this; -- 1.5.2.4 Best regards, Alexei -- All science is either physics or stamp collecting. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 827 bytes Desc: Digital signature URL: From varg at theor.jinr.ru Mon Sep 17 15:24:25 2007 From: varg at theor.jinr.ru (Alexei Sheplyakov) Date: Mon, 17 Sep 2007 17:24:25 +0400 Subject: [GiNaC-devel] [PATCH 4/4] introduce expand_options::expand_idx_rename and use it in mul::expand(). In-Reply-To: References: Message-ID: This helps mul::expand() and friends to recognize objects which have no indices at all. --- ginac/flags.h | 3 ++- ginac/mul.cpp | 8 +++++++- ginac/power.cpp | 7 ++++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/ginac/flags.h b/ginac/flags.h index 372b899..39a2113 100644 --- a/ginac/flags.h +++ b/ginac/flags.h @@ -30,7 +30,8 @@ class expand_options { public: enum { expand_indexed = 0x0001, ///< expands (a+b).i to a.i+b.i - expand_function_args = 0x0002 ///< expands the arguments of functions + expand_function_args = 0x0002, ///< expands the arguments of functions + expand_rename_idx = 0x0004 ///< used internally by mul::expand() }; }; diff --git a/ginac/mul.cpp b/ginac/mul.cpp index 298715b..4e95a63 100644 --- a/ginac/mul.cpp +++ b/ginac/mul.cpp @@ -1002,7 +1002,13 @@ ex mul::expand(unsigned options) const return (new mul(*this))->setflag(status_flags::dynallocated | status_flags::expanded); } - const bool skip_idx_rename = ! info(info_flags::has_indices); + // do not rename indices if the object has no indices at all + if ((!(options & expand_options::expand_rename_idx)) && + this->info(info_flags::has_indices)) + options |= expand_options::expand_rename_idx; + + const bool skip_idx_rename = !(options & expand_options::expand_rename_idx); + // First, expand the children std::auto_ptr expanded_seqp = expandchildren(options); const epvector & expanded_seq = (expanded_seqp.get() ? *expanded_seqp : seq); diff --git a/ginac/power.cpp b/ginac/power.cpp index cc003bc..7d909e8 100644 --- a/ginac/power.cpp +++ b/ginac/power.cpp @@ -1009,8 +1009,13 @@ ex power::expand_mul(const mul & m, const numeric & n, unsigned options, bool fr return _ex1; } + // do not bother to rename indices if there are no any. + if ((!(options & expand_options::expand_rename_idx)) + && m.info(info_flags::has_indices)) + options |= expand_options::expand_rename_idx; // Leave it to multiplication since dummy indices have to be renamed - if (get_all_dummy_indices(m).size() > 0 && n.is_positive()) { + if ((options & expand_options::expand_rename_idx) && + (get_all_dummy_indices(m).size() > 0) && n.is_positive()) { ex result = m; exvector va = get_all_dummy_indices(m); sort(va.begin(), va.end(), ex_is_less()); -- 1.5.2.4 Best regards, Alexei -- All science is either physics or stamp collecting. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 827 bytes Desc: Digital signature URL: From varg at theor.jinr.ru Mon Sep 17 15:50:22 2007 From: varg at theor.jinr.ru (Alexei Sheplyakov) Date: Mon, 17 Sep 2007 17:50:22 +0400 Subject: [GiNaC-devel] [PATCH] Apparently mul ctors do index renaming too. Fix them also. In-Reply-To: References: Message-ID: Do not bother to rename indices if object has no indices at all. --- ginac/expairseq.cpp | 15 ++++++++++++--- 1 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ginac/expairseq.cpp b/ginac/expairseq.cpp index 79c741a..788f783 100644 --- a/ginac/expairseq.cpp +++ b/ginac/expairseq.cpp @@ -812,8 +812,8 @@ void expairseq::construct_from_2_ex(const ex &lh, const ex &rh) construct_from_2_ex_via_exvector(lh,rh); } else { #endif // EXPAIRSEQ_USE_HASHTAB - if(is_a(lh)) - { + if (is_a(lh) && lh.info(info_flags::has_indices) && + rh.info(info_flags::has_indices)) { ex newrh=rename_dummy_indices_uniquely(lh, rh); construct_from_2_expairseq(ex_to(lh), ex_to(newrh)); @@ -1057,6 +1057,7 @@ void expairseq::make_flat(const exvector &v) // and their cumulative number of operands int nexpairseqs = 0; int noperands = 0; + bool do_idx_rename = false; cit = v.begin(); while (cit!=v.end()) { @@ -1064,6 +1065,9 @@ void expairseq::make_flat(const exvector &v) ++nexpairseqs; noperands += ex_to(*cit).seq.size(); } + if (is_a(*this) && (!do_idx_rename) && + cit->info(info_flags::has_indices)) + do_idx_rename = true; ++cit; } @@ -1071,7 +1075,7 @@ void expairseq::make_flat(const exvector &v) seq.reserve(v.size()+noperands-nexpairseqs); // copy elements and split off numerical part - make_flat_inserter mf(v, this->tinfo() == &mul::tinfo_static); + make_flat_inserter mf(v, do_idx_rename); cit = v.begin(); while (cit!=v.end()) { if (ex_to(*cit).tinfo()==this->tinfo()) { @@ -1105,6 +1109,7 @@ void expairseq::make_flat(const epvector &v, bool do_index_renaming) // and their cumulative number of operands int nexpairseqs = 0; int noperands = 0; + bool really_need_rename_inds = false; cit = v.begin(); while (cit!=v.end()) { @@ -1112,8 +1117,12 @@ void expairseq::make_flat(const epvector &v, bool do_index_renaming) ++nexpairseqs; noperands += ex_to(cit->rest).seq.size(); } + if ((!really_need_rename_inds) && is_a(*this) && + cit->rest.info(info_flags::has_indices)) + really_need_rename_inds = true; ++cit; } + do_index_renaming = do_index_renaming && really_need_rename_inds; // reserve seq and coeffseq which will hold all operands seq.reserve(v.size()+noperands-nexpairseqs); -- 1.5.2.4 Best regards, Alexei -- All science is either physics or stamp collecting. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 827 bytes Desc: Digital signature URL: From varg at theor.jinr.ru Mon Sep 17 17:02:29 2007 From: varg at theor.jinr.ru (Alexei Sheplyakov) Date: Mon, 17 Sep 2007 19:02:29 +0400 Subject: [GiNaC-devel] [PATCH 1/5, GiNaC 1.3] Improve info(info_flags::has_indices), introduce flags to cache the result. In-Reply-To: References: Message-ID: This is the similar set of patches for GiNaC 1.3 --- ginac/expairseq.cpp | 23 +++++++++++++++++++++-- ginac/flags.h | 4 +++- ginac/idx.cpp | 7 +++++-- ginac/power.cpp | 15 +++++++++++++++ ginac/symbol.cpp | 30 ++++++++++++++++-------------- 5 files changed, 60 insertions(+), 19 deletions(-) diff --git a/ginac/expairseq.cpp b/ginac/expairseq.cpp index be8790f..97cf961 100644 --- a/ginac/expairseq.cpp +++ b/ginac/expairseq.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "expairseq.h" #include "lst.h" @@ -261,8 +262,26 @@ void expairseq::do_print_tree(const print_tree & c, unsigned level) const bool expairseq::info(unsigned inf) const { - if (inf == info_flags::expanded) - return (flags & status_flags::expanded); + switch(inf) { + case info_flags::expanded: + return (flags & status_flags::expanded); + case info_flags::has_indices: { + if (flags & status_flags::has_indices) + return true; + else if (flags & status_flags::has_no_indices) + return false; + for (epvector::const_iterator i = seq.begin(); i != seq.end(); ++i) { + if (i->rest.info(info_flags::has_indices)) { + this->setflag(status_flags::has_indices); + this->clearflag(status_flags::has_no_indices); + return true; + } + } + this->clearflag(status_flags::has_indices); + this->setflag(status_flags::has_no_indices); + return false; + } + } return inherited::info(inf); } diff --git a/ginac/flags.h b/ginac/flags.h index a42f869..33622f9 100644 --- a/ginac/flags.h +++ b/ginac/flags.h @@ -179,7 +179,9 @@ public: evaluated = 0x0002, ///< .eval() has already done its job expanded = 0x0004, ///< .expand(0) has already done its job (other expand() options ignore this flag) hash_calculated = 0x0008, ///< .calchash() has already done its job - not_shareable = 0x0010 ///< don't share instances of this object between different expressions unless explicitly asked to (used by ex::compare()) + not_shareable = 0x0010, ///< don't share instances of this object between different expressions unless explicitly asked to (used by ex::compare()) + has_indices = 0x0020, + has_no_indices = 0x0040 // ! (has_indices || has_no_indices) means "don't know" }; }; diff --git a/ginac/idx.cpp b/ginac/idx.cpp index 3d363e0..601a77c 100644 --- a/ginac/idx.cpp +++ b/ginac/idx.cpp @@ -232,8 +232,11 @@ void spinidx::do_print_tree(const print_tree & c, unsigned level) const bool idx::info(unsigned inf) const { - if (inf == info_flags::idx) - return true; + switch(inf) { + case info_flags::idx: + case info_flags::has_indices: + return true; + } return inherited::info(inf); } diff --git a/ginac/power.cpp b/ginac/power.cpp index f243147..676b862 100644 --- a/ginac/power.cpp +++ b/ginac/power.cpp @@ -240,6 +240,21 @@ bool power::info(unsigned inf) const basis.info(inf); case info_flags::expanded: return (flags & status_flags::expanded); + case info_flags::has_indices: { + if (flags & status_flags::has_indices) + return true; + else if (flags & status_flags::has_no_indices) + return false; + else if (basis.info(info_flags::has_indices)) { + setflag(status_flags::has_indices); + clearflag(status_flags::has_no_indices); + return true; + } else { + clearflag(status_flags::has_indices); + setflag(status_flags::has_no_indices); + return false; + } + } } return inherited::info(inf); } diff --git a/ginac/symbol.cpp b/ginac/symbol.cpp index 2edd714..0e51f0e 100644 --- a/ginac/symbol.cpp +++ b/ginac/symbol.cpp @@ -190,20 +190,22 @@ void symbol::do_print_python_repr(const print_python_repr & c, unsigned level) c bool symbol::info(unsigned inf) const { - if (inf == info_flags::symbol) - return true; - if (inf == info_flags::polynomial || - inf == info_flags::integer_polynomial || - inf == info_flags::cinteger_polynomial || - inf == info_flags::rational_polynomial || - inf == info_flags::crational_polynomial || - inf == info_flags::rational_function || - inf == info_flags::expanded) - return true; - if (inf == info_flags::real) - return domain == domain::real; - else - return inherited::info(inf); + switch (inf) { + case info_flags::symbol: + case info_flags::polynomial: + case info_flags::integer_polynomial: + case info_flags::cinteger_polynomial: + case info_flags::rational_polynomial: + case info_flags::crational_polynomial: + case info_flags::rational_function: + case info_flags::expanded: + return true; + case info_flags::has_indices: + return false; + case info_flags::real: + return domain == domain::real; + } + return inherited::info(inf); } ex symbol::eval(int level) const -- 1.5.2.4 Best regards, Alexei -- All science is either physics or stamp collecting. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 827 bytes Desc: Digital signature URL: From varg at theor.jinr.ru Mon Sep 17 17:03:00 2007 From: varg at theor.jinr.ru (Alexei Sheplyakov) Date: Mon, 17 Sep 2007 19:03:00 +0400 Subject: [GiNaC-devel] [PATCH 2/5, GiNaC 1.3] Tell mul::expand() to not rename indices if the product has no indices at all. In-Reply-To: References: Message-ID: --- ginac/mul.cpp | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ginac/mul.cpp b/ginac/mul.cpp index 3c87d5a..5176218 100644 --- a/ginac/mul.cpp +++ b/ginac/mul.cpp @@ -940,6 +940,7 @@ bool mul::can_be_further_expanded(const ex & e) ex mul::expand(unsigned options) const { + const bool skip_idx_rename = ! info(info_flags::has_indices); // First, expand the children std::auto_ptr expanded_seqp = expandchildren(options); const epvector & expanded_seq = (expanded_seqp.get() ? *expanded_seqp : seq); @@ -1003,7 +1004,7 @@ ex mul::expand(unsigned options) const for (epvector::const_iterator i2=add2begin; i2!=add2end; ++i2) { // Don't push_back expairs which might have a rest that evaluates to a numeric, // since that would violate an invariant of expairseq: - const ex rest = (new mul(i1->rest, rename_dummy_indices_uniquely(i1->rest, i2->rest)))->setflag(status_flags::dynallocated); + const ex rest = (new mul(i1->rest, skip_idx_rename ? i2->rest : rename_dummy_indices_uniquely(i1->rest, i2->rest)))->setflag(status_flags::dynallocated); if (is_exactly_a(rest)) { oc += ex_to(rest).mul(ex_to(i1->coeff).mul(ex_to(i2->coeff))); } else { @@ -1034,7 +1035,10 @@ ex mul::expand(unsigned options) const for (size_t i=0; isetflag(status_flags::dynallocated); if (can_be_further_expanded(term)) { distrseq.push_back(term.expand()); -- 1.5.2.4 Best regards, Alexei -- All science is either physics or stamp collecting. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 827 bytes Desc: Digital signature URL: From varg at theor.jinr.ru Mon Sep 17 17:03:27 2007 From: varg at theor.jinr.ru (Alexei Sheplyakov) Date: Mon, 17 Sep 2007 19:03:27 +0400 Subject: [GiNaC-devel] [PATCH 3/5, GiNaC 1.3] power::expand_mul: do not try to rename indices if the object has no indices at all. In-Reply-To: References: Message-ID: --- ginac/power.cpp | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/ginac/power.cpp b/ginac/power.cpp index 676b862..bbcb453 100644 --- a/ginac/power.cpp +++ b/ginac/power.cpp @@ -916,7 +916,7 @@ ex power::expand_mul(const mul & m, const numeric & n, unsigned options, bool fr } // Leave it to multiplication since dummy indices have to be renamed - if (get_all_dummy_indices(m).size() > 0 && n.is_positive()) { + if (m.info(info_flags::has_indices) && (get_all_dummy_indices(m).size() > 0) && n.is_positive()) { ex result = m; for (int i=1; i < n.to_int(); i++) result *= rename_dummy_indices_uniquely(m,m); -- 1.5.2.4 Best regards, Alexei -- All science is either physics or stamp collecting. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 827 bytes Desc: Digital signature URL: From varg at theor.jinr.ru Mon Sep 17 17:04:01 2007 From: varg at theor.jinr.ru (Alexei Sheplyakov) Date: Mon, 17 Sep 2007 19:04:01 +0400 Subject: [GiNaC-devel] [PATCH 4/5, GiNaC 1.3] {mul, power}::expand: expand monomials faster. In-Reply-To: References: Message-ID: --- ginac/mul.cpp | 12 ++++++++++++ ginac/power.cpp | 3 +++ 2 files changed, 15 insertions(+), 0 deletions(-) diff --git a/ginac/mul.cpp b/ginac/mul.cpp index 5176218..d6ff7cb 100644 --- a/ginac/mul.cpp +++ b/ginac/mul.cpp @@ -34,6 +34,7 @@ #include "lst.h" #include "archive.h" #include "utils.h" +#include "symbol.h" #include "compiler.h" namespace GiNaC { @@ -940,7 +941,18 @@ bool mul::can_be_further_expanded(const ex & e) ex mul::expand(unsigned options) const { + { + // trivial case: expanding the monomial (~ 30% of all calls) + epvector::const_iterator i = seq.begin(), seq_end = seq.end(); + while ((i != seq.end()) && is_a(i->rest) && i->coeff.info(info_flags::integer)) + ++i; + if (i == seq_end) + return (new mul(*this))->setflag(status_flags::dynallocated | status_flags::expanded); + } + const bool skip_idx_rename = ! info(info_flags::has_indices); + if (skip_idx_rename) + ++(mul_expand_stats::n_indexless); // First, expand the children std::auto_ptr expanded_seqp = expandchildren(options); const epvector & expanded_seq = (expanded_seqp.get() ? *expanded_seqp : seq); diff --git a/ginac/power.cpp b/ginac/power.cpp index bbcb453..010af6c 100644 --- a/ginac/power.cpp +++ b/ginac/power.cpp @@ -680,6 +680,9 @@ unsigned power::return_type_tinfo() const ex power::expand(unsigned options) const { + if (is_a(basis) && exponent.info(info_flags::integer)) + return (new power(*this))->setflag(status_flags::dynallocated | status_flags::expanded); + if (options == 0 && (flags & status_flags::expanded)) return *this; -- 1.5.2.4 Best regards, Alexei -- All science is either physics or stamp collecting. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 827 bytes Desc: Digital signature URL: From varg at theor.jinr.ru Mon Sep 17 17:05:24 2007 From: varg at theor.jinr.ru (Alexei Sheplyakov) Date: Mon, 17 Sep 2007 19:05:24 +0400 Subject: [GiNaC-devel] [PATCH 5/5, GiNaC 1.3] introduce expand_options::expand_idx_rename and use it in mul::expand(). In-Reply-To: References: Message-ID: Helps to avoid useless (and expansive) rename_dummy_indices_uniquely(). --- ginac/flags.h | 3 ++- ginac/mul.cpp | 10 +++++++--- ginac/power.cpp | 7 ++++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/ginac/flags.h b/ginac/flags.h index 33622f9..478da32 100644 --- a/ginac/flags.h +++ b/ginac/flags.h @@ -30,7 +30,8 @@ class expand_options { public: enum { expand_indexed = 0x0001, ///< expands (a+b).i to a.i+b.i - expand_function_args = 0x0002 ///< expands the arguments of functions + expand_function_args = 0x0002, ///< expands the arguments of functions + expand_rename_idx = 0x0004 ///< used internally by mul::expand() }; }; diff --git a/ginac/mul.cpp b/ginac/mul.cpp index d6ff7cb..b7e0e82 100644 --- a/ginac/mul.cpp +++ b/ginac/mul.cpp @@ -950,9 +950,13 @@ ex mul::expand(unsigned options) const return (new mul(*this))->setflag(status_flags::dynallocated | status_flags::expanded); } - const bool skip_idx_rename = ! info(info_flags::has_indices); - if (skip_idx_rename) - ++(mul_expand_stats::n_indexless); + // do not rename indices if the object has no indices at all + if ((!(options & expand_options::expand_rename_idx)) && + this->info(info_flags::has_indices)) + options |= expand_options::expand_rename_idx; + + const bool skip_idx_rename = !(options & expand_options::expand_rename_idx); + // First, expand the children std::auto_ptr expanded_seqp = expandchildren(options); const epvector & expanded_seq = (expanded_seqp.get() ? *expanded_seqp : seq); diff --git a/ginac/power.cpp b/ginac/power.cpp index 010af6c..42e14c1 100644 --- a/ginac/power.cpp +++ b/ginac/power.cpp @@ -918,8 +918,13 @@ ex power::expand_mul(const mul & m, const numeric & n, unsigned options, bool fr return _ex1; } + // do not bother to rename indices if there are no any. + if ((!(options & expand_options::expand_rename_idx)) + && m.info(info_flags::has_indices)) + options |= expand_options::expand_rename_idx; // Leave it to multiplication since dummy indices have to be renamed - if (m.info(info_flags::has_indices) && (get_all_dummy_indices(m).size() > 0) && n.is_positive()) { + if ((!(options & expand_options::expand_rename_idx)) && + (get_all_dummy_indices(m).size() > 0) && n.is_positive()) { ex result = m; for (int i=1; i < n.to_int(); i++) result *= rename_dummy_indices_uniquely(m,m); -- 1.5.2.4 -- All science is either physics or stamp collecting. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 827 bytes Desc: Digital signature URL: From kreckel at ginac.de Mon Sep 17 21:30:04 2007 From: kreckel at ginac.de (Richard B. Kreckel) Date: Mon, 17 Sep 2007 21:30:04 +0200 Subject: [GiNaC-devel] [PATCH 1/5, GiNaC 1.3] Improve info(info_flags::has_indices), introduce flags to cache the result. In-Reply-To: References: Message-ID: <46EED5BC.5090404@ginac.de> Alexei Sheplyakov wrote: > This is the similar set of patches for GiNaC 1.3 A simple proposal: let's not care about release 1.3 so much. It is a waste of time now that 1.4 is out. If there's some really serious issue with 1.3 we can fix it for the 1.3 branch, but only as long as it is still in use by people out there. But making an effort to backport as much as possible appears pointless to me. And as soon as there are radical proposals that break the ABI it would make more sense to branch 1.4. Cheers -richy. -- Richard B. Kreckel From varg at theor.jinr.ru Tue Sep 18 09:18:40 2007 From: varg at theor.jinr.ru (Sheplyakov Alexei) Date: Tue, 18 Sep 2007 11:18:40 +0400 Subject: [GiNaC-devel] about "obsolete" versions In-Reply-To: <46EED5BC.5090404@ginac.de> References: <46EED5BC.5090404@ginac.de> Message-ID: <20070918071840.GB20384@theor.jinr.ru> Hello! On Mon, Sep 17, 2007 at 09:30:04PM +0200, Richard B. Kreckel wrote: > A simple proposal: let's not care about release 1.3 so much. It is a > waste of time now that 1.4 is out. Frankly, I'm not going to switch to 1.4 anytime soon, so I do care about 1.3. In general, I don't like to upgrade unless there is a compelling reason to do so (e.g. new version is 2x faster, or has some feature I need very much, etc). > If there's some really serious issue with 1.3 we can fix it for the 1.3 > branch, I think this particular regression is pretty serious. > but only as long as it is still in use by people out there. There is at least 1 user :) People don't like to upgrade (especially if their code breaks, gets substantially slower, etc), so I think there will be more. > But making an effort to backport as much as possible appears pointless > to me. Actually, [almost] all patches for 1.4 (and HEAD) I've submitted were forward ported (in most cases porting boils down to git-cherry-pick). Best regards, Alexei -- All science is either physics or stamp collecting. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 827 bytes Desc: Digital signature URL: