Integrating more than one function error in python - python

Lets say i define my function G,
def G(k, P, W):
return k**2*P*W**2
Where P and W are two functions that have independent variables of k and k is a defined number.
I am trying to integrate this from 0 to infinity
I = scipy.integrate.quad(G, 0, np.Inf)
inputting this into my console gives me the error,
G() takes exactly 3 arguments (2 given)
I tried using the arg() command, but it does not seem to change it and code remains stubborn. What am i doing wrong and what am i missing?

If I understand correctly, k is a constant. Then you can write:
k = 10
I = integrate.dblquad(lambda p,w: G(k,p,w), 0, np.Inf, lambda x: 0, lambda x: np.Inf)
Found it in the scipy documentation.
Besides, your integral looks divergent.
For symbolic integrals see sympy.integrate. It is a different library.
import * from sympy
k,P,W = symbols('k P W')
integrate(G(k,P,W),P,W)

Related

How to calculate a sigmoid function without using an exp() function in Python?

I'm working in somewhat of a limited development environment. I'm writing a neural network in Python. I don't have access to numpy and as it is I can't even import the math module. So my options are limited. I need to calculate the sigmoid function, however I'm not sure how the exp() function works under the hood. I understand exponents and that I can use code like:
base = .57
exp = base ** exponent
However I'm not sure what exponent should be? How do functions like numpy.exp() calculate the exponent? This is what I need to replicate.
The exponential function exp(a) is equivalent to e ** a, where e is Euler's number.
>>> e = 2.718281828459045
>>> def exp(a):
... return e ** a
...
>>> import math # accuracy test
>>> [math.exp(i) - exp(i) for i in range(1, 12, 3)]
[0.0, 7.105427357601002e-15, 2.2737367544323206e-13, 1.4551915228366852e-11]
def sigmoid(z):
e = 2.718281828459
return 1.0/(1.0 + e**(-1.0*z))
# This is the formula for sigmoid in pure python
# where z = hypothesis. You have to find the value of hypothesis
you can use ** just fine for your use case it will work with both float and integer input
print(2**3)
8
print(2**0.5 )
1.4142135623730951
if you really need a drop in replacement for numpy.exp()
you can just make a function that behaves like it is written in the docs https://numpy.org/doc/stable/reference/generated/numpy.exp.html
from typing import List
def not_numpy_exp(x:[List[float],float]):
e = 2.718281828459045 # close enough
if type(x) == list:
return [e ** _x for _x in x]
else:
return e**x
how the exp() function works under the hood
If you mean math.exp from built-in module math in this place it does simply
exp(x, /)
Return e raised to the power of x.
where e should be understand as math.e (2.718281828459045). If import math is not allowed you might do
pow(2.718281828459045, x)
instead of exp(x)

Why doesn't use the variable value inside the function in python

Why doesn't the following function take the inner h value that is defined in the function body and gives weird results (arbitrary h value)?
def diff(f): # def not define
h = 0.001
return (lambda x: (f(x+h) - f(x)) / h)
def sin_by_million (x):
return math.sin( 10 ** 6 *x)
>>> diff(sin_by_million) (0)
826.8795405320026
Instead of 1000000?
As per #ThierryLathuille comment, your step h is too big. In real life, you should adapt it based on the function and value at which you want the derivative.
Check out jax instead:
import jax
import jax.numpy as np
def sin_by_million(x):
return np.sin(1e6 * x)
Then:
>>> g = jax.grad(sin_by_million)
... g(0.0)
DeviceArray(1000000., dtype=float32)
The beauty of jax is that it actually compiles your call tree using chain rule, and produces some code (the calls after the first one are much, much faster). It also works on multivariate functions and complex code (with some rules though). And it works wonderfully well & fast on GPUs.

Python -the integral from function multiplication

In python, I have two functions f1(x) and f2(x) returning a number. I would like to calculate a definite integral after their multiplication, i.e., something like:
scipy.integrate.quad(f1*f2, 0, 1)
What is the best way to do it? Is it even possible in python?
I found out just a second ago, that I can use lambda :)
scipy.integrate.quad(lambda x: f1(x)*f2(x), 0, 1)
Anyway, I'm leaving it here. Maybe it will help somebody out.
When I had the same problem, I used this (based on the suggestion above)
from scipy.integrate import quad
def f1(x):
return x
def f2(x):
return x**2
ans, err = quad(lambda x: f1(x)*f2(x), 0, 1)
print("the result is", ans)

Python: How to integrate a math function using only math module?

Just started learning python, and was asked to define a python function that integrate a math function.
We were instructed that the python function must be in the following form: (for example, to calculate the area of y = 2x + 3 between x=1 and x=2 )
integrate( 2 * x + 3, 1, 2 )
(it should return the area below)
and we are not allowed to use/import any libraries other than math (and the built in integration tool is not allowed either).
Any idea how I should go about it? When I wrote the program, I always get x is undefined, but if I define x as a value ( lets say 0 ) then the 2*x+3 part in the parameters is always taken as a value instead of a math equation, so I can't really use it inside?
It would be very helpful, not just to this assignment, but many in the future if I know how a python function can take a math equation as parameter, so thanks alot.
Let's say your integration function looks like this:
def integrate(func, lo_x, hi_x):
#... Stuff to perform the integral, which will need to evaluate
# the passed function for various values of x, like this
y = func(x)
#... more stuff
return value
Then you can call it like this:
value = integrate(lambda x: 2 * x + 3, 1, 2)
edit
However, if the call to the integration function has to look exactly like
integrate( 2 * x + 3, 1, 2 )
then things are a bit trickier. If you know that the function is only going to be called with a polynomial function you could do it by making x an instance of a polynomial class, as suggested by M. Arthur Vaïsse in his answer.
Or, if the integrate( 2 * x + 3, 1, 2 ) comes from a string, eg from a command line argument or a raw_input() call, then you could extract the 2 * x + 3 (or whatever) from the string using standard Python string methods and then build a lambda function from that using exec.
Here come an implementation that fill the needs I think. It allow you to define mathematical function such as 2x+3 and propose an implementation of integral calculation by step as described here [http://en.wikipedia.org/wiki/Darboux_integral]
import math
class PolynomialEquation():
""" Allow to create function that are polynomial """
def __init__(self,coef):
"""
coef : coeficients of the polynome.
An equation initialized with [1,2,3] as parameters is equivalent to:
y = 1 + 2X + 3X²
"""
self.coef = coef
def __call__(self, x):
"""
Make the object callable like a function.
Return the value of the equation for x
"""
return sum( [self.coef[i]*(x**i) for i in range(len(self.coef)) ])
def step_integration(function, start, end, steps=100):
"""
Proceed to a step integration of the function.
The more steps there are, the more the approximation is good.
"""
step_size = (end-start)/steps
values = [start + i*step_size for i in range(1,steps+1)]
return sum([math.fabs(function(value)*step_size) for value in values])
if __name__ == "__main__":
#check that PolynomialEquation.value works properly. Assert make the program crash if the test is False.
#y = 2x+3 -> y = 3+2x -> PolynomialEquation([3,2])
eq = PolynomialEquation([3,2])
assert eq(0) == 3
assert eq(1) == 5
assert eq(2) == 7
#y = 1 + 2X + 3X² -> PolynomialEquation([1,2,3])
eq2 = PolynomialEquation([1,2,3])
assert eq2(0) == 1
assert eq2(1) == 6
assert eq2(2) == 17
print(step_integration(eq, 0, 10))
print(step_integration(math.sin, 0, 10))
EDIT : in truth the implementation is only the upper Darboux integral. The true Darboux integral could be computed if really needed by computing the lower Darboux integral ( replace range(1, steps+1) by range(steps) in step_integration function give you the lower Darboux function. And then increase the step parameter while the difference between the two Darboux function is greater than a small value depending on your precision need (could be 0.001 for example). Thus a 100 step integration is suppose to give you a decent approximation of the integral value.

Find root of a function in a given interval

I am trying to find the root of a function between by [0, pi/2], all algorithms in scipy have this condition : f(a) and f(b) must have opposite signs.
In my case f(0)*f(pi/2) > 0 is there any solution, I precise I don't need solution outside [0, pi/2].
The function:
def dG(thetaf,psi,gamma) :
return 0.35*((cos(psi))**2)*(2*sin(3*thetaf/2+2*gamma)+(1+4*sin(gamma)**2)*sin(thetaf/2)-‌​sin(3*thetaf/2))+(sin(psi)**2)*sin(thetaf/2)
Based on the comments and on #Mike Graham's answer, you can do something that will check where the change of signs are. Given y = dG(x, psi, gamma):
x[y[:-1]*y[1:] < 0]
will return the positions where you had a change of sign. You can an iterative process to find the roots numerically up to the error tolerance that you need:
import numpy as np
from numpy import sin, cos
def find_roots(f, a, b, args=[], errTOL=1e-6):
err = 1.e6
x = np.linspace(a, b, 100)
while True:
y = f(x, *args)
pos = y[:-1]*y[1:] < 0
if not np.any(pos):
print('No roots in this interval')
return roots
err = np.abs(y[pos]).max()
if err <= errTOL:
roots = 0.5*x[:-1][pos] + 0.5*x[1:][pos]
return roots
inf_sup = zip(x[:-1][pos], x[1:][pos])
x = np.hstack([np.linspace(inf, sup, 10) for inf, sup in inf_sup])
There is a root only if, between a and b, there are values with different signs. If this happens there are almost certainly going to be multiple roots. Which one of those do you want to find?
You're going to have to take what you know about f to figure out how to deal with this. If you know there is exactly one root, you can just find the local minimumn. If you know there are two, you can find the minimum and use that's coordinate c to find one of the two roots (one between a and c, the other between c and what used to be called b).
You need to know what you're looking for to be able to find it.

Categories

Resources