Posts: 7
Threads: 1
Joined: Mar 2017
Mar-19-2017, 11:39 PM
(This post was last modified: Mar-19-2017, 11:39 PM by pythonforumrocks.)
I don't have a great understanding of calculus (or python) but I need to find the average value of a curve for a project. I've been using a widget from wolframalpha.com. Can I duplicate that in python?
Here's the widget:
http://www.wolframalpha.com/widgets/view...dcbe645198
Posts: 4,229
Threads: 97
Joined: Sep 2016
The best I could find with a quick Google for the symbolic solving of integrals was sympy ( http://www.scipy-lectures.org/advanced/sympy.html). You could of course do a simulation of the limit (dividing the area under the curve into a bunch of small rectangles, and calculating the total area of the rectangles), but that may not suit your needs.
Posts: 331
Threads: 2
Joined: Feb 2017
sympy has support for both indefinite and definite integrals:
Output: In [1]: from sympy import integrate, Symbol, init_printing
In [2]: init_printing(use_unicode=True)
In [3]: x = Symbol('x')
In [4]: integrate(x**2, x)
Out[4]:
3
x
──
3
In [5]: integrate(x**2, (x, 1, 2))
Out[5]: 7/3
Or you can use numerical integration provided by SciPy.
Posts: 7
Threads: 1
Joined: Mar 2017
I don't see how the range ("from" and "to" on the wolframalpha.com widget) should be specified. Here's my formula:
f(x) = ( a * b ) / ( c * 1.05^x )
from = 1
to = b
http://www.wolframalpha.com/widgets/view...dcbe645198
I will have values for a, b, and c.
Posts: 331
Threads: 2
Joined: Feb 2017
Mar-20-2017, 02:18 PM
(This post was last modified: Mar-20-2017, 02:20 PM by zivoni.)
You can simplify your function as k * 1.05^(-x), where k = a * b / c. ( mathjax support would be handy here)
Lets suppose that k = 5 and you want to integrate over interval [1,5].
You can use scipy's quad() - its arguments are function's definition (as a python function) and lower and upper limit:
Output: In [1]: from scipy import integrate
In [2]: k, a, b = 5, 1, 5
In [3]: integrate.quad(lambda x: k * 1.05**(-x), a, b)
Out[3]: (17.30418300357802, 1.9211502392899616e-13)
output is the result and an estimation of error.
You can use sympy's integrate() , where first argument is a function definition and second is a tuple, with elements being variable you integrate by, lower limit, upper limit. With sympy you can write your function almost "naturally", but you need to specify that x has a special meaning (a symbol). If you are interested only in numerical result, scipy's quad is probably easier to use.
Output: In [4]: from sympy import integrate, Symbol
In [5]: x = Symbol('x')
In [6]: integrate(k * 1.05**(-x), (x, a, b))
Out[6]: 17.3041830035780
And finally, you can use a piece of paper (and a brain) and realize that the primitive function of k * 1.05^(-x) is -k / log(1.05) * 1.05^(-x). After that its just
Output: In [7]: from math import log
In [8]: -k / log(1.05) * ( 1.05**-b - 1.05**-a )
Out[8]: 17.304183003578018
As python is not a domain-specific language for math/symbol manipulation, using python for calculus would require atleast basic understanding of python and basic understanding of a calculus, you likely need to spend some effort and study both a little.
Posts: 7
Threads: 1
Joined: Mar 2017
I'm getting a different output from the wolframalpha.com widget compared to your functions above. With:
k, a, b = 5, 1, 5
and:
k = a * b / c
I get 4.32605 from the widget by using:
f(x) = ( a * b ) / ( c * 1.05^x )
from = 1
to = b
Could you point out my mistake and/or misunderstanding?
Posts: 331
Threads: 2
Joined: Feb 2017
Mar-20-2017, 04:34 PM
(This post was last modified: Mar-20-2017, 05:30 PM by zivoni.)
Hmm, I was little unclear with notation. After first line i just stopped to care about original values of a, b, c - they were used only to compute k and forgotten (with k = a * b / c function k * 1.05^(-x) is same as (a*b)/c * 1.05^(-x) )
And rest was just integration of function k * 1.05^(-x) on interval [a, b], whatever values of k, a, b are. And for integral of 5 * 1.05^(-x) on interval [1, 5] wolfram alpha gives same result (17.3042) - just fill there 5 * 1.05^(-x), from 1, to 5.
Posts: 7
Threads: 1
Joined: Mar 2017
I have to confess I'm a bit lost. What would you say is the simplest python expression of what I've been doing in the Wolfram Alpha widget?
Posts: 331
Threads: 2
Joined: Feb 2017
I think that something like
integrate.quad(lambda x: k * 1.05**(-x), a, b) is probably the simplest way possible - to compute a definite integral you need to have a function to integrate, a lower bound, an upper bound. And you must express that you want to compute the definite integral from these three things. So I am not sure if it even can be significantly simpler ...
Anyway, I can try to rewrite what I think you tried to compute - just "verbatim" rewrite without any changes
from scipy import integrate
a, b, c = 2, 5, 2 # constants
def my_func(x): # "defining" your function
f_x = a * b / ( c * 1.05**x ) # value of f(x)
return f_x
print( integrate.quad(my_func, 1, b) ) # you want to integrate function my_func on interval [1, b] and print result And output of it is:
Output: (17.30418300357802, 1.9211502392899616e-13)
I hope that it helps. And if not, perhaps someone else would volunteer ...
Posts: 7
Threads: 1
Joined: Mar 2017
Well, my goal is to get the same output from a python expression that I get from Wolfram Alpha but I'm getting different output. With:
a, b, c = 2, 5, 2
I get ~ 17.30 from this (a one-liner is better for my application):
integrate.quad(lambda x: (a*b/c) * 1.05**(-x), 1, b)
I get ~ 4.32 from Wolfram Alpha by using these inputs on the page (with a, b, and c replaced with their values above):
f(x) = ( a * b ) / ( c * 1.05^x )
from = 1
to = b
http://www.wolframalpha.com/widgets/view...dcbe645198
Your function seems to be giving me exactly 4x what Wolfram Alpha is giving me. What am I missing?
BTW, I think your code should read the following with 1 as the lower bound instead of a:
integrate.quad(lambda x: k * 1.05**(-x), 1, b)
|