Optimizing nested functions for quadrature routine - python

I wrote the code below in Python to create a function that integrates func(x+t**(1/2) * z)*... with respect to z, where I want to call the function for some x.
This is part of a bigger code and in order to make the whole program go faster I wondered if there was a way to optimize the way pregau works.
def gauss(func, t):
def gauss(x):
def pregau(z):
arg = x + t ** (1 / 2) * z
return func(arg) * math.exp(-(z**2)/2)
integration = integrate.quad(pregau, -np.inf, np.inf, epsabs=0.001)[0]
return (2 * math.pi) ** (-1/2) * integration
return gauss
I thought about interpolating it on the whole space, but maybe any of you have better ideas to solve this problem?

Related

How do I write a summation series in Python for a 2D function?

I am trying to write a multi-variable function in Python that is also embedded in a summation.
This is the equation:
F(x, t) = sum[ (1/n) * (-1)^(n-1) * sin(pi * x * n) * e^(-n^2*t) ] from n = 1 to A
where A is a defined constant and F(x, t) is a 2 dimensional array.
I had a thought about using a while loop but got no where. Does anyone have any idea of what I can do?

scipy.optimize.minimize two different outputs for the same(?) input

I have a function func(x). I want to know the x for func(x)-7=0. Because there is no exact real answer, I thought minimize would be a good idea.
from scipy.optimize import minimize
def func(x): # testing function which leads to the same behaviour
return (x * 5 + x * (1 - x) * (6-3*x) * 5)
def comp(x): # comparison function which should get zero
return abs(((func(x)) - 7))
x0 = 0.
x_real = minimize(comp, x0) # minimize comparison function to get x
print(x_real.x)
The last print gives me [ 0.7851167]. The following print...
print(comp(x_real.x))
print(comp(0.7851167))
...leads to different outputs:
[ 1.31290960e-08]
6.151420706146382e-09
Can someone explain me this behaviour?
EDIT: I think i understood your question wrong. Rounding the number as you did in the print statements obviously will result in some differences (which are pretty small (around 1e-9)).
To find all x, you should apply some global solution method or start from different intital point to find all local minimas(as seen in the plot).
The equation however has two solutions.
def func(x): # testing function which leads to the same behaviour
return (x * 5 + x * (1 - x) * (6-3*x) * 5)
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-0.1,1,100)
plt.plot(x, func(x)-7)
plt.plot(x, np.zeros(100))
plt.show()
The function:

How to put an integral in a function in python/matplotlib

So pretty much, I am aiming to achieve a function f(x)
My problem is that my function has an integral in it, and I only know how to construct definite integrals, so my question is how does one create an indefinite integral in a function (or there may be some other method I am currently unaware of)
My function is defined as :
(G is gravitational constant, although you can leave G out of your answer for simplicity, I'll add it in my code)
Here is the starting point, but I don't know how to do the integral portion
import numpy as np
def f(x):
rho = 5*(1/(1+((x**2)/(3**2))))
function_result = rho * 4 * np.pi * x**2
return function_result
Please let me know if I need to elaborate on something.
EDIT-----------------------------------------------------
I made some major progress, but I still have one little error.
Pretty much, I did this:
from sympy import *
x = Symbol('x')
rho = p0()*(1/(1+((x**2)/(rc()**2))))* 4 * np.pi * x**2
fooply = integrate(rho,x)
def f(rx):
function_result = fooply.subs({x:rx})
return function_result
Which works fine when I plug in one number for f; however, when I plug in an array (as I need to later), I get the error:
raise SympifyError(a)
sympy.core.sympify.SympifyError: SympifyError: [3, 3, 3, 3, 3]
(Here, I did print(f([3,3,3,3,3]))). Usually, the function returns an array of values. So if I did f([3,2]) it should return [f(3),f(2)]. Yet, for some reason, it doesn't for my function....
Thanks in advance
how about:
from sympy import *
x, p0, rc = symbols('x p0 rc', real=True, positive=True)
rho = p0*(1/(1+((x**2)/(rc))))* 4 * pi * x**2
fooply = integrate(rho,x)/x
rho, fooply
(4*pi*p0*x**2/(1 + x**2/rc),
4*pi*p0*rc*(-sqrt(rc)*atan(x/sqrt(rc)) + x)/x)
fooply = fooply.subs({p0: 2.0, rc: 3.0})
np_fooply = lambdify(x, fooply, 'numpy')
print(np_fooply(np.array([3,3,3,3,3])))
[ 29.81247362 29.81247362 29.81247362 29.81247362 29.81247362]
To plug in an array to a SymPy expression, you need to use lambdify to convert it to a NumPy function (f = lambdify(x, fooply)). Just using def and subs as you have done will not work.
Also, in general, when using symbolic computations, it's better to use sympy.pi instead of np.pi, as the former is symbolic and can simplify. It will automatically be converted to the numeric pi by lambdify.

Manipulating functions in python

I want to be able to use one function in another function, in this case the function nu in the expression for integrand. At the moment this is my code:
from trapezium import trap
import scipy as sp
# mass_enc returns the mass enclosed within a radius R
# nu is the density function
def mass_enc(q, R):
integrand = lambda r: 4 * sp.pi * r**2 * q(r)
return trap(integrand, 0, R, 100)
def nu(a):
return a
print(mass_enc(nu, 10))
However this seems messy - is there a better way to do it?

Solve expression with iterative method in Python

I'm new with Python, and started to work on a Coordinate Conversion program. The problem is that I can't find an iterative method to solve one of the expressions.
Expressions:
N = a / math.sqrt(1 - (e2 * (math.sin(phi))**2))
phi = math.atan((Z / math.sqrt((X**2) + (Y**2))) * ((1-e2) * (N / N + hei)**-1))
lam = math.atan(Y / X)
hei = (math.sqrt((X ** 2) + (Y ** 2))) / math.cos(phi)
Here, a and e2 are constants.
The user is supposed to introduce the values of X, Y and Z and obtain phi, lam and hei. But, given that N is a function that depends of phi, it is necessary to create a loop, making hei = 0 in the second equation as an initial value, in order to procure a first approximation for phi. However, I don't know how to end that cycle when phi has reached a certain value (for instance, when 9 or more of the decimals of phi are equal to the previous value in the loop).
You could break the loop based on the difference between the value of phi in the previous loop and that in the current loop, i.e. if the difference is smaller than 10^(-9).

Categories