I am trying to use scipy's integrate.quad and it isn't working for my function.
import numpy as np
from scipy.integrate import quad
def cos_func (x):
return np.cos(np.power(x, 3) + 1)
result_quad = quad(cos_func, 0, 10)[0]
print(result_quad)
I have tried with just x and x^2 in the cos function and both work fine, it's only with x^3, I have also tried using x**3
instead of np.power(x, 3)
and that didn't change anything. Any help in fixing and explaining why it doesn't work would be appreciated.
The x3 in cos(x3+1) will cause the cosine function to oscillate very fast near x=10. You would need a lot of nodes to capture all those oscillations. One way of circumventing that would be to split the integral range for x into [0,1] and [1,10] and make the substitution x=u1/3 to do the second one. (The substitution would be ill-behaved at x=0).
import numpy as np
from scipy.integrate import quad
def cos_func (x):
return np.cos(np.power(x, 3) + 1)
def ucos_func (u):
return np.cos(u + 1) / ( 3 * u ** ( 2.0 / 3.0 ) )
result_quad = quad(cos_func, 0, 1)[0] + quad( ucos_func, 1, 1000.0 )[0]
print(result_quad)
Output (I hope it's right!):
0.0451983043279886
Trying a home-grown version for the original integral (sorry, in c++!):
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
double integrate( double a, double b, int n, double f( double ) );
int main()
{
auto f = []( double x ){ return cos( x * x * x + 1 ); };
double a = 0, b = 10;
#define SP << setw( 15 ) <<
cout SP "intervals" SP "estimate" << '\n';
for ( int n = 10; n <= 1000000; n *= 10 )
{
double I = integrate( a, b, n, f );
cout SP n SP I << '\n';
}
}
double integrate( double a, double b, int n, double f( double ) )
{
double dx = ( b - a ) / n;
double sum = 0.5 * ( f( a ) + f( b ) );
for ( int k = 1; k < n; k++ ) sum += f( a + k * dx );
return sum * dx;
}
Output with number of intervals:
intervals estimate
10 -3.00969
100 0.559173
1000 0.0424572
10000 0.0451753
100000 0.0451981
1000000 0.0451983