How to use exp() in integration function? - python

Here is a snippet of my code.
from scipy.integrate import quad
from numpy import exp, log, inf
def f(x):
return log(log(x))/(x*log(x**2))
val, err = quad(f, exp(), exp(2))
val
I know the code is structured correctly but I cannot format the exp() correctly. What am I doing wrong? The function should output 0.069324. Thanks ahead of time for the help!!!
Here is the answer from WolfRamAlpha:

numpy's exp is a function, not a number. You want
exp(1) = e
exp(2) = e**2
or maybe
import numpy as np
np.e
np.e**2
as your integration limits.
That said, I get
from numpy import exp, log
def f(x):
return log(log(x))/(x*log(x**2))
val, err = quad(f, exp(1), exp(2))
val
returning 0.12011325347955035
This is definitely the value of this integral. You can change variables to verify
val,err = quad(lambda x: log(x)/(2*x),1,2)
which gives the same result

Just replace exp() by exp(1) and you are good to go. By the way, once you have figured out the correct function, you can also use one liner lambda functions. Your code is perfectly fine. I thought of just sharing another possible way to implement the same thing.
f = lambda x: np.log(np.log(x))/(x*np.log(x**2))
val, err = quad(f, exp(1), 2*exp(1))

Related

Integrating a function of two variables over an array of values

I'm currently trying to solve this integral using SciPy:
I was first advised to use interpolation, which I tried but cannot figure out for some reason, but would probably be a good approach. I found this post about using np.vectorize and I think it might still work, but I am getting an error. Here is the code that I have written thus far (also note that n and n,eq are not indices, they're just variable names):
import numpy as np
from scipy import integrate
def K(x): #This is a function in the integral.
b = 0.252
return b*(((4/(x**3))+(3/(x**2))+1/x) + (4/(x**3) + 1/(x**2))*np.exp(-x))
def Xntot_integrand(x,z): #Defining the integrand
Xneq_x = (1+np.exp(x))**(-1) #This is the term outside the integral and squared within it.
return Xneq_x(x)**2 * np.exp(K(z) - K(x)) * np.exp(x)
Xntot_integrand = np.vectorize(Xntot_integrand)
def Xntot_integrated(x,z):
return quad(Xntot_integrand, 0, z)
Xntot_integrated=np.vectorize(Xntot_integrated)
T_narrow = np.linspace(1,0.01,100) #Narrow T range from 1 to 0.01 MeV
z_narrow = Q/T_narrow
final_integrated_Xneq = Xntot_integrated(z_narrow)
I am getting the error that I am missing a positional argument when I call Xntot_integrated (which makes sense, I think it is still in the two variables x and z).
So I suppose the issue is stemming from where I use quad() because after it is integrated, x should go away. Any advice? Should I use tabulation/interpolation instead?
You need to be using the args keyword argument of integrate.quad to pass additional inputs to the function, so it would look like this:
def Xntot_integrated(z):
return integrate.quad(Xntot_integrand, 0, z, args=(z,))
Note here x is not an input to the integrated function, only z, the first input to the integrand is the integration variable and any extra information is passed via args=(z,) tuple.
alternatively you can define a wrapper that knows z from context and only takes the integration variable as input:
def Xntot_integrated(z):
def integrand(x):return Xntot_integrand(x,z)
return integrate.quad(integrand, 0, z)
but most API's that take a function typically have a keyword argument to specify those inputs. (threading.Thread comes to mind.)
also your Xneq_x should probably be a function itself since you accidentally use it as such inside your integrand (it is just a value there right now) and you will need to use it outside the integration anyway :)

Creating vector with one unknown using a function

I have a problem that I cannot get my head around although there must be a simple way to do so. Basically, I have this function:
Pr(d) = Pr(d_0) -10*n*lodg(d/d_0)
where we can ignore (for now) the Pr(d) term. Now, I want to pass the follwing dataframe:
d
0 200
1 600
2 800
3 1000
with d_0 constant. I sould actually pass it as an array using df_matrix = df.to_numpy().
What I want is to create a function
import pandas as pd
import numpy as np
from sympy import symbols, solve
from scipy.optimize import fsolve
import math
def recieved_power(pr_d0,d_0, x):
pr_d0 -10*n*math.log(d/d_0)
that will return a vector with the variable n (unknown). It should return:
-3.0102999566398116*n
-7.781512503836435*n
-9.030899869919434*n
-10.0*n
Is that possible. I cannot just multiply by n afterwards because there might be new factors in a later stage of the work.
Thanks for any insight.
I suggest you change
def recieved_power(pr_d0,d_0, x):
pr_d0 -10*n*math.log(d/d_0)
into
def recieved_power(pr_d0,d,d_0):
return lambda n: [ pr_d0 -10*n*math.log(single_d/d_0) for single_d in d]
For example, the following code snippet takes in the parameters pr_d0, d and d0 and returns a function which takes in n and outputs a list of numbers, each of which representing a single pr_d0 -10nmath.log(d/d_0) value
import math
d=[200,600,800,1000]
def recieved_power(pr_d0,d,d_0):
return lambda n: [ pr_d0 -10*n*math.log(single_d/d_0) for single_d in d]
func_list=recieved_power(0,d,d_0=1)
print(func_list(3))

How can I use a calculated value of a function in another function in another Python file?

I have wrote the following code in derivation.py:
def Interpolation(ableitungWinkel,x_values):
z = medfilt(derivation,3)
diff = abs(derivation-z)
new_smootheddata = np.where(diff>3,z,derivation)
x=np.arange(0,len(x_values[:-2]))
f = interp1d(x,new_smootheddata,kind="linear")
xnew = np.arange(0, len(x_values[:-3]),0.01)
ynew = f(xnew)
s=plt.plot(x, z,"o",xnew, ynew, "-")
return s
In my project there is also integration.py. In this Python file I need the values which z calculates in the function def interpolation for this calculation:
def horizontalAcceleration(strideData):
resultsHorizontal = list()
for i in range (len(strideData)):
yAngle = z
xAcceleration = strideData.to_numpy()[i, 4]
yAcceleration = strideData.to_numpy()[i, 5]
a = ((m.cos(m.radians(yAngle)))*yAcceleration)-((m.sin(m.radians(yAngle)))*xAcceleration)
resultsHorizontal.append(a)
resultsHorizontal.insert(0, 0)
return resultsHorizontal
As you can see I have already added z to the function def horizontalAcceleration at the place where it should go.
To use z there, I tried the following: from derivation import z
But that doesn't work. Because then I get the error: ImportError: cannot import name 'z' from 'derivation'
Have anybody an idea how I can solve this problem? Thanks for helping me.
I think that your misunderstanding is because you think a function is like a script that has been run and modified a.global state. That's not what a function is. A function is a series of actions performed on its inputs (ignoring closures for a minute) which returns some results. You can call it many times, but without calling it, it never executes. Once it stops executing all its variables go out of scope.
You can import and call a function though. So you can change the return type of Interpolation to return everything you need somewhere else. E.g.
def Interpolation(...):
...
return {'z': z, 's': s}
Then somewhere you import that function, call it, get back all the data you need, then pass that to your other function.
import Interpolation from derivation
# get z and s in a dict result
result = Interpolation(...)
# pass s as well as the other argument to your other function
horizontalAcceleration(strideData, result['s'])

Python scipy module derivate not working with input from user

When I tried to calculate a derivate from an user it gave me an error, that says that derivate does not take string inputs, but so how Ican achieve this
import scipy.misc import derivate
fx=input()
print(derivative(fx,1.0,dx=1e-8))
The first parameter is func, not str docs. If you want it as input you can use lambda and eval. The input need to be in x**3 + x**2 format
fx = input()
f = lambda x: eval(fx)
print(derivative(f, 1.0, dx=1e-8))
Use below code
from scipy.misc import derivative
def f(x):
return x**2 + x
print(derivative(f,1.0,dx=1e-6))
------------ Updated---------------------
Explanation: - With your code you have tried to pass a string to the function derivative which expects a function instead , here is the doc

ValueError: need more than 3 values to unpack when using optimize.minimize

I'm pretty new to python and I got stuck on this:
I'd like to use scipy.optimize.minimize to maximize a function and I'm having some problem with the extra arguments of the function I defined.
I looked for a solution in tons of answered questions but I can't find anything that solves my problem.
I saw in Structure of inputs to scipy minimize function how to pass extra arguments that one wants to be constant in the minimization of the function and my code seems fine to me from this point of view.
This is my code:
import numpy as np
from scipy.stats import pearsonr
import scipy.optimize as optimize
def min_pears_function(a,exp):
(b,c,d,e)=a
return (1-(pearsonr(b + exp[0] * c + exp[1] * d + exp[2],e)[0]))
a = (log_x,log_y,log_t,log_z) # where log_x, log_y, log_t and log_z are numpy arrays with same length
guess_PF=[0.6,2.0,0.2]
res = optimize.minimize(min_pears_function, guess_PF, args=(a,), options={'xtol': 1e-8, 'disp': True})
When running the code I get the following error:
ValueError: need more than 3 values to unpack
But I can't see what needed argument I'm missing. The function seems to work fine, so I guess the problem is in optimize.minimize call?
Your error occurs here:
def min_pears_function(a,exp):
# XXX: This is your error line
(b,c,d,e)=a
return (1-(pearsonr(b + exp[0] * c + exp[1] * d + exp[2],e)[0]))
This is because:
the initial value you pass to optimize.minimize is guessPF which has just three values ([0.6,2.0,0.2]).
this initial value is passed to min_pears_function as the variable a.
Did you mean for it to be passed as exp? Is it exp you wish to solve for? In that case, redefine the signature as:
def min_pears_function(exp, a):
...

Categories

Resources