Date: Tue, 25 Oct 2022 15:57:49 -0400

I feel that you didn't really address the point I raised.

If we had std::cbrt(z) for complex arguments alone, it would make sense to

define it as std::pow(z, 1.0/3.0). But the simultaneous presence of that

overload *and* the one for reals, such that the two do not agree when

restricted to the real line, that would likely cause great confusion to

programmers.

Another way of saying it is that there's a general design principle that if

you're going to have multiple overloads of a function, you shouldn't need

to know which one is going to get called in order to know that it's going

to do what you want. The proposal to add std::cbrt(std::complex<T> z) with

the semantics of std::pow(z, 1.0/3.0) violates that principle.

Sebastian's point (4a) would avoid this problem.

On Tue, Oct 25, 2022 at 3:44 PM Jason C via Std-Proposals <

std-proposals_at_[hidden]> wrote:

> 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

>>

> --

> Std-Proposals mailing list

> Std-Proposals_at_[hidden]

> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

>

If we had std::cbrt(z) for complex arguments alone, it would make sense to

define it as std::pow(z, 1.0/3.0). But the simultaneous presence of that

overload *and* the one for reals, such that the two do not agree when

restricted to the real line, that would likely cause great confusion to

programmers.

Another way of saying it is that there's a general design principle that if

you're going to have multiple overloads of a function, you shouldn't need

to know which one is going to get called in order to know that it's going

to do what you want. The proposal to add std::cbrt(std::complex<T> z) with

the semantics of std::pow(z, 1.0/3.0) violates that principle.

Sebastian's point (4a) would avoid this problem.

On Tue, Oct 25, 2022 at 3:44 PM Jason C via Std-Proposals <

std-proposals_at_[hidden]> wrote:

> 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

>>

> --

> Std-Proposals mailing list

> Std-Proposals_at_[hidden]

> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

>

-- *Brian Bi*

Received on 2022-10-25 19:58:03