wrong result in complex pow
Hello, the pow-function pow(scalar, complex) in boost/math/cstdfloat/cstdfloat_complex_std.hpp get wrong result. Current implementation: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { return std::exp(a * std::log(x)); } I think that's correct: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { return std::exp(a * std::log(complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(x))); } regards Gero
the pow-function pow(scalar, complex) in> boost/math/cstdfloat/cstdfloat_complex_std.hpp> get wrong result. Thanks Gero, Good catch. This does seem like a bug.I am on the go, but later today, I'll add thisas an issue in Git and kick off the discussionfor the fix with the colleagues. Kind regards, Chris
On Thursday, January 28, 2021, 12:55:59 PM GMT+1, Gero Peterhoff via Boost <boost@lists.boost.org> wrote: Hello, the pow-function pow(scalar, complex) in boost/math/cstdfloat/cstdfloat_complex_std.hpp get wrong result. Current implementation: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { return std::exp(a * std::log(x)); } I think that's correct: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { return std::exp(a * std::log(complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(x))); } regards Gero _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
the pow-function pow(scalar, complex) in>> boost/math/cstdfloat/cstdfloat_complex_std.hpp>> get wrong result. Thanks Gero,> I am on the go, but later today, I'll add this> as an issue in Git and kick off the discussion> for the fix with the colleagues. A new issue can be found here, but itis not clear which code example elicitsthe unexpected behavior.
https://github.com/boostorg/math/issues/506 On Thursday, January 28, 2021, 12:55:59 PM GMT+1, Gero Peterhoff via Boost <boost@lists.boost.org> wrote: Hello, the pow-function pow(scalar, complex) in boost/math/cstdfloat/cstdfloat_complex_std.hpp get wrong result. Current implementation: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { return std::exp(a * std::log(x)); } I think that's correct: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { return std::exp(a * std::log(complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(x))); } regards Gero _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Hello Christopher, I just noticed that my simple patch with base=0 doesn't work. It is probably not that simple. https://godbolt.org/z/8Me15Y regards Gero Am 30.01.21 um 16:22 schrieb Christopher Kormanyos:
the pow-function pow(scalar, complex) in boost/math/cstdfloat/cstdfloat_complex_std.hpp get wrong result.
Thanks Gero, I am on the go, but later today, I'll add this as an issue in Git and kick off the discussion for the fix with the colleagues.
A new issue can be found here, but it is not clear which code example elicits the unexpected behavior.
https://github.com/boostorg/math/issues/506 <https://github.com/boostorg/math/issues/506>
On Thursday, January 28, 2021, 12:55:59 PM GMT+1, Gero Peterhoff via Boost <boost@lists.boost.org> wrote:
Hello, the pow-function pow(scalar, complex) in boost/math/cstdfloat/cstdfloat_complex_std.hpp get wrong result.
Current implementation: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { return std::exp(a * std::log(x)); }
I think that's correct: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { return std::exp(a * std::log(complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(x))); }
regards Gero
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost <http://lists.boost.org/mailman/listinfo.cgi/boost>
noticed that my simple patch with base=0> doesn't work. Thanks Gero.
Yes. I am trying a patch that handles zero explicitly.I'm not quite sure if all zeros, NaNs and Infinitiesare correct yet,... But the patch is generallymoving toward the fix shown in the link below... If you get a chance, could you try that patchfrom the branch linked below? https://github.com/boostorg/math/blob/2eac693e12547c1ca26800c2403e4e50f62d29... Kind regards, Chris On Sunday, January 31, 2021, 2:17:32 PM GMT+1, Gero Peterhoff <g.peterhoff@t-online.de> wrote: Hello Christopher, I just noticed that my simple patch with base=0 doesn't work. It is probably not that simple. https://godbolt.org/z/8Me15Y regards Gero Am 30.01.21 um 16:22 schrieb Christopher Kormanyos:
the pow-function pow(scalar, complex) in boost/math/cstdfloat/cstdfloat_complex_std.hpp get wrong result.
Thanks Gero, I am on the go, but later today, I'll add this as an issue in Git and kick off the discussion for the fix with the colleagues.
A new issue can be found here, but it is not clear which code example elicits the unexpected behavior.
https://github.com/boostorg/math/issues/506 <https://github.com/boostorg/math/issues/506>
On Thursday, January 28, 2021, 12:55:59 PM GMT+1, Gero Peterhoff via Boost <boost@lists.boost.org> wrote:
Hello, the pow-function pow(scalar, complex) in boost/math/cstdfloat/cstdfloat_complex_std.hpp get wrong result.
Current implementation: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { return std::exp(a * std::log(x)); }
I think that's correct: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { return std::exp(a * std::log(complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(x))); }
regards Gero
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost <http://lists.boost.org/mailman/listinfo.cgi/boost>
noticed that my simple patch with base=0>> doesn't work. Thanks Gero. Yes. I am trying a patch that handles zero explicitly.> I'm not quite sure if all zeros, NaNs and Infinities> are correct yet, Gero, I patched this about as far as I'd like to go for this particular issue, added relevanttests. Underway, I did find that morepossible work with zero, inf, NaN parametersthat *could* be done in that particular header,but I will not modify these at the moment.This is because there are not a lot of requestsfor changes. I'd probably end up breakingexisting code if I tried to clean up allkinds of edge cases that my eyes happenedacross. That being said, the exact issue that youhave pointed out and addressed in thisthread on the board is being handledin the PR here: https://github.com/boostorg/math/pull/507 ... with fixed code here:https://github.com/boostorg/math/blob/e3cc94a580f3d1282578b0c31f985a392c866f... Gero, if you get a chance, could yougive the patch a try? It will expectedly bemerged in and available in the next release. Kind regards, Chris On Sunday, January 31, 2021, 3:22:53 PM GMT+1, Christopher Kormanyos <e_float@yahoo.com> wrote:
noticed that my simple patch with base=0> doesn't work. Thanks Gero.
Yes. I am trying a patch that handles zero explicitly.I'm not quite sure if all zeros, NaNs and Infinitiesare correct yet,... But the patch is generallymoving toward the fix shown in the link below... If you get a chance, could you try that patchfrom the branch linked below? https://github.com/boostorg/math/blob/2eac693e12547c1ca26800c2403e4e50f62d29... Kind regards, Chris On Sunday, January 31, 2021, 2:17:32 PM GMT+1, Gero Peterhoff <g.peterhoff@t-online.de> wrote: Hello Christopher, I just noticed that my simple patch with base=0 doesn't work. It is probably not that simple. https://godbolt.org/z/8Me15Y regards Gero Am 30.01.21 um 16:22 schrieb Christopher Kormanyos:
the pow-function pow(scalar, complex) in boost/math/cstdfloat/cstdfloat_complex_std.hpp get wrong result.
Thanks Gero, I am on the go, but later today, I'll add this as an issue in Git and kick off the discussion for the fix with the colleagues.
A new issue can be found here, but it is not clear which code example elicits the unexpected behavior.
https://github.com/boostorg/math/issues/506 <https://github.com/boostorg/math/issues/506>
On Thursday, January 28, 2021, 12:55:59 PM GMT+1, Gero Peterhoff via Boost <boost@lists.boost.org> wrote:
Hello, the pow-function pow(scalar, complex) in boost/math/cstdfloat/cstdfloat_complex_std.hpp get wrong result.
Current implementation: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { return std::exp(a * std::log(x)); }
I think that's correct: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { return std::exp(a * std::log(complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(x))); }
regards Gero
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost <http://lists.boost.org/mailman/listinfo.cgi/boost>
Hello Chris, your patch doesn't seem to be working properly yet. I also noticed that there is the same problem with NaN and inf (and zeros?) for pow(complex, complex). I'm currently working on tests for all pow functions and patches. Hope I'll get this ready soon and send it to you. thx Gero Am 01.02.21 um 14:41 schrieb Christopher Kormanyos:
noticed that my simple patch with base=0 doesn't work.
Thanks Gero. Yes. I am trying a patch that handles zero explicitly. I'm not quite sure if all zeros, NaNs and Infinities are correct yet,
Gero, I patched this about as far as I'd like to go for this particular issue, added relevant tests. Underway, I did find that more possible work with zero, inf, NaN parameters that *could* be done in that particular header, but I will not modify these at the moment. This is because there are not a lot of requests for changes. I'd probably end up breaking existing code if I tried to clean up all kinds of edge cases that my eyes happened across.
That being said, the exact issue that you have pointed out and addressed in this thread on the board is being handled in the PR here: https://github.com/boostorg/math/pull/507 <https://github.com/boostorg/math/pull/507>
... with fixed code here: https://github.com/boostorg/math/blob/e3cc94a580f3d1282578b0c31f985a392c866f... <https://github.com/boostorg/math/blob/e3cc94a580f3d1282578b0c31f985a392c866f19/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp#L509>
Gero, if you get a chance, could you give the patch a try? It will expectedly be merged in and available in the next release.
Kind regards, Chris
On Sunday, January 31, 2021, 3:22:53 PM GMT+1, Christopher Kormanyos <e_float@yahoo.com> wrote:
noticed that my simple patch with base=0 doesn't work.
Thanks Gero.
Yes. I am trying a patch that handles zero explicitly. I'm not quite sure if all zeros, NaNs and Infinities are correct yet,... But the patch is generally moving toward the fix shown in the link below...
If you get a chance, could you try that patch from the branch linked below?
https://github.com/boostorg/math/blob/2eac693e12547c1ca26800c2403e4e50f62d29... <https://github.com/boostorg/math/blob/2eac693e12547c1ca26800c2403e4e50f62d29bd/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp#L512>
Kind regards, Chris
On Sunday, January 31, 2021, 2:17:32 PM GMT+1, Gero Peterhoff <g.peterhoff@t-online.de> wrote:
Hello Christopher, I just noticed that my simple patch with base=0 doesn't work. It is probably not that simple. https://godbolt.org/z/8Me15Y <https://godbolt.org/z/8Me15Y>
regards Gero
Am 30.01.21 um 16:22 schrieb Christopher Kormanyos:
the pow-function pow(scalar, complex) in boost/math/cstdfloat/cstdfloat_complex_std.hpp get wrong result.
Thanks Gero, I am on the go, but later today, I'll add this as an issue in Git and kick off the discussion for the fix with the colleagues.
A new issue can be found here, but it is not clear which code example elicits the unexpected behavior.
https://github.com/boostorg/math/issues/506 <https://github.com/boostorg/math/issues/506 ><https://github.com/boostorg/math/issues/506 <https://github.com/boostorg/math/issues/506>>
On Thursday, January 28, 2021, 12:55:59 PM GMT+1, Gero Peterhoff via Boost <boost@lists.boost.org <mailto:boost@lists.boost.org>> wrote:
Hello, the pow-function pow(scalar, complex) in boost/math/cstdfloat/cstdfloat_complex_std.hpp get wrong result.
Current implementation: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { return std::exp(a * std::log(x)); }
I think that's correct: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { return std::exp(a * std::log(complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(x))); }
regards Gero
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost <http://lists.boost.org/mailman/listinfo.cgi/boost ><http://lists.boost.org/mailman/listinfo.cgi/boost <http://lists.boost.org/mailman/listinfo.cgi/boost>>
I patched this about as far as I'd like to go Hello Chris,> your patch doesn't seem to be working properly> yet. I also noticed that there is the same problem> with NaN and inf (and zeros?) for> pow(complex, complex). I'm currently working> on tests for all pow functions and patches.> Hope I'll get this ready soon and send it to you. > thx Gero You are right. Thanks for any help you cancontribute. If I look more critically at the file, I think theremight be other functions that could benefit fromsome increased handling of special argumentsNan, inf, zero real/imag. These include sqrt,log, log10, atan, and maybe a few others. I might have underestimated the potentialfor improvement of this file and would nowwonder if a more in-depth refactoringis a wise idea? Compromise on improvementsof risk of breaking existing use in community?
Thoughts? Kind regards, Chris On Wednesday, February 3, 2021, 1:31:48 AM GMT+1, Gero Peterhoff <g.peterhoff@t-online.de> wrote: Hello Chris, your patch doesn't seem to be working properly yet. I also noticed that there is the same problem with NaN and inf (and zeros?) for pow(complex, complex). I'm currently working on tests for all pow functions and patches. Hope I'll get this ready soon and send it to you. thx Gero Am 01.02.21 um 14:41 schrieb Christopher Kormanyos:
noticed that my simple patch with base=0 doesn't work.
Thanks Gero. Yes. I am trying a patch that handles zero explicitly. I'm not quite sure if all zeros, NaNs and Infinities are correct yet,
Gero, I patched this about as far as I'd like to go for this particular issue, added relevant tests. Underway, I did find that more possible work with zero, inf, NaN parameters that *could* be done in that particular header, but I will not modify these at the moment. This is because there are not a lot of requests for changes. I'd probably end up breaking existing code if I tried to clean up all kinds of edge cases that my eyes happened across.
That being said, the exact issue that you have pointed out and addressed in this thread on the board is being handled in the PR here: https://github.com/boostorg/math/pull/507 <https://github.com/boostorg/math/pull/507>
... with fixed code here: https://github.com/boostorg/math/blob/e3cc94a580f3d1282578b0c31f985a392c866f... <https://github.com/boostorg/math/blob/e3cc94a580f3d1282578b0c31f985a392c866f19/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp#L509>
Gero, if you get a chance, could you give the patch a try? It will expectedly be merged in and available in the next release.
Kind regards, Chris
On Sunday, January 31, 2021, 3:22:53 PM GMT+1, Christopher Kormanyos <e_float@yahoo.com> wrote:
noticed that my simple patch with base=0 doesn't work.
Thanks Gero.
Yes. I am trying a patch that handles zero explicitly. I'm not quite sure if all zeros, NaNs and Infinities are correct yet,... But the patch is generally moving toward the fix shown in the link below...
If you get a chance, could you try that patch from the branch linked below?
https://github.com/boostorg/math/blob/2eac693e12547c1ca26800c2403e4e50f62d29... <https://github.com/boostorg/math/blob/2eac693e12547c1ca26800c2403e4e50f62d29bd/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp#L512>
Kind regards, Chris
On Sunday, January 31, 2021, 2:17:32 PM GMT+1, Gero Peterhoff <g.peterhoff@t-online.de> wrote:
Hello Christopher, I just noticed that my simple patch with base=0 doesn't work. It is probably not that simple. https://godbolt.org/z/8Me15Y <https://godbolt.org/z/8Me15Y>
regards Gero
Am 30.01.21 um 16:22 schrieb Christopher Kormanyos:
the pow-function pow(scalar, complex) in boost/math/cstdfloat/cstdfloat_complex_std.hpp get wrong result.
Thanks Gero, I am on the go, but later today, I'll add this as an issue in Git and kick off the discussion for the fix with the colleagues.
A new issue can be found here, but it is not clear which code example elicits the unexpected behavior.
https://github.com/boostorg/math/issues/506 <https://github.com/boostorg/math/issues/506 ><https://github.com/boostorg/math/issues/506 <https://github.com/boostorg/math/issues/506>>
On Thursday, January 28, 2021, 12:55:59 PM GMT+1, Gero Peterhoff via Boost <boost@lists.boost.org <mailto:boost@lists.boost.org>> wrote:
Hello, the pow-function pow(scalar, complex) in boost/math/cstdfloat/cstdfloat_complex_std.hpp get wrong result.
Current implementation: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { return std::exp(a * std::log(x)); }
I think that's correct: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { return std::exp(a * std::log(complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(x))); }
regards Gero
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost <http://lists.boost.org/mailman/listinfo.cgi/boost ><http://lists.boost.org/mailman/listinfo.cgi/boost <http://lists.boost.org/mailman/listinfo.cgi/boost>>
Christopher Kormanyos via Boost said: (by the date of Wed, 3 Feb 2021 19:21:55 +0000 (UTC))
If I look more critically at the file, I think theremight be other functions that could benefit fromsome increased handling of special arguments Nan, inf, zero real/imag. These include sqrt,log, log10, atan, and maybe a few others. I might have underestimated the potentialfor improvement of this file and would now wonder if a more in-depth refactoringis a wise idea? Compromise on improvementsof risk of breaking existing use in community?
How about adding a trait to the floating point type, whether you want exceptions, or any kind of error control. Default value of the trait is the backward compatibility. New and old users are both happy. best regards -- # Janek Kozicki http://janek.kozicki.pl/
Hello Chris, Unfortunately, a few things have come up with me so that I (probably) won't be able to really help in the near future. Some other functions (e.g. log, exp) also give incorrect results for some combinations of nan, inf and 0. But I saw that gcc libquadmath (https://gcc.gnu.org/onlinedocs/libquadmath/Math-Library-Routines.html#Math-L...) offers some complex functions that work correctly. These could be used. But I don't know if clang, intel and/or other compilers can do that too. example inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { __complex128 res = __complex128{x.real(), x.imag()}; res = clogq(res); return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>{crealq(res), cimagq(res)}; } I also noticed a few basic things, maybe you can say why that is: - Why are there explicit complex classes for FP types, why is this not implemented completely via template? The advantage is that built-ins can be used, on the other hand, a separate class must be written for each FP type - with the problems we are currently having. - Why are there missing template conversion ctors for the complex<FP-Type>? That will not do: std::complex<int> ci{4711, 23}; std::complex<double> cd=ci; or std::complex<double> cd = std::complex<double>{ci}; but a ctor must be called explicitly std::complex<double> cd=std::complex<double>{double(ci.real()), double(ci.imag())}; // prevent warnings It's really annoying. - Why are many std-math functions missing for complex; special-functions complete (also applies to std::valarray)? I want to add such things in my math-lib, as far as possible everything constexpr. I also want to provide additional classes for dual and splitcomplex numbers (i²=0, i²=1, but it is far from complete - because it is quite extensive). Maybe these could also be included in boost. To do this, however, it would be necessary to convert the boost-math-lib to C++20, since some functions (or the distinction between dual, complex and splitcomplex - classes/functions) is only possible with concepts (otherwise unreasonable effort). I also need some additional typetraits. thx Gero Am 03.02.21 um 20:21 schrieb Christopher Kormanyos:
I patched this about as far as I'd like to go
Hello Chris, your patch doesn't seem to be working properly yet. I also noticed that there is the same problem with NaN and inf (and zeros?) for pow(complex, complex). I'm currently working on tests for all pow functions and patches. Hope I'll get this ready soon and send it to you. thx Gero
You are right. Thanks for any help you can contribute.
If I look more critically at the file, I think there might be other functions that could benefit from some increased handling of special arguments Nan, inf, zero real/imag. These include sqrt, log, log10, atan, and maybe a few others.
I might have underestimated the potential for improvement of this file and would now wonder if a more in-depth refactoring is a wise idea? Compromise on improvements of risk of breaking existing use in community?
Thoughts?
Kind regards, Chris
On Wednesday, February 3, 2021, 1:31:48 AM GMT+1, Gero Peterhoff <g.peterhoff@t-online.de> wrote:
Hello Chris, your patch doesn't seem to be working properly yet. I also noticed that there is the same problem with NaN and inf (and zeros?) for pow(complex, complex). I'm currently working on tests for all pow functions and patches. Hope I'll get this ready soon and send it to you.
thx Gero
Am 01.02.21 um 14:41 schrieb Christopher Kormanyos:
noticed that my simple patch with base=0 doesn't work.
Thanks Gero. Yes. I am trying a patch that handles zero explicitly. I'm not quite sure if all zeros, NaNs and Infinities are correct yet,
Gero, I patched this about as far as I'd like to go for this particular issue, added relevant tests. Underway, I did find that more possible work with zero, inf, NaN parameters that *could* be done in that particular header, but I will not modify these at the moment. This is because there are not a lot of requests for changes. I'd probably end up breaking existing code if I tried to clean up all kinds of edge cases that my eyes happened across.
That being said, the exact issue that you have pointed out and addressed in this thread on the board is being handled in the PR here: https://github.com/boostorg/math/pull/507 <https://github.com/boostorg/math/pull/507 ><https://github.com/boostorg/math/pull/507 <https://github.com/boostorg/math/pull/507>>
... with fixed code here: https://github.com/boostorg/math/blob/e3cc94a580f3d1282578b0c31f985a392c866f... <https://github.com/boostorg/math/blob/e3cc94a580f3d1282578b0c31f985a392c866f... ><https://github.com/boostorg/math/blob/e3cc94a580f3d1282578b0c31f985a392c866f... <https://github.com/boostorg/math/blob/e3cc94a580f3d1282578b0c31f985a392c866f19/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp#L509>>
Gero, if you get a chance, could you give the patch a try? It will expectedly be merged in and available in the next release.
Kind regards, Chris
On Sunday, January 31, 2021, 3:22:53 PM GMT+1, Christopher Kormanyos <e_float@yahoo.com <mailto:e_float@yahoo.com>> wrote:
noticed that my simple patch with base=0 doesn't work.
Thanks Gero.
Yes. I am trying a patch that handles zero explicitly. I'm not quite sure if all zeros, NaNs and Infinities are correct yet,... But the patch is generally moving toward the fix shown in the link below...
If you get a chance, could you try that patch from the branch linked below?
https://github.com/boostorg/math/blob/2eac693e12547c1ca26800c2403e4e50f62d29... <https://github.com/boostorg/math/blob/2eac693e12547c1ca26800c2403e4e50f62d29... ><https://github.com/boostorg/math/blob/2eac693e12547c1ca26800c2403e4e50f62d29... <https://github.com/boostorg/math/blob/2eac693e12547c1ca26800c2403e4e50f62d29bd/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp#L512>>
Kind regards, Chris
On Sunday, January 31, 2021, 2:17:32 PM GMT+1, Gero Peterhoff <g.peterhoff@t-online.de <mailto:g.peterhoff@t-online.de>> wrote:
Hello Christopher, I just noticed that my simple patch with base=0 doesn't work. It is probably not that simple. https://godbolt.org/z/8Me15Y <https://godbolt.org/z/8Me15Y ><https://godbolt.org/z/8Me15Y <https://godbolt.org/z/8Me15Y>>
regards Gero
Am 30.01.21 um 16:22 schrieb Christopher Kormanyos:
the pow-function pow(scalar, complex) in boost/math/cstdfloat/cstdfloat_complex_std.hpp get wrong result.
Thanks Gero, I am on the go, but later today, I'll add this as an issue in Git and kick off the discussion for the fix with the colleagues.
A new issue can be found here, but it is not clear which code example elicits the unexpected behavior.
https://github.com/boostorg/math/issues/506 <https://github.com/boostorg/math/issues/506 ><https://github.com/boostorg/math/issues/506 <https://github.com/boostorg/math/issues/506 >><https://github.com/boostorg/math/issues/506 <https://github.com/boostorg/math/issues/506 ><https://github.com/boostorg/math/issues/506 <https://github.com/boostorg/math/issues/506>>>
On Thursday, January 28, 2021, 12:55:59 PM GMT+1, Gero Peterhoff via Boost <boost@lists.boost.org <mailto:boost@lists.boost.org> <mailto:boost@lists.boost.org <mailto:boost@lists.boost.org>>> wrote:
Hello, the pow-function pow(scalar, complex) in boost/math/cstdfloat/cstdfloat_complex_std.hpp get wrong result.
Current implementation: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { return std::exp(a * std::log(x)); }
I think that's correct: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { return std::exp(a * std::log(complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(x))); }
regards Gero
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost <http://lists.boost.org/mailman/listinfo.cgi/boost ><http://lists.boost.org/mailman/listinfo.cgi/boost <http://lists.boost.org/mailman/listinfo.cgi/boost >><http://lists.boost.org/mailman/listinfo.cgi/boost <http://lists.boost.org/mailman/listinfo.cgi/boost ><http://lists.boost.org/mailman/listinfo.cgi/boost <http://lists.boost.org/mailman/listinfo.cgi/boost>>>
Some other functions (e.g. log, exp) also give> incorrect results for some combinations> of nan, inf and 0 Yes, I did also notice that.
I also noticed a few basic things,> maybe you can say why that is:> - Why are there explicit complex classes> for FP types, why is this not implemented> completely via template? The advantage is> that built-ins can be used, on the other hand,> a separate class must be written for each> FP type - with the problems we are currently having.> - Why are there missing template conversion> ctors for the complex<FP-Type>? That will not do:> std::complex<int> ci{4711, 23}; std::complex<double> cd=ci; or std::complex<double> cd = std::complex<double>{ci}; but a ctor must be called explicitly std::complex<double> cd=std::complex<double>{double(ci.real()), double(ci.imag())}; // prevent warnings It's really annoying. - Why are many std-math functions missing> for complex; special-functions complete> (also applies to std::valarray)? I want to add such things in my math-lib,> as far as possible everything constexpr... These are good questions and valid points.The files in question were written in 2013/14.In time since passed, we have two major changesincluding Multiprecision's own 128-bitfloat class and a complex adapter. What need to do here is find out whatis thoday's proper niche for <cstdfloat.hpp>?And how can it be made more corrector less wrong, or more standards compliant,or however you want to put it? I will look into a potential larger refactor.A lot of this action will get too in-depthfor the board. Tracking of any significantprogress will probably be handled on theGitHub platform. Kind regards
On Thursday, February 4, 2021, 9:23:42 PM GMT+1, Gero Peterhoff <g.peterhoff@t-online.de> wrote: Hello Chris, Unfortunately, a few things have come up with me so that I (probably) won't be able to really help in the near future. Some other functions (e.g. log, exp) also give incorrect results for some combinations of nan, inf and 0. But I saw that gcc libquadmath (https://gcc.gnu.org/onlinedocs/libquadmath/Math-Library-Routines.html#Math-L...) offers some complex functions that work correctly. These could be used. But I don't know if clang, intel and/or other compilers can do that too. example inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { __complex128 res = __complex128{x.real(), x.imag()}; res = clogq(res); return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>{crealq(res), cimagq(res)}; } I also noticed a few basic things, maybe you can say why that is: - Why are there explicit complex classes for FP types, why is this not implemented completely via template? The advantage is that built-ins can be used, on the other hand, a separate class must be written for each FP type - with the problems we are currently having. - Why are there missing template conversion ctors for the complex<FP-Type>? That will not do: std::complex<int> ci{4711, 23}; std::complex<double> cd=ci; or std::complex<double> cd = std::complex<double>{ci}; but a ctor must be called explicitly std::complex<double> cd=std::complex<double>{double(ci.real()), double(ci.imag())}; // prevent warnings It's really annoying. - Why are many std-math functions missing for complex; special-functions complete (also applies to std::valarray)? I want to add such things in my math-lib, as far as possible everything constexpr. I also want to provide additional classes for dual and splitcomplex numbers (i²=0, i²=1, but it is far from complete - because it is quite extensive). Maybe these could also be included in boost. To do this, however, it would be necessary to convert the boost-math-lib to C++20, since some functions (or the distinction between dual, complex and splitcomplex - classes/functions) is only possible with concepts (otherwise unreasonable effort). I also need some additional typetraits. thx Gero Am 03.02.21 um 20:21 schrieb Christopher Kormanyos:
I patched this about as far as I'd like to go
Hello Chris, your patch doesn't seem to be working properly yet. I also noticed that there is the same problem with NaN and inf (and zeros?) for pow(complex, complex). I'm currently working on tests for all pow functions and patches. Hope I'll get this ready soon and send it to you. thx Gero
You are right. Thanks for any help you can contribute.
If I look more critically at the file, I think there might be other functions that could benefit from some increased handling of special arguments Nan, inf, zero real/imag. These include sqrt, log, log10, atan, and maybe a few others.
I might have underestimated the potential for improvement of this file and would now wonder if a more in-depth refactoring is a wise idea? Compromise on improvements of risk of breaking existing use in community?
Thoughts?
Kind regards, Chris
On Wednesday, February 3, 2021, 1:31:48 AM GMT+1, Gero Peterhoff <g.peterhoff@t-online.de> wrote:
Hello Chris, your patch doesn't seem to be working properly yet. I also noticed that there is the same problem with NaN and inf (and zeros?) for pow(complex, complex). I'm currently working on tests for all pow functions and patches. Hope I'll get this ready soon and send it to you.
thx Gero
Am 01.02.21 um 14:41 schrieb Christopher Kormanyos:
noticed that my simple patch with base=0 doesn't work.
Thanks Gero. Yes. I am trying a patch that handles zero explicitly. I'm not quite sure if all zeros, NaNs and Infinities are correct yet,
Gero, I patched this about as far as I'd like to go for this particular issue, added relevant tests. Underway, I did find that more possible work with zero, inf, NaN parameters that *could* be done in that particular header, but I will not modify these at the moment. This is because there are not a lot of requests for changes. I'd probably end up breaking existing code if I tried to clean up all kinds of edge cases that my eyes happened across.
That being said, the exact issue that you have pointed out and addressed in this thread on the board is being handled in the PR here: https://github.com/boostorg/math/pull/507 <https://github.com/boostorg/math/pull/507 ><https://github.com/boostorg/math/pull/507 <https://github.com/boostorg/math/pull/507>>
... with fixed code here: https://github.com/boostorg/math/blob/e3cc94a580f3d1282578b0c31f985a392c866f... <https://github.com/boostorg/math/blob/e3cc94a580f3d1282578b0c31f985a392c866f... ><https://github.com/boostorg/math/blob/e3cc94a580f3d1282578b0c31f985a392c866f... <https://github.com/boostorg/math/blob/e3cc94a580f3d1282578b0c31f985a392c866f19/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp#L509>>
Gero, if you get a chance, could you give the patch a try? It will expectedly be merged in and available in the next release.
Kind regards, Chris
On Sunday, January 31, 2021, 3:22:53 PM GMT+1, Christopher Kormanyos <e_float@yahoo.com <mailto:e_float@yahoo.com>> wrote:
noticed that my simple patch with base=0 doesn't work.
Thanks Gero.
Yes. I am trying a patch that handles zero explicitly. I'm not quite sure if all zeros, NaNs and Infinities are correct yet,... But the patch is generally moving toward the fix shown in the link below...
If you get a chance, could you try that patch from the branch linked below?
https://github.com/boostorg/math/blob/2eac693e12547c1ca26800c2403e4e50f62d29... <https://github.com/boostorg/math/blob/2eac693e12547c1ca26800c2403e4e50f62d29... ><https://github.com/boostorg/math/blob/2eac693e12547c1ca26800c2403e4e50f62d29... <https://github.com/boostorg/math/blob/2eac693e12547c1ca26800c2403e4e50f62d29bd/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp#L512>>
Kind regards, Chris
On Sunday, January 31, 2021, 2:17:32 PM GMT+1, Gero Peterhoff <g.peterhoff@t-online.de <mailto:g.peterhoff@t-online.de>> wrote:
Hello Christopher, I just noticed that my simple patch with base=0 doesn't work. It is probably not that simple. https://godbolt.org/z/8Me15Y <https://godbolt.org/z/8Me15Y ><https://godbolt.org/z/8Me15Y <https://godbolt.org/z/8Me15Y>>
regards Gero
Am 30.01.21 um 16:22 schrieb Christopher Kormanyos:
the pow-function pow(scalar, complex) in boost/math/cstdfloat/cstdfloat_complex_std.hpp get wrong result.
Thanks Gero, I am on the go, but later today, I'll add this as an issue in Git and kick off the discussion for the fix with the colleagues.
A new issue can be found here, but it is not clear which code example elicits the unexpected behavior.
https://github.com/boostorg/math/issues/506 <https://github.com/boostorg/math/issues/506 ><https://github.com/boostorg/math/issues/506 <https://github.com/boostorg/math/issues/506 >><https://github.com/boostorg/math/issues/506 <https://github.com/boostorg/math/issues/506 ><https://github.com/boostorg/math/issues/506 <https://github.com/boostorg/math/issues/506>>>
On Thursday, January 28, 2021, 12:55:59 PM GMT+1, Gero Peterhoff via Boost <boost@lists.boost.org <mailto:boost@lists.boost.org> <mailto:boost@lists.boost.org <mailto:boost@lists.boost.org>>> wrote:
Hello, the pow-function pow(scalar, complex) in boost/math/cstdfloat/cstdfloat_complex_std.hpp get wrong result.
Current implementation: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { return std::exp(a * std::log(x)); }
I think that's correct: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { return std::exp(a * std::log(complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(x))); }
regards Gero
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost <http://lists.boost.org/mailman/listinfo.cgi/boost ><http://lists.boost.org/mailman/listinfo.cgi/boost <http://lists.boost.org/mailman/listinfo.cgi/boost >><http://lists.boost.org/mailman/listinfo.cgi/boost <http://lists.boost.org/mailman/listinfo.cgi/boost ><http://lists.boost.org/mailman/listinfo.cgi/boost <http://lists.boost.org/mailman/listinfo.cgi/boost>>>
On 04/02/2021 20:23, Gero Peterhoff via Boost wrote:
Hello Chris, Unfortunately, a few things have come up with me so that I (probably) won't be able to really help in the near future. Some other functions (e.g. log, exp) also give incorrect results for some combinations of nan, inf and 0.
But I saw that gcc libquadmath (https://gcc.gnu.org/onlinedocs/libquadmath/Math-Library-Routines.html#Math-L...) offers some complex functions that work correctly. These could be used. But I don't know if clang, intel and/or other compilers can do that too. example inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { __complex128 res = __complex128{x.real(), x.imag()}; res = clogq(res); return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>{crealq(res), cimagq(res)}; }
I also noticed a few basic things, maybe you can say why that is: - Why are there explicit complex classes for FP types, why is this not implemented completely via template? The advantage is that built-ins can be used, on the other hand, a separate class must be written for each FP type - with the problems we are currently having. This is all a question for the C++ committee, my speculation would be
The place to check for this is C99 Annex G - but note that this is non-normative so there will be implementations of std::complex which do not do anything in particular in these cases... platforms too with no infinity or NaN. that they wished to restrict the scope of std::complex to float/double/long double.
- Why are there missing template conversion ctors for the complex<FP-Type>? That will not do: std::complex<int> ci{4711, 23}; std::complex<double> cd=ci; or std::complex<double> cd = std::complex<double>{ci}; but a ctor must be called explicitly std::complex<double> cd=std::complex<double>{double(ci.real()), double(ci.imag())}; // prevent warnings It's really annoying. - Why are many std-math functions missing for complex; special-functions complete (also applies to std::valarray)?
I want to add such things in my math-lib, as far as possible everything constexpr. I also want to provide additional classes for dual and splitcomplex numbers (i²=0, i²=1, but it is far from complete - because it is quite extensive). Maybe these could also be included in boost. To do this, however, it would be necessary to convert the boost-math-lib to C++20, since some functions (or the distinction between dual, complex and splitcomplex - classes/functions) is only possible with concepts (otherwise unreasonable effort). I also need some additional typetraits.
If you want to provide implementations for any complex valued special functions we can take care of the algorithm overload selection - enable_if will do fine, there's no need for concepts just yet. Best John. -- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus
On Feb 5, 2021, at 9:00 AM, John Maddock via Boost <boost@lists.boost.org> wrote:
On 04/02/2021 20:23, Gero Peterhoff via Boost wrote:
Hello Chris, Unfortunately, a few things have come up with me so that I (probably) won't be able to really help in the near future. Some other functions (e.g. log, exp) also give incorrect results for some combinations of nan, inf and 0.
The place to check for this is C99 Annex G - but note that this is non-normative so there will be implementations of std::complex which do not do anything in particular in these cases... platforms too with no infinity or NaN.
But I saw that gcc libquadmath (https://gcc.gnu.org/onlinedocs/libquadmath/Math-Library-Routines.html#Math-L...) offers some complex functions that work correctly. These could be used. But I don't know if clang, intel and/or other compilers can do that too. example inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { __complex128 res = __complex128{x.real(), x.imag()}; res = clogq(res); return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>{crealq(res), cimagq(res)}; }
I also noticed a few basic things, maybe you can say why that is: - Why are there explicit complex classes for FP types, why is this not implemented completely via template? The advantage is that built-ins can be used, on the other hand, a separate class must be written for each FP type - with the problems we are currently having. This is all a question for the C++ committee, my speculation would be that they wished to restrict the scope of std::complex to float/double/long double.
I refer you to https://wg21.link/complex.numbers p2, which states: The effect of instantiating the template complex for any type other than float, double, or long double is unspecified. — Marshall
Some other functions (e.g. log, exp) also> give incorrect results Based on this comment and all theother great comments comments so far,...This thread has motivated reformulationof the original change request. It will be handled as a PR in Math here:https://github.com/boostorg/math/pull/507 Treating the full scope of necessarydiscussions might be best handledin the GitHub issue.
Thanks for getting the ball rollingon this and kind regards, Chris On Friday, February 5, 2021, 6:50:37 PM GMT+1, Marshall Clow via Boost <boost@lists.boost.org> wrote: On Feb 5, 2021, at 9:00 AM, John Maddock via Boost <boost@lists.boost.org> wrote:
On 04/02/2021 20:23, Gero Peterhoff via Boost wrote:
Hello Chris, Unfortunately, a few things have come up with me so that I (probably) won't be able to really help in the near future. Some other functions (e.g. log, exp) also give incorrect results for some combinations of nan, inf and 0.
The place to check for this is C99 Annex G - but note that this is non-normative so there will be implementations of std::complex which do not do anything in particular in these cases... platforms too with no infinity or NaN.
But I saw that gcc libquadmath (https://gcc.gnu.org/onlinedocs/libquadmath/Math-Library-Routines.html#Math-L...) offers some complex functions that work correctly. These could be used. But I don't know if clang, intel and/or other compilers can do that too. example inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { __complex128 res = __complex128{x.real(), x.imag()}; res = clogq(res); return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>{crealq(res), cimagq(res)}; }
I also noticed a few basic things, maybe you can say why that is: - Why are there explicit complex classes for FP types, why is this not implemented completely via template? The advantage is that built-ins can be used, on the other hand, a separate class must be written for each FP type - with the problems we are currently having. This is all a question for the C++ committee, my speculation would be that they wished to restrict the scope of std::complex to float/double/long double.
I refer you to https://wg21.link/complex.numbers p2, which states: The effect of instantiating the template complex for any type other than float, double, or long double is unspecified. — Marshall _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On Fri, Feb 5, 2021 at 10:50 AM Marshall Clow via Boost < boost@lists.boost.org> wrote:
On Feb 5, 2021, at 9:00 AM, John Maddock via Boost <boost@lists.boost.org> wrote:
I also noticed a few basic things, maybe you can say why that is: - Why are there explicit complex classes for FP types, why is this not
This is all a question for the C++ committee, my speculation would be
implemented completely via template? The advantage is that built-ins can be used, on the other hand, a separate class must be written for each FP type - with the problems we are currently having. that they wished to restrict the scope of std::complex to float/double/long double.
I refer you to https://wg21.link/complex.numbers p2, which states: The effect of instantiating the template complex for any type other than float, double, or long double is unspecified.
— Marshall
I will note that there is a proposal that might alter this stance: https://wg21.link/P1467R4
I will note that there is a proposal that> might alter this stance:> https://wg21.link/P1467R4 Oh thanks. This is great! It's goodto see the ball rolling on that one.
Personally, I would really enjoyto see floatN_t in C/C++ world. I was notaware of this particular proposal, which does,in fact, mention, revive and extend previous,partial (yet stalled) work by Bristow, Maddockand myself --- Floating-Point Typedefs HavingSpecified Widths - N1703. In fact, the preliminary work in https://github.com/boostorg/math/tree/develop/include/boost/math/cstdfloat (which contains the original topic of this thread) attempts to providea sensible working model for floatN_t. If ever desired to better align Boost withhttps://wg21.link/P1467R4as it progresses, please feel free to contactus (or me) in the future. Kind regards, Chris On Saturday, February 6, 2021, 1:38:06 AM GMT+1, Jeff Garland via Boost <boost@lists.boost.org> wrote: On Fri, Feb 5, 2021 at 10:50 AM Marshall Clow via Boost < boost@lists.boost.org> wrote:
On Feb 5, 2021, at 9:00 AM, John Maddock via Boost <boost@lists.boost.org> wrote:
I also noticed a few basic things, maybe you can say why that is: - Why are there explicit complex classes for FP types, why is this not
This is all a question for the C++ committee, my speculation would be
implemented completely via template? The advantage is that built-ins can be used, on the other hand, a separate class must be written for each FP type - with the problems we are currently having. that they wished to restrict the scope of std::complex to float/double/long double.
I refer you to https://wg21.link/complex.numbers p2, which states: The effect of instantiating the template complex for any type other than float, double, or long double is unspecified.
— Marshall
I will note that there is a proposal that might alter this stance: https://wg21.link/P1467R4 _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
That's the problem: the generic std::complex class has generic conversion ctors, the FP specializations don't. I don't understand why this is done. Am 05.02.21 um 18:50 schrieb Marshall Clow via Boost:
I refer you to https://wg21.link/complex.numbers p2, which states: The effect of instantiating the template complex for any type other than float, double, or long double is unspecified.
— Marshall
On 08/02/2021 17:30, Gero Peterhoff via Boost wrote:
That's the problem: the generic std::complex class has generic conversion ctors, the FP specializations don't. I don't understand why this is done.
Actually the generic template specification is redundant given that only float/double/long double specializations are allowed. BTW the specializations do have converting constructors, but they are explicit when narrowing which is the right design IMO. -- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus
It would be very desirable to implement all conversion ctors generically so that both directions work: 1) std::complex<double> a{1.1, 2.2}; std::complex<int> b{a}; // works 2) std::complex<int> a{1, 2}; std::complex<double> b{a}; // doesn't work without explicit call std::complex<double> b{a.real(), a.imag()}; or std::complex<double> b{double(a.real()), double(a.imag())}; to prevent warnings. This is cumbersome, confusing and a source of errors. Am 08.02.21 um 19:04 schrieb John Maddock via Boost:
On 08/02/2021 17:30, Gero Peterhoff via Boost wrote:
That's the problem: the generic std::complex class has generic conversion ctors, the FP specializations don't. I don't understand why this is done.
Actually the generic template specification is redundant given that only float/double/long double specializations are allowed.
BTW the specializations do have converting constructors, but they are explicit when narrowing which is the right design IMO.
It would be very desirable to implement all> conversion ctors generically so that both> directions work... The plan is to try to achieve generally the following:
*Interface model based on C++14 <complex>. * Use C99 Annex G to guide us for the rightspecial values to return for arguments zero,INF, NaN? Are those two top-level requirements OK,or at least a good start, more right (less wrong)? Kind regards, Chris On Monday, February 8, 2021, 7:40:12 PM GMT+1, Gero Peterhoff via Boost <boost@lists.boost.org> wrote: It would be very desirable to implement all conversion ctors generically so that both directions work: 1) std::complex<double> a{1.1, 2.2}; std::complex<int> b{a}; // works 2) std::complex<int> a{1, 2}; std::complex<double> b{a}; // doesn't work without explicit call std::complex<double> b{a.real(), a.imag()}; or std::complex<double> b{double(a.real()), double(a.imag())}; to prevent warnings. This is cumbersome, confusing and a source of errors. Am 08.02.21 um 19:04 schrieb John Maddock via Boost:
On 08/02/2021 17:30, Gero Peterhoff via Boost wrote:
That's the problem: the generic std::complex class has generic conversion ctors, the FP specializations don't. I don't understand why this is done.
Actually the generic template specification is redundant given that only float/double/long double specializations are allowed.
BTW the specializations do have converting constructors, but they are explicit when narrowing which is the right design IMO.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Hello Chris, i see that the pow-bug (https://github.com/boostorg/math/issues/506) is also included in 1.76. I think regardless of special values (zero, nan, inf) this should be fixed: inline complex <BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { constexpr BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE zero_v{0}; const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log_i_zero{std::log(std::abs(x)), std::atan2(zero_v, x)}; return std::exp(a * log_i_zero); } There is also an error in your sqrt: inline complex <BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sqrt(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { using std::fabs; using std::sqrt; if (x.real() > 0) { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s = sqrt((fabs(x.real()) + std::abs (x)) / 2); return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(s, x.imag() / (s * 2)); } else if (x.real() < 0) { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s = sqrt((fabs(x.real()) + std::abs(x)) / 2); const bool imag_is_neg = (x.imag() < 0); return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(fabs(x.imag()) / (s * 2), (imag_is_neg ? -s : s)); } else { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sqrt_xi_half = sqrt(x.imag() / 2); return complex <BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> (sqrt_xi_half, sqrt_xi_half); } } As you can see this gives wrong results for real==0 and imag<0 -> std::sqrt from negative number. There are several ways to remedy the error: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sqrt(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { // branchfree return std::pow(x, boost::math::constants::half<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>()); // constexpr BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE // zero_v{0}; /* // 2 branches const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s{std::sqrt((std::abs(x.real()) + std::abs(x)) * boost::math::constants::half<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>())}, t{(std::abs(x.imag ()) * boost::math::constants::half<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>()) / s}; return (x.real() >= zero_v) ? complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>{s, std::copysign (t, x.imag())}: complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>{t, std::copysign (s, x.imag())}; */ /* // 3 branches if (x.real() == zero_v) { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s{std::sqrt(std::abs(x.imag()) * boost::math::constants::half<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>())}; return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>{s, std::copysign(s, x.imag())}; } else { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s{std::sqrt((std::abs(x.real()) + std::abs(x)) * boost::math::constants::half<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>())}, t{(std::abs(x.imag()) * boost::math::constants::half<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>()) / s}; return (x.real() > zero_v) ? complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>{s, std::copysign(t, x.imag())}: complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>{t, std::copysign(s, x.imag())}; } */ } I think pow(x, 0.5) is accurate enough - it is also the fastest. According to the same scheme, cbrt can also be implemented, which is missing so far: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> cbrt(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { constexpr BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE three_v{3}; return std::exp(std::log(x) / three_v); } Something else. I am currently working on an extended math lib, in which I provide many functions that were previously missing. But i don't know how to implement these functions (like atan2): acot2, atanh2 and acoth2. Do you know the algorithms or has information about them? thx Gero
i see that the pow-bug> (https://github.com/boostorg/math/issues/506)> is also included in 1.76 Hi Gero, Thank you for following up on this. You are correct.
The state of that issue is *open*, which means,unfortunately, that I have not yet fixed it. The intent is to gather outstanding relatedpoints, bug-lets and the like and fix theseen-masse in a more dedicated driveforward. The time for me to drive forward on thisis rapidly approaching. The deal is that1.76 was full of many larger organizationsland code-technical efforts in both Mathas well as Multiprecision, followed bycontinued cleanup to this very day. Forward mothion on this issue is plannedforthcoming. kind regards, Chris On Sunday, April 18, 2021, 8:08:39 PM GMT+2, Gero Peterhoff <g.peterhoff@t-online.de> wrote: Hello Chris, i see that the pow-bug (https://github.com/boostorg/math/issues/506) is also included in 1.76. I think regardless of special values (zero, nan, inf) this should be fixed: inline complex <BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { constexpr BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE zero_v{0}; const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log_i_zero{std::log(std::abs(x)), std::atan2(zero_v, x)}; return std::exp(a * log_i_zero); } There is also an error in your sqrt: inline complex <BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sqrt(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { using std::fabs; using std::sqrt; if (x.real() > 0) { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s = sqrt((fabs(x.real()) + std::abs (x)) / 2); return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(s, x.imag() / (s * 2)); } else if (x.real() < 0) { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s = sqrt((fabs(x.real()) + std::abs(x)) / 2); const bool imag_is_neg = (x.imag() < 0); return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(fabs(x.imag()) / (s * 2), (imag_is_neg ? -s : s)); } else { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sqrt_xi_half = sqrt(x.imag() / 2); return complex <BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> (sqrt_xi_half, sqrt_xi_half); } } As you can see this gives wrong results for real==0 and imag<0 -> std::sqrt from negative number. There are several ways to remedy the error: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sqrt(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { // branchfree return std::pow(x, boost::math::constants::half<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>()); // constexpr BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE // zero_v{0}; /* // 2 branches const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s{std::sqrt((std::abs(x.real()) + std::abs(x)) * boost::math::constants::half<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>())}, t{(std::abs(x.imag ()) * boost::math::constants::half<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>()) / s}; return (x.real() >= zero_v) ? complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>{s, std::copysign (t, x.imag())}: complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>{t, std::copysign (s, x.imag())}; */ /* // 3 branches if (x.real() == zero_v) { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s{std::sqrt(std::abs(x.imag()) * boost::math::constants::half<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>())}; return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>{s, std::copysign(s, x.imag())}; } else { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s{std::sqrt((std::abs(x.real()) + std::abs(x)) * boost::math::constants::half<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>())}, t{(std::abs(x.imag()) * boost::math::constants::half<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>()) / s}; return (x.real() > zero_v) ? complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>{s, std::copysign(t, x.imag())}: complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>{t, std::copysign(s, x.imag())}; } */ } I think pow(x, 0.5) is accurate enough - it is also the fastest. According to the same scheme, cbrt can also be implemented, which is missing so far: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> cbrt(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { constexpr BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE three_v{3}; return std::exp(std::log(x) / three_v); } Something else. I am currently working on an extended math lib, in which I provide many functions that were previously missing. But i don't know how to implement these functions (like atan2): acot2, atanh2 and acoth2. Do you know the algorithms or has information about them? thx Gero
Hello Chris, do you already know how you want to realized the new implementation? There are several options: a) template specialization (as before): - write all functions yourself - use the functions of libquadmath (gcc+clang), but not all of them are available, so you would have to write some yourself anyway. I also don't know if the intel compiler has any. b) implement completely via template Both have advantages and disadvantages a) Advantages: you don't have to take care of everything yourself but can use standard functions that have been tested Disadvantages: inflexible, everything has to be rewritten for each additional template specialization; DRY, contradicts the template idea b) Advantages: flexible, no violation of the DRY principle; if errors occur, they only have to be corrected at EXACTLY ONE point and not in EVERY template specialization etc. Disadvantages: high initial effort Of course i prefer variant b. But i want to go into that: originally i only planned to write classes/functions for dual and splitcomplex numbers. These should meet the requirements: - exactly + error handling (i have to do a lot more :-) - fast - constexpr Since all 3 classes (scomplex, complex, dual) are similar, it makes sense to put them on a common code base. This is definitely NOT useful: template <typename T> class scomplex {T r, i; }; template <typename T> class complex {T r, i; }; template <typename T> class dual {T r, i; }; After a lot of trial and error, i came to the conclusion that it is only possible this way (principle): template <typename Type, size_t Size> class simd : public std::array<Type, Size> { functions/operators }; and then template <typename Type> class scomplex {simd<Type, 2> value;}; template <typename Type> class complex {simd<Type, 2> value;}; template <typename Type> class dual {simd<Type, 2> value;}; This has a lot of advantages: - It can be guaranteed that the real and imag values are in direct succession in the memory and that the autovectorization works better - a number of functions/operators can simply use the simd functions/operators (e.g. i came across a bug in the autovectorizers of gcc+clang, which i can work around in a central location) - operator[] and std::get can be made available; that becomes interesting if you also implement quaternion, octonionen, sedenion etc. - type conversions can also be handled centrally in simd In my current implementations i go even further: 1) std::execution::x can be specified for simd (for which I had to extend it for constexpr) 2) reinterpreted the math-functions: - it drives me crazy if the result types do not match the argument, e.g. std::sin(Float) -> Float std::sin(Integer) -> Float std::sin(std::complex<Float>) -> std::complex <Float> std::sin(std::complex<Integer>) -> std::complex <Integer> - now there is only one variant - WYCIWYG "What You Call Is What You Get": std::math::sin(Type) -> Type std::math::sin(std::math::complex<Type>) -> std::math::complex <Type> where you can set centrally whether rounding or shortening should be made for Float->Integer. Otherwise, for example, std::math::sin(integer) would (almost) always be 0. 3) retrofitted some missing functions - cot, sec, csc ... - inv 1/x, can be optimized for s/complex, dual etc. - rounding - classifiacation - and more My goal is to provide all math and special functions constexpr for scalar types, scomplex, complex and dual (later then quaternion, octonionen, sedenion, ...). A hell of a lot of effort. But I think that you want to do that too - we could help each other and learn a lot. @John can you provide in boost/math/constants: root(5) 1/root(5) psi=1-phi zero=0 one=1 two=2 three=3 four=4 five=5 ten=10 quarter=0.25 This is useful to guarantee that the values are constexpr. thx Gero Am 19.04.21 um 17:28 schrieb Christopher Kormanyos:
i see that the pow-bug (https://github.com/boostorg/math/issues/506 <https://github.com/boostorg/math/issues/506>) is also included in 1.76
Hi Gero,
Thank you for following up on this.
You are correct.
The state of that issue is *open*, which means, unfortunately, that I have not yet fixed it.
The intent is to gather outstanding related points, bug-lets and the like and fix these en-masse in a more dedicated drive forward.
The time for me to drive forward on this is rapidly approaching. The deal is that 1.76 was full of many larger organizationsl and code-technical efforts in both Math as well as Multiprecision, followed by continued cleanup to this very day.
Forward mothion on this issue is planned forthcoming.
kind regards, Chris
do you already know how you want to> realized the new implementation
Hi Gero. Thanks for responding and pleaseaccept my apologies for the late response. The short answer to the queries above andsuggestions from your side, having muchdepth and information is that i plan toimprove (via refactor) for 1.77. This is the only actual issue in Boostthat I have assigned to myself rightnow. I took some time to clean upsome projects in other domains,but expect to re-open work on thisissue shortly. Kind regards, Chris On Saturday, May 1, 2021, 11:00:18 PM GMT+2, Gero Peterhoff <g.peterhoff@t-online.de> wrote: Hello Chris, do you already know how you want to realized the new implementation? There are several options: a) template specialization (as before): - write all functions yourself - use the functions of libquadmath (gcc+clang), but not all of them are available, so you would have to write some yourself anyway. I also don't know if the intel compiler has any. b) implement completely via template Both have advantages and disadvantages a) Advantages: you don't have to take care of everything yourself but can use standard functions that have been tested Disadvantages: inflexible, everything has to be rewritten for each additional template specialization; DRY, contradicts the template idea b) Advantages: flexible, no violation of the DRY principle; if errors occur, they only have to be corrected at EXACTLY ONE point and not in EVERY template specialization etc. Disadvantages: high initial effort Of course i prefer variant b. But i want to go into that: originally i only planned to write classes/functions for dual and splitcomplex numbers. These should meet the requirements: - exactly + error handling (i have to do a lot more :-) - fast - constexpr Since all 3 classes (scomplex, complex, dual) are similar, it makes sense to put them on a common code base. This is definitely NOT useful: template <typename T> class scomplex {T r, i; }; template <typename T> class complex {T r, i; }; template <typename T> class dual {T r, i; }; After a lot of trial and error, i came to the conclusion that it is only possible this way (principle): template <typename Type, size_t Size> class simd : public std::array<Type, Size> { functions/operators }; and then template <typename Type> class scomplex {simd<Type, 2> value;}; template <typename Type> class complex {simd<Type, 2> value;}; template <typename Type> class dual {simd<Type, 2> value;}; This has a lot of advantages: - It can be guaranteed that the real and imag values are in direct succession in the memory and that the autovectorization works better - a number of functions/operators can simply use the simd functions/operators (e.g. i came across a bug in the autovectorizers of gcc+clang, which i can work around in a central location) - operator[] and std::get can be made available; that becomes interesting if you also implement quaternion, octonionen, sedenion etc. - type conversions can also be handled centrally in simd In my current implementations i go even further: 1) std::execution::x can be specified for simd (for which I had to extend it for constexpr) 2) reinterpreted the math-functions: - it drives me crazy if the result types do not match the argument, e.g. std::sin(Float) -> Float std::sin(Integer) -> Float std::sin(std::complex<Float>) -> std::complex <Float> std::sin(std::complex<Integer>) -> std::complex <Integer> - now there is only one variant - WYCIWYG "What You Call Is What You Get": std::math::sin(Type) -> Type std::math::sin(std::math::complex<Type>) -> std::math::complex <Type> where you can set centrally whether rounding or shortening should be made for Float->Integer. Otherwise, for example, std::math::sin(integer) would (almost) always be 0. 3) retrofitted some missing functions - cot, sec, csc ... - inv 1/x, can be optimized for s/complex, dual etc. - rounding - classifiacation - and more My goal is to provide all math and special functions constexpr for scalar types, scomplex, complex and dual (later then quaternion, octonionen, sedenion, ...). A hell of a lot of effort. But I think that you want to do that too - we could help each other and learn a lot. @John can you provide in boost/math/constants: root(5) 1/root(5) psi=1-phi zero=0 one=1 two=2 three=3 four=4 five=5 ten=10 quarter=0.25 This is useful to guarantee that the values are constexpr. thx Gero Am 19.04.21 um 17:28 schrieb Christopher Kormanyos:
i see that the pow-bug (https://github.com/boostorg/math/issues/506 <https://github.com/boostorg/math/issues/506>) is also included in 1.76
Hi Gero,
Thank you for following up on this.
You are correct.
The state of that issue is *open*, which means, unfortunately, that I have not yet fixed it.
The intent is to gather outstanding related points, bug-lets and the like and fix these en-masse in a more dedicated drive forward.
The time for me to drive forward on this is rapidly approaching. The deal is that 1.76 was full of many larger organizationsl and code-technical efforts in both Math as well as Multiprecision, followed by continued cleanup to this very day.
Forward mothion on this issue is planned forthcoming.
kind regards, Chris
provide all math and special functions> constexpr for scalar types, scomplex,> complex I will start with 506 with the noteswe made here:https://github.com/boostorg/math/issues/506 I think I can commit to that level in 506.I'm not sure if I will have time forother numerical types in this areain the next time, as GSoC willalso begin.
Kind regards, Chris On Saturday, May 1, 2021, 11:00:18 PM GMT+2, Gero Peterhoff <g.peterhoff@t-online.de> wrote: Hello Chris, do you already know how you want to realized the new implementation? There are several options: a) template specialization (as before): - write all functions yourself - use the functions of libquadmath (gcc+clang), but not all of them are available, so you would have to write some yourself anyway. I also don't know if the intel compiler has any. b) implement completely via template Both have advantages and disadvantages a) Advantages: you don't have to take care of everything yourself but can use standard functions that have been tested Disadvantages: inflexible, everything has to be rewritten for each additional template specialization; DRY, contradicts the template idea b) Advantages: flexible, no violation of the DRY principle; if errors occur, they only have to be corrected at EXACTLY ONE point and not in EVERY template specialization etc. Disadvantages: high initial effort Of course i prefer variant b. But i want to go into that: originally i only planned to write classes/functions for dual and splitcomplex numbers. These should meet the requirements: - exactly + error handling (i have to do a lot more :-) - fast - constexpr Since all 3 classes (scomplex, complex, dual) are similar, it makes sense to put them on a common code base. This is definitely NOT useful: template <typename T> class scomplex {T r, i; }; template <typename T> class complex {T r, i; }; template <typename T> class dual {T r, i; }; After a lot of trial and error, i came to the conclusion that it is only possible this way (principle): template <typename Type, size_t Size> class simd : public std::array<Type, Size> { functions/operators }; and then template <typename Type> class scomplex {simd<Type, 2> value;}; template <typename Type> class complex {simd<Type, 2> value;}; template <typename Type> class dual {simd<Type, 2> value;}; This has a lot of advantages: - It can be guaranteed that the real and imag values are in direct succession in the memory and that the autovectorization works better - a number of functions/operators can simply use the simd functions/operators (e.g. i came across a bug in the autovectorizers of gcc+clang, which i can work around in a central location) - operator[] and std::get can be made available; that becomes interesting if you also implement quaternion, octonionen, sedenion etc. - type conversions can also be handled centrally in simd In my current implementations i go even further: 1) std::execution::x can be specified for simd (for which I had to extend it for constexpr) 2) reinterpreted the math-functions: - it drives me crazy if the result types do not match the argument, e.g. std::sin(Float) -> Float std::sin(Integer) -> Float std::sin(std::complex<Float>) -> std::complex <Float> std::sin(std::complex<Integer>) -> std::complex <Integer> - now there is only one variant - WYCIWYG "What You Call Is What You Get": std::math::sin(Type) -> Type std::math::sin(std::math::complex<Type>) -> std::math::complex <Type> where you can set centrally whether rounding or shortening should be made for Float->Integer. Otherwise, for example, std::math::sin(integer) would (almost) always be 0. 3) retrofitted some missing functions - cot, sec, csc ... - inv 1/x, can be optimized for s/complex, dual etc. - rounding - classifiacation - and more My goal is to provide all math and special functions constexpr for scalar types, scomplex, complex and dual (later then quaternion, octonionen, sedenion, ...). A hell of a lot of effort. But I think that you want to do that too - we could help each other and learn a lot. @John can you provide in boost/math/constants: root(5) 1/root(5) psi=1-phi zero=0 one=1 two=2 three=3 four=4 five=5 ten=10 quarter=0.25 This is useful to guarantee that the values are constexpr. thx Gero Am 19.04.21 um 17:28 schrieb Christopher Kormanyos:
i see that the pow-bug (https://github.com/boostorg/math/issues/506 <https://github.com/boostorg/math/issues/506>) is also included in 1.76
Hi Gero,
Thank you for following up on this.
You are correct.
The state of that issue is *open*, which means, unfortunately, that I have not yet fixed it.
The intent is to gather outstanding related points, bug-lets and the like and fix these en-masse in a more dedicated drive forward.
The time for me to drive forward on this is rapidly approaching. The deal is that 1.76 was full of many larger organizationsl and code-technical efforts in both Math as well as Multiprecision, followed by continued cleanup to this very day.
Forward mothion on this issue is planned forthcoming.
kind regards, Chris
acot2, atanh2 and acoth2. Do you know> the algorithms or has information about them? I might have some notes from previousprojects. Please allow me to get backto you on this particular query. Thanks again Gero! Kind regards, Chris
On Sunday, April 18, 2021, 8:08:39 PM GMT+2, Gero Peterhoff <g.peterhoff@t-online.de> wrote: Hello Chris, i see that the pow-bug (https://github.com/boostorg/math/issues/506) is also included in 1.76. I think regardless of special values (zero, nan, inf) this should be fixed: inline complex <BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) { constexpr BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE zero_v{0}; const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log_i_zero{std::log(std::abs(x)), std::atan2(zero_v, x)}; return std::exp(a * log_i_zero); } There is also an error in your sqrt: inline complex <BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sqrt(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { using std::fabs; using std::sqrt; if (x.real() > 0) { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s = sqrt((fabs(x.real()) + std::abs (x)) / 2); return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(s, x.imag() / (s * 2)); } else if (x.real() < 0) { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s = sqrt((fabs(x.real()) + std::abs(x)) / 2); const bool imag_is_neg = (x.imag() < 0); return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(fabs(x.imag()) / (s * 2), (imag_is_neg ? -s : s)); } else { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sqrt_xi_half = sqrt(x.imag() / 2); return complex <BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> (sqrt_xi_half, sqrt_xi_half); } } As you can see this gives wrong results for real==0 and imag<0 -> std::sqrt from negative number. There are several ways to remedy the error: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sqrt(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { // branchfree return std::pow(x, boost::math::constants::half<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>()); // constexpr BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE // zero_v{0}; /* // 2 branches const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s{std::sqrt((std::abs(x.real()) + std::abs(x)) * boost::math::constants::half<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>())}, t{(std::abs(x.imag ()) * boost::math::constants::half<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>()) / s}; return (x.real() >= zero_v) ? complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>{s, std::copysign (t, x.imag())}: complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>{t, std::copysign (s, x.imag())}; */ /* // 3 branches if (x.real() == zero_v) { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s{std::sqrt(std::abs(x.imag()) * boost::math::constants::half<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>())}; return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>{s, std::copysign(s, x.imag())}; } else { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s{std::sqrt((std::abs(x.real()) + std::abs(x)) * boost::math::constants::half<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>())}, t{(std::abs(x.imag()) * boost::math::constants::half<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>()) / s}; return (x.real() > zero_v) ? complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>{s, std::copysign(t, x.imag())}: complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>{t, std::copysign(s, x.imag())}; } */ } I think pow(x, 0.5) is accurate enough - it is also the fastest. According to the same scheme, cbrt can also be implemented, which is missing so far: inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> cbrt(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { constexpr BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE three_v{3}; return std::exp(std::log(x) / three_v); } Something else. I am currently working on an extended math lib, in which I provide many functions that were previously missing. But i don't know how to implement these functions (like atan2): acot2, atanh2 and acoth2. Do you know the algorithms or has information about them? thx Gero
participants (6)
-
Christopher Kormanyos
-
Gero Peterhoff
-
Janek Kozicki
-
Jeff Garland
-
John Maddock
-
Marshall Clow