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

Make std::complex<DualNumber> work #66

Open
dschwen opened this issue Nov 20, 2020 · 7 comments
Open

Make std::complex<DualNumber> work #66

dschwen opened this issue Nov 20, 2020 · 7 comments

Comments

@dschwen
Copy link
Contributor

dschwen commented Nov 20, 2020

We're looking into using the Eigen library to obtain eigen decompositions of matrices of dual numbers. This is of course because LAPACK precludes us from using dual numbers entirely while Eigen is beautifully templated.

I seem to have hit a snag though as there are a bunch of functions used in <complex> that are not overloaded (or specialized) for dual numbers. This results in errors like

/Users/schwd/miniconda3/envs/moose/bin/../include/c++/v1/complex:685:15: error: no matching function for call to 'scalbn'
    _Tp __y = scalbn((__b * __c - __a * __d) / __denom, -__ilogbw);

and

/Users/schwd/miniconda3/envs/moose/bin/../include/c++/v1/complex:676:29: error: no matching function for call to 'fabs'
    _Tp __logbw = logb(fmax(fabs(__c), fabs(__d)));
@dschwen
Copy link
Contributor Author

dschwen commented Nov 20, 2020

Hm, I guess complex numbers are not necessary if we can assume the matices are symmetrical.

@roystgnr
Copy link
Owner

I do hope you've got another way out of this. DualNumber<complex> should be workable in theory, but std::complex<DualNumber> isn't; C++ says that Specializing the template std::complex for any type other than float, double, and long double is unspecified.

In my experience those specializations are often workable in practice, but not always; I must have hit a compiler that agreed with the standard instead of with me at some point, or I wouldn't have remembered the disagreement. To be fully portable you wouldn't be able to just specialize std::complex; you'd have to create MetaPhysicL::complex, as well as versions of all the functions you'd want to act on that.

@roystgnr
Copy link
Owner

Looks like even boost might have run into this problem? They at least try to specialize complex<boost::multiprecision::float128>, but when you can help it they recommend you use boost::multiprecision::complex128 instead, and I'd bet that compatibility issues with the former overloads are why.

@cticenhour
Copy link

I'm running into this issue more generally while converting some MOOSE objects that utilize std::complex into AD objects. I often utilize complex to make field calculations easier in my electromagnetics code. I think I'll be able to find a workaround, but I just wanted to bump this thread so you know that others are interested in any improvements here (even if I don't have the time to implement it myself right now 😢).

@dschwen
Copy link
Contributor Author

dschwen commented Mar 10, 2021

So the answer would be to roll our own moose::complex number type?!

@roystgnr
Copy link
Owner

So the answer would be to roll our own moose::complex number type?!

I absolutely hate this, but: yes, probably. It would be a shim to std::complex for float/double/long double, and to a new MetaPhysicL::complex<T> for MetaPhysicL types, and to boost::multiprecision::complex128 for quad precision builds ...

And it would be incredibly annoying but I fear it would be the only way to guarantee things not breaking with some new compiler years down the road.

We could probably make std::complex<MetaPhysicL::foo> a shim to MetaPhysicL::complex<foo>, so that on compiler+library combinations which support it we'd get additional backwards compatibility with generic codes that explicitly reference std::complex rather than using context-dependent namespace lookup, but I'd want to rely on that as little as possible.

@dschwen
Copy link
Contributor Author

dschwen commented Mar 10, 2021 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants