C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::cbrt(std::complex)

From: Jason C <jason.cipriani_at_[hidden]>
Date: Tue, 25 Oct 2022 15:43:28 -0400
Hi Sebastian,

I just replied to Brian Bi elsewhere in this thread at the same time you
wrote that, and I think the reply applies here too.

What about just having std::cbrt(z) return whatever pow(z, 1/3) returns?

The idea is, just as sqrt() arbitrarily returns the positive root, cbrt()
can return whatever root as well. And then, just as it's trivial to get the
*other* root given sqrt()'s result (multiply by -1), it's also relatively
straightforward to get the other two roots given cbrt()'s result (rotate
+/- 120 deg in complex plane; as illustrated in de Moivre's formula). It
doesn't *really* matter which root is returned.

And then you'd get consistency with pow(), which is good.

Does that seem reasonable?

Jason

On Tue, Oct 25, 2022 at 3:29 PM Sebastian Wittmeier via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Hi Jason,
>
> ordering the roots per se is probably not the problem.
>
> But getting the root at the expected position is:
>
>
>
> If the first solution is identical to x=exp(z^(1/3)), i.e. -pi/3 < arg(z)
> <= pi/3
>
> then the next roots could continue counter-clockwise.
>
>
>
> Compared to the real function:
>
> The cbrt(positive double) would be always the first of three roots of this
> complex function.
>
> The cbrt(negative double) would be always the second of three roots
> defined this way.
>
> The cbrt(negative double) when presented to the function as (negative
> double - epsilon*i)
>
> would be always the third of three roots.
>
>
>
>
>
> So there are 6 possibilities:
>
> 1) define cbrt(complex) not at all
>
> 2) define cbrt(complex) as exp(z^(1/3))
>
> 3) define cbrt(complex) as the root with the largest real magnitude
>
> That is the same result as cbrt(double)
>
> 4a) define two functions cbrt_principal (2) and cbrt_maxreal (3)
>
> safer solution
>
> 4b) use a second parametercbrt(double, tag)
>
> with tag=complex::principal_root or complex::maxreal (type, enum, ...)
>
> 5) return a list of all three roots
>
> caller possibly would have to sort (see above, where the position of
> maxreal could be any of the three)
>
> 6) return the nth root by provided index
>
> could lead to several repeated calls to function, which is wasteful,
> especially if caller has to sort the results afterwards, when looking for
> (3)
>
>
> I think 4) is the nicest alternative of the ones presented.
>
> Some math / numerically oriented programming languages provide 5), most
> (all?) others provide 2), some (Julia) have the same discussion and stay
> for the moment at 1).
>
>
>
> Best,
>
> Sebastian
>
>
>
> -----Ursprüngliche Nachricht-----
> *Von:* Jason C via Std-Proposals <std-proposals_at_[hidden]>
> *Gesendet:* Di 25.10.2022 18:41
> *Betreff:* Re: [std-proposals] std::cbrt(std::complex)
> *An:* Dejan Milosavljevic <dmilos_at_[hidden]>;
> *CC:* Jason C <jason.cipriani_at_[hidden]>; std-proposals_at_[hidden];
> On Tue, Oct 25, 2022 at 12:30 PM Jason C <jason.cipriani_at_[hidden]> wrote:
>
> Perhaps
>
> template <typename T>
> std::tuple<std::complex<T>,std::complex<T>,std::complex<T> > cbrt
> (std::complex<T> const &c)
>
>
> Although... this then implies that the roots are ordered, and I'm pretty
> sure there's no predictable and consistent way to ensure some order of the
> returned roots given that there's no solid definition of ordering for
> complex number combined with realistic fp precision errors.
>
> I'm starting to think maybe my idea wasn't such a good one after all and
> this is probably too complicated to make its way into std; users would be
> better off choosing other implementations that meet their specific needs,
> probably.
>
> Jason
>
>
>
>
>
>
> On Tue, Oct 25, 2022 at 11:48 AM Dejan Milosavljevic <dmilos_at_[hidden]>
> wrote:
>
> Cubic root have three solutions.
> *What is the rule to uniquely pick the first one?*
> Rest of them we can have by multiply with cbrt( {+1,0} );
>
> My proposal for complex cbrt:
> template< typename T/*number like*/>
> std::complex<T> cbrt( std::complex<T> const& c, int index =0 /* which
> root to use is defined by ( index % 3) 0,1 or 2 */ );
>
> This might be too complex.
> Any idea to make it simple?
>
> On Tue, Oct 25, 2022 at 5:01 PM Jason C via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
> <complex> is conspicuously missing cbrt().
>
> If I put together a proposal to add std::cbrt(std::complex) to <complex>,
> would there be any interest?
>
> Any thoughts?
>
> Jason
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2022-10-25 19:43:57