stan-dev / stanc3

The Stan transpiler (from Stan to C++ and beyond).
BSD 3-Clause "New" or "Revised" License
142 stars 46 forks source link

more complex functions #1162

Closed bob-carpenter closed 2 years ago

bob-carpenter commented 2 years ago

Is your feature request related to a problem? Please describe.

Yes. Not all of the complex functions are exposed through the language. Here's a list of

Describe the solution you'd like

I'd like to see the following functions added with complex signatures. If you only implement some of these functions, please mark them off so we can create a new issue with the remaining ones.

Shorthand:

Plus, wherever a complex value is allowed, its corresponding real should also be supported. The signatures exist for these function for real values, except where noted.

Functions which fail expression tests at the moment:

These should just work for complex values if the templating is rich enough---the definitions are identical to the real cases.

Describe alternatives you've considered

Not really any alternative if we want these complex functions.

Additional context

n/a

WardBrian commented 2 years ago

operator.(CM, complex), operator.(complex, CM)

We don't define operator.* for scalar-matrix ops for the real-valued versions either, this is just what operator* does in those cases. (Note, this is inconsistent with operator./)

Additionally, the assignment operator overloads already exist (The compiler defines operator*= in terms of operator*, so they all implicitly get added)

WardBrian commented 2 years ago

It seems like operator./ when one of the arguments is a complex scalar is failing expression tests and may need some C++ work before exposing. Going through most of the rest of the list, it's a somewhat slow process.

determinant has too strict a requirement at the moment (uses std::is_arithmetic for the prim overload)

inverse fails for a similar reason

WardBrian commented 2 years ago

mdivide_left (aka operator\) fails to compile the expression tests due to templates. mdivide_right (aka operator/) works fine.

svd_U and svd_V both fail to match templates.

cholesky_decompose fails due to a template error in stan/lib/stan_math/stan/math/prim/err/elementwise_check.hpp:210:28: error: no match for call to ‘(const stan::math::check_not_nan(const char*, const char*, const T_y&) [with T_y = Eigen::Matrix<std::complex<double>, -1, -1>]::<lambda(double)>) (std::complex<double>&)’