Computing Riemann-Liouville Integral using Sympy - python

New to calculus and not sure where this goes...
I'm trying to compute the Riemann-Liouville interpretation of the integral in Python using sympy. However the resulting integral when running my code between 0 and T contains T as a variable, which I do not want. What should I do to fix this?
Code:
def integral(f, order):
gamma_recip = 1/gamma(order)
T = sympy.Symbol('T')
r = sympy.Symbol('r')
eq = (T-r) ** order - 1
function_eq = eq * f(r)
integral = sympy.integrate(function_eq, (r, 0, T))
return integral
Equation:
Sample call as requested:
-0.333333333333333*T**3 + 0.0833333333333333*T**4.0
Function and order used:
def f(x):
return x**2
print(integral(f, 1.0))
Expected result:
r**3/3

Two issues:
you are using "T" as the integral limit so you will end up with that in the result; if you want "r" in the result, swap the use of T and r in your function
you didn't put parentheses around the order - 1 in your definition of eq; if you do you will (with your current code) get the expected T**3/3

Related

how can write this formula in python?

how can i write a function that takes 2 integer parameters, a and b.
Inside the function I need calculate the value of x using the formula below (where the term 2a indicates that 2 is multiplied by a).
I'm quite lost with doing this can someone please give me a hint on how to start this code in python?
You can use the below method to achieve your goal.
# remember to import math
x = lambda a, b: (math.sqrt(b**2 - 1) + b)/(2 * a)
Now you can use this function:
x(5, 10) # gives 1.99498743710662 (roughly)
Here is how:
def x(a, b):
return (b+(b**2-1)**0.5)/(2*a)
In python, we use ** for power symbols.

Obtaining coefficients of complex expressions in sympy

I have a relatively simple complex sympy expression which one can easily read the coefficients off of the variables. However coeff function does not appear to be working correctly
import sympy as sp
a,b = sp.symbols("a, b")
expr = 2640.0*a - 4.5*(1 + 1j)*(264.0*a + 264.0*b) - 4.5*(+1 - 1j)*(264.0*a + 264.0*b)
print(expr.coeff(a))
> 2640.00000000000
print(sp.simplify(expr))
> 264.0*a - 2376.0*b
I would expect the output of expr.coeff(a) to return 264.0 but it clearly isnt? Any help is appreciated.
coeff gives coefficients of the expression at the top level. If you use expand before looking for the coefficient then you will get the mathematical (not expression-dependent-literal) coefficient. If you know the expression is linear in the symbol of interest, you could also differentiate once:
>>> expr.diff(a)
264.000000000000
>>> expr.expand().coeff(a)
264.000000000000
Poly automatically expands expressions and allows queries for monomials, too:
>>> Poly(expr).coeff_monomial(a)
264.000000000000
Your first expression has 2640.0 as the coefficient of a. As you can see, the coefficient becomes zero only after simplifying it. Indeed, if you print the coefficient after simplifying the expression, you get 264.0
import sympy as sp
a,b = sp.symbols("a, b")
expr = 2640.0*a - 4.5*(1 + 1j)*(264.0*a + 264.0*b) - 4.5*(+1 - 1j)*(264.0*a + 264.0*b)
print(expr.coeff(a))
# 2640.00000000000
print(sp.simplify(expr))
# 264.0*a - 2376.0*b
print(sp.simplify(expr).coeff(a)) # <--- Simplified expression
# 264.000000000000

Take the Sigma of a factorial with unknown variable (using sympy?)

Good day,
I am trying to write a function for the following equation:
Where B and N are given and I am solving for A.
I was reading up and it seemed like sympy was the way to go so I started to declare the known variables, but when it came to the sigma notation with the factorial, I had no idea of how to approach it since A is an unknown.
Here is what I came up with:
from sympy import Eq, var, solve
from math import *
A = var('A')
channels = raw_input("Enter the number of channels: ")
#GOS = raw_input("Enter GOS: ")
Sigma = A
for i in range(0,channels+1):
Sigma += (A**i / factorial(i))
# equation = Eq((A**channels / factorial(channels)) / Sigma)
# print solve(equation)
which gives me the error TypeError: cannot concatenate 'str' and 'int' objects
This makes sense to me, but my lack of knowledge with sympy makes me unable to figure out how to fix it.
EDIT: Looking around a bit more, I edited my code to this:
from sympy import *
A = symbols('A')
channels = raw_input("Enter the number of channels: ")
GOS = raw_input("Enter GOS: ")
Sigma = summation(A**i / factorial(i), (i, 0,channels))
print Sigma
# equation = Eq((A**channels / factorial(channels)) / Sigma)
Now I get NameError: name 'i' is not defined
Thanks in advance.
First of all, the error ( name 'i' not defined) is because you havent defined it. so you need to give an initial value for i.
secondly, I have tried to make your program run. got an error free solution with this code:
from sympy import *
A = symbols('A')
channels = raw_input("Enter the number of channels: ")
GOS = raw_input("Enter GOS: ")
# note that I convert the string 'channel' to an int
# convert to float if channel could also be a floating number
channels = int(channels)
Sigma = A
for i in range(0,channels+1):
Sigma += (A**i / factorial(i))
print Sigma
The result,
inputs: channels = 3, GOS = 1
output: A**3/6 + A**2/2 + 2*A + 1
EDIT: Out of interest I started looking further into your problem (also because I could realize this question would not stop just by a datatype issue).
The Solve function has 2 inputs, the equation and the symbol to calculate.
it solves the equation == 0. so the variable B has to be subtracted from the equation. (I supposed the input GOS is the B variable in the function)
equation = (A**channels / factorial(channels)) / Sigma
print(solve(equation-int(GOS), A))
running the code with the lines above (add them under the code) gave these outputs:
A**3/6 + A**2/2 + 2*A + 1
[-2 - sqrt(2), -2 + sqrt(2)]
I must notice that if the GOS does not intersect the function it gives large results with additional parameter I (capital i, might indicate imaginary i).
I hoped this helped solving your problem.
To describe a similar sum as at the top of the page, when I use the asmeurer's recommendation summation, I get the error -TypeError: 'Symbol' object is not subscriptable." What could be the possible cause of this error? I imported the libraries below. There is a continuation of the code, but I did not add it to avoid confusion.
import sympy as sympy
from sympy import *
from sympy import summation, symbols
class FQ():
def integrate(self):
for k in range(1, self.Nt):
i = symbols('i', integer=True)
self.Sigma = summation(self.u[i+1][j], (i, 0, k - 1))
#second attempt
def integrate(self, alpha, Nt, Nx, L):
for k in range(1, self.Nt):
for j in range(1, self.Nx-1):
#define sum
for i in range(1, self.Nt):
Sigma = summation(u[i+1][j], (i, 0, k-1))
You can also perform the summation in SymPy using the summation function
i = symbols('i')
summation(A**i/factorial(i), (i, 0, N)
Another note: you are starting with Sigma = A, meaning your final result is A + ΣA^i/i! instead of just ΣA^i/i! (you can see in the output from #Petrus1904's answer there is a 2*A instead of A). If you want to use a loop to compute a summation you should initialize the variable to 0.

How can I use sympy to find the error in approximation of a definite integral?

Our assignment is to use sympy to evaluate the exact definite integral of a function and then compare it with the approximation of the definite integral obtained from another python function we wrote. With simple polynomial functions my code works fine, but with a complicated sine function it keeps either breaking or returning nan.
from numpy import *
def simpson(f,a,b,n):
if n<=0 or n%2!=0:
print('Error: the number of subintervals must be a positive even number')
return float('NaN')
h = float(b - a) / float(n)
x = arange(a,b+h,h)
fx = f(x)
fx[1:n:2] *= 4.0
fx[2:n:2] *= 2.0
return (h/3.)*sum(fx)
this is in one file (simpandtrap) and gives the approximation for the definite integral of f from a to b using a simpson's rule approximation with n subintervals
from pylab import *
def s(x):
return x*sin(3./(x+(x==0)))
This is the function giving me trouble, in a file called assignment8functions
import assignment8functions as a
import SimpAndTrap as st
import sympy as sp
x = sp.symbols('x')
Exact_int_q = sp.integrate(a.q(x),(x,0,2)).evalf(25)
Exact_int_s = sp.integrate(x*sp.sin(3./(x)),(x,0,2)).evalf(25)
q(x) is another function we're supposed to use that everything works fine for - it's just a polynomial. When I try to do the integration the same way it breaks, so I had to put the function for s(x) directly into the call instead of importing the one from the other file
n = a.array([10,100,1000,10000,10000,1000000])
s_error_simp_array = a.zeros(6)
for i in a.arange(6):
s_error_simp_array[i] = abs(Exact_int_s - st.simpson(a.s,0,2,n[i])
here I try to find the error in the approximation. the problem is first of all that Exact_int_s is apparently -4.5*Si(zoo) + 8.16827746848576, and I have no idea what that's supposed to mean, and also that the simpson function always returns nan.
I know it's a lot of words and code, but does anybody know what's wrong?
To avoid the answer -4.5*Si(zoo)+ 8.--- just start the integration at a small positive number, e.g.:
x = sp.Symbol('x')
print sp.integrate( x * sin(3./x), (x, 0.000001, 2) )
and you'll get an answer like 1.0996940...
You can justify this because |s(x)| <= x for small x, so the interval [0, epsilon] can't contribute that much.
Btw - your simpson implemention seems to check out.

How can I create functions that handle polynomials?

I have these problems about polynomials and I've spent about 4 hours on this, but I just can't get it. I'm new to Python and programming and I've tried working it out on paper, but I just don't know.
Write and test a Python function negate(p) that negates the polynomial represented by the list of its coeffeicients p and returns a new polynomial (represented as a list). In other words, write a function that makes the list of numbers negative.
Write a Python function eval_polynomial(p, x) that returns the value of P(x), where P is the polynomial represented by the list of its coefficients p. For example, eval_polynomial([1, 0, 3], 2) should return 1*2^2 + 0*2 + 3 = 7. Use a single while loop.
Write and test a function multiply_by_one_term(p, a, k) that multiplies a given polynomial p, represented by a list of coefficients, by ax^k and returns the product as a new list.
I would really appreciate it if someone could help me.
I'd recommend using numpy.poly1d and numpy.polymul, where the coefficients are a0*x2 + a1*x + a2.
For example, to represent 3*x**2 + 2*x + 1:
p1 = numpy.poly1d([3,2,1])
And with the resulting poly1d object you can operate using *, / and so on...:
print(p1*p1)
# 4 3 2
#9 x + 12 x + 10 x + 4 x + 1
If you want to build your own functions, assuming that p contains the coefficients in order: a0 + a1*x + a2*x**2 + ...:
def eval_polynomial(p,x):
return sum((a*x**i for i,a in enumerate(p)))
def multiply_by_one_term(p, a, k):
return [0]*k + [a*i for i in p]
Note
My evaluate function uses exponentials, which can be avoided with Horner's rule, as posted in another answer, which is available in Numpy's polyval function
Please use Horner's Method instead!
For polynomials, you should consider Horner's Method. Its main feature is that computing a polynomial of order N requires only N multiplies and N additions -- no exponentials:
def eval_polynomial(P, x):
'''
Compute polynomial P(x) where P is a vector of coefficients, highest
order coefficient at P[0]. Uses Horner's Method.
'''
result = 0
for coeff in P:
result = x * result + coeff
return result
>>> eval_poly([1, 0, 3], 2)
7
You can work through it by hand, or follow the link to see how it works.

Categories