Reputation: 1827
I'm trying to plot the integral of this normal distribution for values greater than x defined as
where
defining both functions in python
import scipy.integrate as integrate
import numpy as np
def gaussian(x, mu, sig):
norm = 1/np.sqrt(2*np.pi*sig*sig)
return norm * np.exp(-np.power(x - mu, 2.) / (2. * sig*sig))
def gaussianGreater(x, mu, sig):
Integrand = lambda x: gaussian(x, mu, sig)
return integrate.quad(Integrand,-np.Inf, x)[0]
My problem now lies in the integration bounds of my gaussianGreater
function while it is being evaluated through the distribution function. When evaluating, this occurs.
y = gaussianGreater(subdist_1, mu_1, sig_1 )
xd = np.argsort(subdist_1)
fig = plt.figure(figsize=(8,6))
ax = fig.add_subplot(111)
ax.plot(subdist_1[xd] ,y[xd] )
ValueError: The truth value of an array with more than one element
is ambiguous. Use a.any() or a.all()
I tried changing the upper bounds to what the error gave me, but that would return the error 'float' object has no attribute '__getitem__'
Applying a for loop does not work either
[gaussianGreater(x, mu_1, sig_1 ) for x in subdist_1]
TypeError: only integer arrays with one element can be converted to an index
How do I fix this problem?
Upvotes: 1
Views: 1427
Reputation:
You can directly use scipy.stats.norm's survival function for 1 - F(x):
import scipy.stats as ss
x = np.linspace(-3, 3, 100)
y = ss.norm.sf(x) # you can pass its mean and std. dev. as well
plt.plot(x, y)
Upvotes: 1
Reputation: 621
What you've defined will work only when x
is a single float
. If what you want is to be able to pass a numpy array, say np.array([0.2, 0.3])
and get [N(>0.2), N(>0.3)], then you can use the function as you've already defined and just call the vectorize
method. So if a
was the numpy array you were using, a.vectorize(gaussianGreater)
would get you an array with gaussianGreater
applied to each element. You could define another function, vectorGausssianGreater
that takes an array and just returns the result of that vectorize call on it. If what you really want is a single function that can take an array value, you could define something like the following:
def gaussian_greater(values, mean, standard_deviation):
def greater_float(upper_bound):
integrand = lambda y: gaussian(y, mean, standard_deviation)
return integrate.quad(integrand, -np.inf, upper_bound)[0]
return values.vectorize(greater)
Upvotes: 1