Complex function integration using trapezoidal rule in C++

Viewed 210
#include <complex>  
complex<double> integral(complex<double> (*f)(complex<double> x), complex<double> l, complex<double> u, size_t n) {
   complex<double> step = (u - l) / (double)n;
   complex<double> area(0, 0);
   for (size_t i = 0; i < n; i++) {
      complex<double> inner = l + (i + 0.5) * step;
      area = area + f(inner) / inner * step;
   }
   return area;
}
int main() {
   cout << integral(cos, 0, 2, 100);
   return 0;
}

error

main.cpp:35:13: error: no matching function for call to 'integral'
main.cpp:24:17: note: candidate function not viable: no overload of 'cos' matching 'complex<double> (*)(complex<double>)' for 1st argument

I would like to integrate complex function using trapezoidal method.

The lower and the upper bounds are complex numbers as well.

If I only use double (I replace every complex<double> to double) it is working I am getting the proper solution, but if I use complex<double> I get the previously mentioned error code.

Maybe there are issues in my algorithm, I would appreciate if you could highlights me.

2 Answers

It's because the complex overloads of std::cos take their argument by reference. That makes them incompatible with a function pointer type with the argument by value.

template< class T >
complex<T> cos( const complex<T>& z );

https://en.cppreference.com/w/cpp/numeric/complex/cos

Instead of chasing a moving target (exact parameter types), I would suggest using an abstraction such as std::function<complex<double> (complex<double>)>

integral's first parameter type

complex<double> (*f)(complex<double> x)

is wrong.

The complex form of std::cos takes its parameter by constant reference.

Change your first parameter to this and std::cos will be a match.

complex<double> (*f)(complex<double> const & x)
//                                   ^^^^^^^
Related