Dear all, I am about to release 1.3.6 this evening (or later ... ;-) ). Please have a look at the NEWS file and the last minute submissions I did and tell me if you find something missing or wrong. @Alexei: I had to apply two of your patches manually, because the format was somehow broken. I hope I did everything correctly. @Richy: I'd like to include Chris' numerical evaluation of tgamma and friends. It's just another class added, so I think it is okay to be included because the ABI doesn't change. But because of bad experience in the past I'd like to ask you again to be sure. Regards, Jens
On Tue, Dec 12, 2006 at 05:45:36PM +0100, Jens Vollinga wrote:
Dear all,
I am about to release 1.3.6 this evening (or later ... ;-) ). Please have a look at the NEWS file and the last minute submissions I did and tell me if you find something missing or wrong.
@Alexei: I had to apply two of your patches manually, because the format was somehow broken. I hope I did everything correctly.
There is no need for doing useless job. Feel free to ask me to re-send the patch[es] if you need.
@Richy: I'd like to include Chris' numerical evaluation of tgamma and friends. It's just another class added, so I think it is okay to be included because the ABI doesn't change. But because of bad experience in the past I'd like to ask you again to be sure.
+class lanczos_coeffs +{ + public: + lanczos_coeffs(); + bool sufficiently_accurate(int digits); + int get_order() const { return current_vector->size(); } + numeric calc_lanczos_A(const numeric &) const; + private: + static std::vector<numeric> coeffs_12; // Use in case Digits <= 20 + static std::vector<numeric> coeffs_30; // Use in case Digits <= 50 + static std::vector<numeric> coeffs_60; // Use in case Digits <= 100 + static std::vector<numeric> coeffs_120; // Use in case Digits <= 200 With such a code one need to break ABI (add extra class members) in order to increase the precision. May be replacing all these with static std::vector<std::vector<numeric> > would be better solution? +lanczos_coeffs::lanczos_coeffs() +{ if (coeffs_12[0] != 0) + return; I think coeffs_12[0] might be not initialized at this stage (and contain random garbage). const numeric lgamma(const numeric &x) { - throw dunno(); + lanczos_coeffs lc; + if (lc.sufficiently_accurate(Digits)) { + numeric pi_val(cln::pi(cln::default_float_format)); What happens here if Digits > default_float_format? + numeric result + = sqrt(numeric(2).mul(pi_val)) + .mul(temp.power(x.add(numeric(-1,2)))) + .mul(exp(temp.mul(-1))) + .mul(A); + All these foo.mul(bar).add(baz) are plain ugly. Any objections against s/numeric/cl_N/g (so it is possible to use natural syntax)? Best regards, Alexei -- All science is either physics or stamp collecting.
@Richy: I'd like to include Chris' numerical evaluation of tgamma and friends. It's just another class added, so I think it is okay to be included because the ABI doesn't change. But because of bad experience in the past I'd like to ask you again to be sure.
The patch addressing some of issues I've pointed out is available here: http://theor.jinr.ru/~varg/0001-lanczos_coeffs-fix-several-implementation-de... [Mailing list software rejects it due to the size] Best regards, Alexei -- All science is either physics or stamp collecting.
Sheplyakov Alexei wrote:
+class lanczos_coeffs +{ + public: + lanczos_coeffs(); + bool sufficiently_accurate(int digits); + int get_order() const { return current_vector->size(); } + numeric calc_lanczos_A(const numeric &) const; + private: + static std::vector<numeric> coeffs_12; // Use in case Digits <= 20 + static std::vector<numeric> coeffs_30; // Use in case Digits <= 50 + static std::vector<numeric> coeffs_60; // Use in case Digits <= 100 + static std::vector<numeric> coeffs_120; // Use in case Digits <= 200
With such a code one need to break ABI (add extra class members) in order to increase the precision. May be replacing all these with static std::vector<std::vector<numeric> > would be better solution?
But if the extra class members are of a class that is not intended to be used by any user of the library and cannot be used (at least without messing around), then it is okay. Chris was careful enough to add the class to file numeric.cpp, not to any of our header files. So it is not something anybody can use when linking his/her apps. Hence, there isn't anything that can break when the library is later upgraded underneath applications using it. Regards -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/>
On Tue, Dec 12, 2006 at 09:34:57PM +0100, Richard B. Kreckel wrote:
But if the extra class members are of a class that is not intended to be used by any user of the library and cannot be used (at least without messing around),
There is no need of "messing around". Corresponding symbols are readily available in the shared object (since they have ELF visibility `default' rather than `hidden' or `private'), so: // bugme.cpp #include <ginac/ginac.h> namespace GiNaC { class lanczos_coeffs; } void foo() { using namespace GiNaC; lanczos_coeffs bugme; // do something here } BTW, people *do use* _exN stuff in their code.
Hence, there isn't anything that can break when the library is later upgraded underneath applications using it.
I don't think that changing class layout for increasing precision is a good idea anyway. Best regards, Alexei -- All science is either physics or stamp collecting.
Dear Alexei, On Wed, 13 Dec 2006, Sheplyakov Alexei wrote:
// bugme.cpp #include <ginac/ginac.h> namespace GiNaC { class lanczos_coeffs; }
void foo() { using namespace GiNaC; lanczos_coeffs bugme; // do something here }
The compiler says: "error: aggregate GiNaC::lanczos_coeffs bugme has incomplete type and cannot be defined". Hence, users would have to import the entire definition of this class from the file numeric.cpp. I think in that case they should know that they are doing something non-standard that can break at any time. If this is the only problem with it, I would not worry too much. Best wishes, Chris
Dear Alexei, On Tue, 12 Dec 2006, Sheplyakov Alexei wrote:
+ static std::vector<numeric> coeffs_12; // Use in case Digits <= 20 + static std::vector<numeric> coeffs_30; // Use in case Digits <= 50 + static std::vector<numeric> coeffs_60; // Use in case Digits <= 100 + static std::vector<numeric> coeffs_120; // Use in case Digits <= 200
With such a code one need to break ABI (add extra class members) in order to increase the precision. May be replacing all these with static std::vector<std::vector<numeric> > would be better solution?
Richy has already answered this.
+lanczos_coeffs::lanczos_coeffs() +{ if (coeffs_12[0] != 0) + return;
I think coeffs_12[0] might be not initialized at this stage (and contain random garbage).
No, that is not true. The elements of the vector have been constructed using the default constructor of numeric. Therfore they are zero if this constructor is called for the first time.
const numeric lgamma(const numeric &x) { - throw dunno(); + lanczos_coeffs lc; + if (lc.sufficiently_accurate(Digits)) { + numeric pi_val(cln::pi(cln::default_float_format));
What happens here if Digits > default_float_format?
I sincerely hope that it won't cause problems, because otherwise I'm afraid that also the function PiEvalf will do the wrong thing.
+ numeric result + = sqrt(numeric(2).mul(pi_val)) + .mul(temp.power(x.add(numeric(-1,2)))) + .mul(exp(temp.mul(-1))) + .mul(A); +
All these foo.mul(bar).add(baz) are plain ugly. Any objections against s/numeric/cl_N/g (so it is possible to use natural syntax)?
If that has infix operators, I would say it would be much nicer. Best wishes, Chris
Hi, Chris!
const numeric lgamma(const numeric &x) { - throw dunno(); + lanczos_coeffs lc; + if (lc.sufficiently_accurate(Digits)) { + numeric pi_val(cln::pi(cln::default_float_format));
What happens here if Digits > default_float_format?
I sincerely hope that it won't cause problems
... because it is impossible: /** Assign a native long to global Digits object. */ _numeric_digits& _numeric_digits::operator=(long prec) { digits = prec; cln::default_float_format = cln::float_format(prec); return *this; } Sorry for the noise.
All these foo.mul(bar).add(baz) are plain ugly. Any objections against s/numeric/cl_N/g (so it is possible to use natural syntax)?
If that has infix operators, I would say it would be much nicer.
Sure, it has (like [almost] all CLN types).
With such a code one need to break ABI (add extra class members) in order to increase the precision. May be replacing all these with static std::vector<std::vector<numeric> > would be better solution?
Richy has already answered this.
I think his answer is wrong. Leaving aside the ABI, I don't think adding more members to a class to achive better precision is a good idea anyway. Secondly, it would be nice to remove artificial limit (Digits <= 200) and make the evaluation really arbitrary-precision. To do this one need to calculate missing coefficients at run-time and store them in vector<vector <numeric> > (or vector<vector <cl_R> >).
+lanczos_coeffs::lanczos_coeffs() +{ if (coeffs_12[0] != 0) + return;
I think coeffs_12[0] might be not initialized at this stage (and contain random garbage).
No, that is not true. The elements of the vector have been constructed using the default constructor of numeric.
I think it is safer and simpler to add `static int count' so we don't ever run into yet another static order initailization problem. Best regards, Alexei -- All science is either physics or stamp collecting.
Dear Alexei, On Wed, 13 Dec 2006, Sheplyakov Alexei wrote:
All these foo.mul(bar).add(baz) are plain ugly. Any objections against s/numeric/cl_N/g (so it is possible to use natural syntax)?
If that has infix operators, I would say it would be much nicer.
Sure, it has (like [almost] all CLN types).
Okay, then I will do this as soon as I have some time.
Secondly, it would be nice to remove artificial limit (Digits <= 200) and make the evaluation really arbitrary-precision. To do this one need to calculate missing coefficients at run-time and store them in vector<vector <numeric> > (or vector<vector <cl_R> >).
Yes, but calculating these coefficients is rather demanding. I don't think users will like it very much if evalfing their expressions, suddenly makes their pogram allocate a few hundreds of MBs. Fortunately, these hundreds of MBs are deallocated after that, but it still needs to fit next to the memory of the application that the user is trying to run. Actually, I do not understand very well why it is so computationally intense. Maybe I could try to make the intermediate integer coefficients floats, so that they can be smaller? Not sure, maybe I will have a look at this.
+lanczos_coeffs::lanczos_coeffs() +{ if (coeffs_12[0] != 0) + return;
I think coeffs_12[0] might be not initialized at this stage (and contain random garbage).
No, that is not true. The elements of the vector have been constructed using the default constructor of numeric.
I think it is safer and simpler to add `static int count' so we don't ever run into yet another static order initailization problem.
Yes, there will be probs if someone starts doing evalfs of gamma functions at static initialization time. Okay, I think I will do as you suggest. Best wishes, Chris
On Tue, Dec 12, 2006 at 05:45:36PM +0100, Jens Vollinga wrote:
Please have a look at the NEWS file and the last minute submissions I did and tell me if you find something missing or wrong.
diff --git a/NEWS b/NEWS index af36279..c8154e2 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ This file records noteworthy changes. * Fixed bug in numerical evaluation of multiple polylogs. * Fixed numerical integration of complex functions. * Fixed bug in tensor::replace_contr_index(). +* Fixed bug in reposition_dummy_indices(). 1.3.5 (17 August 2006) * Re-built bison related files that caused bugs with gcc 4.
@Alexei: I had to apply two of your patches manually, because the format was somehow broken. I hope I did everything correctly.
I'm little bit busy now, could you please wait till tomorrow? Best regards, Alexei -- All science is either physics or stamp collecting.
Hello, Jens!
@Alexei: I had to apply two of your patches manually, because the format was somehow broken. I hope I did everything correctly.
Yes, modulo minor whitespace damage :)
I'm little bit busy now, could you please wait till tomorrow?
okay. I will wait (as long as it takes).
I've found yet another bug (seems to be fixed in HEAD): #include <iostream> #include <stdexcept> #include <ginac/ginac.h> using namespace std; using namespace GiNaC; int main(int argc, char** argv) { idx a(symbol("a"), 8), b(symbol("b"), 8), c(symbol("c"), 8), d(symbol("d"), 8), e(symbol("e"), 8), f(symbol("f"), 8); ex H1 = color_f(a, c, e)*color_f(b, d, e) + color_f(a, d, e)*color_f(b, c, e); ex test = (H1*H1).expand(expand_options::expand_indexed); cout << test << endl; // 2*f.e.b.d*f.e.b.c*f.e.a.c*f.e.a.d+f.symbol8.b.c*f.symbol8.a.d*f.e.b.c*f.e.a.d+f.symbol7.b.d*f.symbol7.a.c*f.e.b.d*f.e.a.c // inconsistent indices! cout << test.simplify_indexed() << endl; // prints 288, should be 216 return 0; } I wonder if it is possible to backport the fix... Best regards, Alexei -- All science is either physics or stamp collecting.
Hi, Sheplyakov Alexei schrieb:
I've found yet another bug (seems to be fixed in HEAD):
I wonder if it is possible to backport the fix...
that is fixed by the Oct 20th patch in HEAD, isn't it? That is hard to backport ... Does the inclusion of a friend class declaration in a class change its ABI? Regards, Jens
Dear Alexei, On Wed, 13 Dec 2006, Sheplyakov Alexei wrote:
ex H1 = color_f(a, c, e)*color_f(b, d, e) + color_f(a, d, e)*color_f(b, c, e);
ex test = (H1*H1).expand(expand_options::expand_indexed); cout << test << endl; // 2*f.e.b.d*f.e.b.c*f.e.a.c*f.e.a.d+f.symbol8.b.c*f.symbol8.a.d*f.e.b.c*f.e.a.d+f.symbol7.b.d*f.symbol7.a.c*f.e.b.d*f.e.a.c // inconsistent indices!
cout << test.simplify_indexed() << endl; // prints 288, should be 216
At my place this prints 144-2*f.c.a.symbol8*f.a.d.e*f.d.symbol8.b*f.c.e.b. Strange??? @dummy index renaming: yes, this has been much improved in HEAD. In principle I think it would be possible to move the class make_flat_inserter into the *.cpp files. But that would be code duplication. Not so nice. Besides that, new functions were added to indexed.cpp and these need to be called from indexed.h. Fixing all this in a binary compatible way would get way too messy IMO. Maybe we should release 1.4 and claim proudly that we now can rename dummy indices. Good thing that we don't keep an accurate NEWS file. That way we can can announce it like it is new. :-o ;-) Best wishes, Chris
Dear all, I plan to do the following now (unless counseled otherwise ...): - leave the numerical evaluation of tgamma and friends out of 1.3.6. (sorry for edgy Etch). - don't do anything about the dummy index bug and start a discussion about the next major release 1.4. Regards, Jens
Jens Vollinga wrote:
@Richy: I'd like to include Chris' numerical evaluation of tgamma and friends. It's just another class added, so I think it is okay to be included because the ABI doesn't change. But because of bad experience in the past I'd like to ask you again to be sure.
The goal with the branch releases has always been to be strictly binary compatible. Updating the library underneath a program linked against it should not render the program unusable. Linux distributors rely on this when building library packages. The patch by Chris does clearly not change any public interface that might be used by an application. Regards -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/>
participants (4)
-
Chris Dams
-
Jens Vollinga
-
Richard B. Kreckel
-
varg@theor.jinr.ru