Different results when computing integral analytically/with scipy VS approximating integral
Question:
I’m trying to calculate the integral of a variant of the Hill Equation shown here.
When I try implementing this with the integrate function in SciPy, I get the following:
from scipy import integrate
Top = 0.9015038230670139
Bottom = 0.5972679490151096
ic50 = 17561.998143066336
Coef = -1.245569789770613
def Hill_formula(X):
return Bottom + (Top - Bottom)/(1 + ((10**np.log10(ic50))/10**X)**Coef)
integrate.quad(Hill_formula, 0.001, 40.0)
with the result coming out to (25.18116866489653, 1.3873362345430754e-08)
However, looking at the graph of this equation with 100 evenly spaced points from 0.001 to 40.0, it clearly looks nothing close to the given answer of ~25: (EDIT: It actually does look right on hindsight because I misread the y-axis of the plot. Still would appreciate help on why this discrepancy exists though)
Checking with an approximation method for the area under the curve gives a similar result:
from scipy.integrate import simpson
points = np.linspace(0.001, 40.0, num=100)
curve_results = []
for val in points:
curve_results.append(Hill_formula(val))
np.abs(simpson(points, curve_results))
resulting in 1.2913519756923537. Is there a reason why this discrepancy exists?
I tried calculating the analytical solution of the integral and using that resulting equation to directly obtain the area under the curve between the bounds, but ran into that same strange ~25 answer.
Answers:
From the documentation of scipy.simpson
:
scipy.integrate.simpson(y, x=None, dx=1.0, axis=-1, even='avg')
Integrate y(x) using samples along the given axis and the composite
Simpson's rule. If x is None, spacing of dx is assumed.
If there are an even number of samples, N, then there are an odd
number of intervals (N-1), but Simpson's rule requires an even number
of intervals. The parameter 'even' controls how this is handled.
Parameters
----------
y : array_like
Array to be integrated.
x : array_like, optional
If given, the points at which `y` is sampled.
...
That means that you’ve probably meant to write simpson(curve_results, points)
instead of np.abs(simpson(points, curve_results))
. That results in 25.18116860801739
, which has the same first 9 digits as the one you’ve obtained and the the analytical result evaluating to 25.181168664896531...
.
I’m trying to calculate the integral of a variant of the Hill Equation shown here.
When I try implementing this with the integrate function in SciPy, I get the following:
from scipy import integrate
Top = 0.9015038230670139
Bottom = 0.5972679490151096
ic50 = 17561.998143066336
Coef = -1.245569789770613
def Hill_formula(X):
return Bottom + (Top - Bottom)/(1 + ((10**np.log10(ic50))/10**X)**Coef)
integrate.quad(Hill_formula, 0.001, 40.0)
with the result coming out to (25.18116866489653, 1.3873362345430754e-08)
However, looking at the graph of this equation with 100 evenly spaced points from 0.001 to 40.0, it clearly looks nothing close to the given answer of ~25: (EDIT: It actually does look right on hindsight because I misread the y-axis of the plot. Still would appreciate help on why this discrepancy exists though)
Checking with an approximation method for the area under the curve gives a similar result:
from scipy.integrate import simpson
points = np.linspace(0.001, 40.0, num=100)
curve_results = []
for val in points:
curve_results.append(Hill_formula(val))
np.abs(simpson(points, curve_results))
resulting in 1.2913519756923537. Is there a reason why this discrepancy exists?
I tried calculating the analytical solution of the integral and using that resulting equation to directly obtain the area under the curve between the bounds, but ran into that same strange ~25 answer.
From the documentation of scipy.simpson
:
scipy.integrate.simpson(y, x=None, dx=1.0, axis=-1, even='avg')
Integrate y(x) using samples along the given axis and the composite
Simpson's rule. If x is None, spacing of dx is assumed.
If there are an even number of samples, N, then there are an odd
number of intervals (N-1), but Simpson's rule requires an even number
of intervals. The parameter 'even' controls how this is handled.
Parameters
----------
y : array_like
Array to be integrated.
x : array_like, optional
If given, the points at which `y` is sampled.
...
That means that you’ve probably meant to write simpson(curve_results, points)
instead of np.abs(simpson(points, curve_results))
. That results in 25.18116860801739
, which has the same first 9 digits as the one you’ve obtained and the the analytical result evaluating to 25.181168664896531...
.