C++ Logo

std-discussion

Advanced search

Re: [isocpp-sci] Problems with pow(std::complex<T>, double)

From: Mark Hoemmen <mhoemmen_at_[hidden]>
Date: Wed, 3 Mar 2021 15:31:52 -0700
complex<long double> does help a little bit: https://godbolt.org/z/dj9cnv

Davis pointed out that mixing the tiny imaginary part with the not-tiny
real part is the problem. That means that the best you can hope for is
a small normwise forward error, which we do get (the last thing printed
in the above example). Generally, getting pointwise small errors is
harder than getting normwise small errors.

mfh

On 3/3/2021 13:02, Peter C++ via Sci wrote:
> while not a cure, try complex<long double> if that gives you more precision on your system.
>
> Sent from Peter Sommerlad's iPad
> +41 79 432 23 32
>
>> On 3 Mar 2021, at 20:52, Bell, Ian H. (Fed) <ian.bell_at_[hidden]> wrote:
>>
>> Davis,
>>
>> Thanks for the link to the cpython code. That's quite conclusive, and I can see the logic of that approach.
>>
>> Can you think of a relatively safe way to get C++ to play nicely with the evaluation of these "tiny imaginary components are OK" problem? I get that a^b is "problematic" (to say the least) for a complex and b non-integer, but that's the problem I'm banging my head against at the moment.
>>
>> Ian
>>
>> -----Original Message-----
>> From: Herring, Davis <herring_at_[hidden]>
>> Sent: Wednesday, March 3, 2021 2:25 PM
>> To: Peter Sommerlad (C++) <peter.cpp_at_[hidden]>
>> Cc: Bell, Ian H. (Fed) <ian.bell_at_[hidden]>; std-discussion_at_[hidden]; sci_at_[hidden]
>> Subject: Re: [isocpp-sci] [std-discussion] Problems with pow(std::complex<T>, double)
>>
>>>> using an integral 2nd argument to pow() solves the issue. May be
>>>> python is optimizing by checking that 2.0 is actually integral.
>> This is exactly what happens <https://github.com/python/cpython/blob/master/Objects/complexobject.c#L530>. In a similar, albeit static, fashion, libstdc++ has retained the int overload (removed in C++11) for similar reasons <https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/std/complex#L1011>.
>>
>>> Taking the generic definition of complex pow function I can confirm
>>> that the pow() implementation is carrying the same error. May be, what
>>> you attempt is just beyond reasonable precision to expect from floating point.
>> The problem is that the function being differentiated intermixes the real and imaginary components of its input (when implemented as appropriate for floating-point inputs) via converting it to polar form. That completely defeats the "tiny imaginary components are OK" idea.
>>
>> Davis
> _______________________________________________
> Sci mailing list
> Sci_at_[hidden]
> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/sci
> Link to this post: http://lists.isocpp.org/sci/2021/03/0381.php

Received on 2021-03-03 16:31:57