Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid embedded `std::complex` when providing `T=std::complex<Q>`?

For a Polynomial equation solver, it would be great to template it to have any type available:

template <class number, int degree>
class PolynomialEquation
{
public:

private:
    array<number, degree+1> myEquation;
    array<complex<number>, degree> equationResult;
};

This allows, for example, doublein ℝ to be used for the input, and the result to be std::complex<double> in ℂ (we know that from degree 2 and over, solution to equation usually fall into ℂ, example: x^2+1 ).

But, the input to the equation could also be a std::complex. In this case, the type of myEquation shall be complex, but equationResult should NOT be a std::complex<complex<T>>, but just a normal complex number of type T.

Questions:

How to make the type of equationResult to be the sub-type of std::complex when the equation is provided with std::complex?

Is there an std::is_floating_point equivalent like std::is_complex_number ?

like image 547
Adrian Maire Avatar asked Jul 28 '16 15:07

Adrian Maire


2 Answers

You may create a traits, something like:

template <typename T>
struct to_complex {
    using type = std::complex<T>;
};

template <typename T>
struct to_complex<std::complex<T>> {
    using type = std::complex<T>;
};

And then

template <class number, int degree>
class PolynomialEquation
{
public:

private:
    array<number, degree+1> myEquation;
    array<typename to_complex<number>::type, degree> equationResult;
};
like image 175
Jarod42 Avatar answered Sep 17 '22 22:09

Jarod42


I don't think there is a trait for checking if the type is a complex number but it should be relatively easy to create one (also the alternative implementation to Jarod's to_complex):

#include <type_traits>
#include <complex>
#include <iostream>

template <class T>
struct is_complex_number: std::false_type { };

template <class T>
struct is_complex_number<std::complex<T>>: std::true_type { };

template <class T>
struct to_complex: std::conditional<is_complex_number<T>::value, T, std::complex<T>> { };

int main() {
   std::cout << is_complex_number<float>::value << std::endl; // output: 0
   std::cout << is_complex_number<std::complex<float>>::value << std::endl; // output: 1
   typename to_complex<float>::type c; // decltype(c) == complex<float>
   typename to_complex<std::complex<float>>::type d; // decltype(d) == complex<float>
}
like image 26
W.F. Avatar answered Sep 20 '22 22:09

W.F.