# STD-DISCUSSION

Subject: Re: Problems with pow(std::complex<T>, double)
Date: 2021-03-03 10:01:34

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.

IÂ amÂ CC-inÂ numericsÂ SG6Â toÂ queryÂ theÂ numericsÂ expertsÂ there.

#includeÂ <iostream>
#includeÂ <complex>
#includeÂ <cmath>

intÂ main()

{
Â Â Â Â usingÂ namespaceÂ std::literals;

Â Â Â Â autoÂ xÂ =Â -0.1+Â 1e-100i;
Â Â Â Â autoÂ yÂ =Â 2.0+0i;
Â Â Â Â autoÂ zÂ =Â std::exp(y*std::log(x));
Â Â Â Â autoÂ zpowÂ =Â std::pow(x,y);

Â Â Â  std::cout << z << zpow << std::pow(-0.1+ 1e-100i, 2) << ":" << x *
xÂ <<std::endl;

}

Peter.

PeterÂ SommerladÂ (C++)Â viaÂ Std-DiscussionÂ wroteÂ onÂ 03.03.21Â 16:48:
> using an integral 2nd argument to pow() solves the issue. May be
> python isÂ optimizingÂ byÂ checkingÂ thatÂ 2.0Â isÂ actuallyÂ integral.
>
>

>
> #includeÂ <iostream>
> #includeÂ <complex>
> #includeÂ <cmath>
>
> intÂ main()
> {
> Â Â Â Â Â usingÂ namespaceÂ std::literals;
> Â Â Â Â Â autoÂ xÂ =Â -0.1+Â 1e-100i;
> Â Â Â Â Â std::coutÂ <<Â std::pow(-0.1+Â 1e-100i,Â 2)Â <<Â ":"Â <<Â xÂ *Â xÂ <<std::endl;
> }
>
>
> ButÂ IÂ amÂ farÂ fromÂ beingÂ aÂ numericsÂ orÂ pythonÂ expert.
>
> Regards
> Peter.
>
> willÂ wrayÂ viaÂ Std-DiscussionÂ wroteÂ onÂ 03.03.21Â 16:29:
>> Confirm;Â somethingÂ fishyÂ here.
>> CuriousÂ ifÂ theÂ unqualifiedÂ 'pow'Â wasÂ aÂ culprit,Â IÂ qualifiedÂ asÂ std::pow
>> andÂ stillÂ confirmÂ theÂ sameÂ badÂ resultÂ onÂ gcc,Â clang,Â iccÂ andÂ msvcÂ latest.
>>
>> TheÂ equivalentÂ CÂ programÂ hasÂ theÂ sameÂ outputÂ inÂ gccÂ andÂ clang

>>
>> #includeÂ "stdio.h"
>> #includeÂ "complex.h"
>> #includeÂ "math.h"
>>
>> intÂ main()Â {
>> Â Â Â Â Â doubleÂ complexÂ xÂ =Â -0.1Â +Â IÂ *Â 1e-100;
>> Â Â Â Â Â doubleÂ complexÂ pÂ =Â cpow(x,Â 2.0);
>> Â Â Â Â Â printf("%g,%g\n",creal(p),cimag(p));
>> }
>>
>> Implies:
>> (1) cut-n-paste code of same numerical precision 'bug' across
>> implementations,Â or
>> (2)Â precisionÂ 'bug'Â inÂ theÂ specificationÂ ofÂ complexÂ pow
>>
>> If 2. then it may be hard to correct it as a defect as it will change
>> existingÂ results?
>>
>> NotÂ sureÂ ifÂ there'sÂ stillÂ aÂ dedicatedÂ numericsÂ SGÂ -
>> SG19Â MLÂ hasÂ someÂ remitÂ forÂ numerics,Â includingÂ automaticÂ differentiation
>> SG14Â alsoÂ doesÂ numerics
>> or,Â thisÂ mayÂ alsoÂ beÂ inÂ theÂ remitÂ ofÂ theÂ newÂ JointÂ CÂ andÂ C++Â StudyÂ Group
>> (thereÂ hasÂ beenÂ recentÂ workÂ onÂ complexÂ inÂ C)
>>
>>
>>
>>
>> On Wed, Mar 3, 2021 at 9:05 AM Bell, Ian H. (Fed) via Std-Discussion
>> <std-discussion_at_[hidden]
>> <mailto:std-discussion_at_[hidden]>>Â wrote:
>>
>> Â Â Â Â TheÂ recentÂ â€œrediscoveryâ€Â ofÂ complexÂ stepÂ derivatives

>>
>> Â Â Â Â hasÂ madeÂ numericalÂ differentiationÂ asÂ accurateÂ asÂ anyÂ other
>> Â Â Â Â evaluationÂ inÂ doubleÂ precisionÂ arithmetic.Â Â ToÂ fullyÂ makeÂ useÂ of
>> Â Â Â Â thisÂ technique,Â allÂ functionsÂ mustÂ acceptÂ eitherÂ complexÂ orÂ double
>> Â Â Â Â arguments.Â InÂ principleÂ thatÂ isÂ noÂ problemÂ forÂ C++.Â InÂ practice,
>> Â Â Â Â seriousÂ problemsÂ occurÂ inÂ someÂ cases.____
>>
>> Â Â Â Â __Â __
>>
>> Â Â Â Â HereÂ firstÂ isÂ aÂ simpleÂ exampleÂ inÂ PythonÂ ofÂ whenÂ thingsÂ goÂ right.
>> Â Â Â Â TheÂ derivativeÂ ofÂ x^2.0Â isÂ 2.0*x,Â soÂ theÂ derivativeÂ ofÂ x^2.0Â at
>> Â Â Â Â x=-0.1Â shouldÂ beÂ dy/dx=-0.2.Â Â InÂ Python,Â noÂ problemÂ toÂ useÂ complex
>> Â Â Â Â stepÂ derivativesÂ toÂ evaluate:____
>>
>> Â Â Â Â __Â __
>>
>> Â Â Â Â hÂ =Â 1e-100____
>>
>> Â Â Â Â zÂ =Â -0.1+1j*h____
>>
>> Â Â Â Â print(pow(z,Â 2.0),Â pow(z,Â 2.0).imag/h,Â (z*z).imag/h)____
>>
>> Â Â Â Â __Â __
>>
>> Â Â Â Â gives____
>>
>> Â Â Â Â __Â __
>>
>> Â Â Â Â (0.010000000000000002-2e-101j)Â -0.2Â -0.2____
>>
>> Â Â Â Â __Â __
>>
>> Â Â Â Â OnÂ theÂ contrary,Â theÂ sameÂ exampleÂ inÂ C++Â ____
>>
>> Â Â Â Â __Â __
>>
>> Â Â Â Â #includeÂ <iostream>____
>>
>> Â Â Â Â #includeÂ <complex>____
>>
>> Â Â Â Â #includeÂ <cmath>____
>>
>> Â Â Â Â __Â __
>>
>> Â Â Â Â intÂ main()____
>>
>> Â Â Â Â {____
>>
>> Â Â Â Â Â Â Â Â Â std::coutÂ <<Â pow(std::complex<double>(-0.1,Â 1e-100),Â 2.0)Â <<
>> Â Â Â Â std::endl;Â ____
>>
>> Â Â Â Â }____
>>
>> Â Â Â Â __Â __
>>
>> Â Â Â Â gives____
>>
>> Â Â Â Â __Â __
>>
>> Â Â Â Â (0.01,-2.44929e-18)____
>>
>> Â Â Â Â __Â __
>>
>> Â Â Â Â __Â __
>>
>> Â Â Â Â IÂ believeÂ theÂ problemÂ hasÂ toÂ doÂ withÂ theÂ handlingÂ ofÂ theÂ branch-cut
>> Â Â Â Â ofÂ theÂ logÂ function.Â Â InÂ anyÂ case,Â thisÂ demonstratesÂ aÂ resultÂ that
>> Â Â Â Â isÂ silentlyÂ inÂ errorÂ byÂ 83Â ordersÂ ofÂ magnitude!Â HadÂ IÂ multipliedÂ the
>> Â Â Â Â complexÂ stepÂ byÂ itselfÂ ratherÂ thanÂ pow(z,2.0),Â IÂ wouldÂ haveÂ obtained
>> Â Â Â Â theÂ correctÂ result.____
>>
>> Â Â Â Â __Â __
>>
>> Â Â Â Â IÂ realizeÂ thatÂ IÂ amÂ probingÂ anÂ uncomfortableÂ partÂ ofÂ theÂ complex
>> Â Â Â Â plane,Â butÂ IÂ wonderÂ ifÂ thisÂ couldÂ beÂ handledÂ moreÂ likeÂ Python,Â to
>> Â Â Â Â minimizeÂ surprisesÂ forÂ complexÂ stepÂ derivativeÂ approaches?____
>>
>> Â Â Â Â __Â __
>>
>> Â Â Â Â Ian____
>>
>> Â Â Â Â __Â __
>>
>> Â Â Â Â --Â Â Â Â Â Std-DiscussionÂ mailingÂ list
>> Â Â Â  Std-Discussion_at_[hidden]
>> <mailto:Std-Discussion_at_[hidden]>

>>
>>
>>
>
>

```--