Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SolveNormalizedCubic fix to return proper real root #224

Merged

Conversation

bareya
Copy link
Contributor

@bareya bareya commented Oct 28, 2021

In some cases solveNormalizedCubic can return a real value from principled root that is a complex root. This happens in #86 for example.

In case of discriminant D > 0 there must be one real and two complex roots. Given formula: -q/2 + sqrt(D) might be a negative number. Instead of searching though y0, y1, y2 to find the real root, we can solve it as follows:

T sign = a < T (0) ? T (-1) : T (1);
return sign * std::pow (sign * a, T (1) / x);

@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Oct 28, 2021

CLA Signed

The committers are authorized under a signed CLA.

Copy link
Contributor

@meshula meshula left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for figuring this out. One small suggestion on copysign

if (D > 0)
{
auto real_root = [] (T a, T x) -> T {
T sign = a < T (0) ? T (-1) : T (1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
T sign = a < T (0) ? T (-1) : T (1);
T sign = std::copysign(T(1), a);

Copy link
Contributor Author

@bareya bareya Oct 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion @meshula.

Also, I have a question, I didn't notice but in the declaration of the function here:
https://github.com/AcademySoftwareFoundation/Imath/blob/master/src/Imath/ImathRoots.h#L67
IMATH_HOSTDEVICE is used. Does it mean we can't use std:: features? I guess code has to compile as cuda code too?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the delay, and thank you for the fix! I'm not entirely sure about the complete details of compatibility between cuda and std, but I'm pretty sure simple inline std:: functions are acceptable.

use copy sign

Co-authored-by: Nick Porcino <[email protected]>
Signed-off-by: Piotr Barejko <[email protected]>
@cary-ilm cary-ilm merged commit e361b75 into AcademySoftwareFoundation:master Nov 12, 2021
cary-ilm pushed a commit to cary-ilm/Imath that referenced this pull request Jan 17, 2022
…oundation#224)

* SolveNormalizedCubic fix to return proper real root

Signed-off-by: Piotr Barejko <[email protected]>

* Update src/Imath/ImathRoots.h

use copy sign

Co-authored-by: Nick Porcino <[email protected]>
Signed-off-by: Piotr Barejko <[email protected]>

Co-authored-by: Nick Porcino <[email protected]>
cary-ilm pushed a commit that referenced this pull request Jan 20, 2022
* SolveNormalizedCubic fix to return proper real root

Signed-off-by: Piotr Barejko <[email protected]>

* Update src/Imath/ImathRoots.h

use copy sign

Co-authored-by: Nick Porcino <[email protected]>
Signed-off-by: Piotr Barejko <[email protected]>

Co-authored-by: Nick Porcino <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants