Integration in python containing some parameter - python

I want to perform integration of an equation with one variable and few constants in the form of symblos namely, A,k,p whose values I have planned to enter after integration. Integrating equation with only one variable but with no other symbol(containing some constant value) is simple and direct, but for the case in which symbols are present, integration using quad from scipy.integrate gives an error. Actually quad() requires the values of all symbols to be pre-defined. I want a solution where I don't have to enter the values for symbols beforehand but take an input and substitue them afterwards.
To make the problem even more clear,
I want to integrate a wave equation
A * sin(kx + wt) , where A is amplitude, w is angular velocity, t is time and x is position (x is only variable )
quad() requires to define the values for A, k and p before integrating but what I want to do is first integrate A * sin(kx + wt) and then substitue the values for A, k and p in the result by taking user input
.
Please suggest a method to do so :)

We can use sympy library for integrating a function without assigning values for its symbols(having some constant real number as its value) (A,k,p and s).
Example code from one of my projects:
from sympy import *
A = symbol('A')
k = symbol('k')
p = symbol('p')
x = symbol('x')
s = symbol('s')
f = integrate(exp(-1*s*x)*A*sin(k*x+p),(x,0,oo))
f = f.subs(A,50)
print str(f)
(x,0,oo) means integrate wrt x from zero (0) to infinty(oo)
What the code requires to be done is, first define constants A, k, p and s as well as the variable x as symbols and then use integrate() to integrate the expression.
integrate() returns the integrated expression and now, f.subs(symbol,value) is used to substitue the values of symbols.
in f.subs(symbol,value) , f is the variable containing the integrated expression, symbol is the symbol defined earlier(like A,k,p) and value is the constant value for that symbol.
This method also helps to get definite integration(from x=a to x=b) of equations. What one has to do is substitute the value of x with b and store it in some variable m using m = f.subs(x,b) and then use n = f.subs(x,a) to substitute the value of x with a and store it in some variable n. Now, substract m and n using m - n to get the definite integral of the expression
There is one more possibe solution to the question.
What can be done is define a function which takes user inputs for A, k and p and then use quad() to integrate the expression, this will wipe out the need to first integrate the expression and then take user input to substitue the values of symbolic constants

It appears you are not defining the variable "A", try doing
A=15
Or anything like that, just make sure you define A before calling it.

Related

Sympy not properly displaying conjugate of square root of real

I keep getting expressions like this image, despite declaring these symbols as reals.
The code to reproduce is:
import sympy as sp
delta = sp.Symbol('delta', real=True)
f = sp.sqrt(1/delta)
prod = sp.conjugate(f)*f
prod.subs(delta,delta)
I expected to get 1/delta
Also trying simplify() does not work either.
According to the official SymPy Docs for conjugate, it looks like the function is supposed to return the complex conjugate for its input. In other words, it takes the complex part of the number and flips the sign.
In your example, you are taking the square root of a variable. If delta = -1, then the resulting conjugate could be unreal and thus different than if delta was any other integer. Thus, SymPy wraps the result in a conjugate object.
If you want to tell Sympy that your variable delta is positive (and thus f must be real), then you should define it as delta = sp.Symbol('delta', real=True, positive=True).

How to solve equations in python

I try to write a script that simulates a resistor. It takes 2 arguments for example P and R and it should calculate all missing values of this resistor.
The problem is that I don't want to write every single possible equation for every value. This means I want to write something like (U=RxI, R=U/R, I=U/R , P=UxI) and the script should then complete all equation with the given values for every equation.
For example, something like this:
in R=10
in I=5
out U=R*I
out P=I**2 * R
You can use https://pypi.org/project/Equation/ Packages.
Example
>>> from Equation import Expression
>>> fn = Expression("sin(x+y^2)",["y","x"])
>>> fn
sin((x + (y ^ (2+0j))))
>>> print fn
\sin\left(\left(x + y^{(2+0j)}\right)\right)
>>> fn(3,4)
(0.42016703682664092+0j)
Sympy
Second: https://github.com/sympy/sympy/wiki
Arbitrary precision integers, rationals and floats, as well as symbolic expressions
Simplification (e.g. ( abb + 2bab ) → (3ab^2)), expansion (e.g. ((a+b)^2) → (a^2 + 2ab + b^2)), and other methods of rewriting expressions
Functions (exp, log, sin, ...)
Complex numbers (like exp(Ix).expand(complex=True) → cos(x)+Isin(x))
Taylor (Laurent) series and limits
Differentiation and integration
In vanilla python, there is no solution as general as the one you are looking for.
The typical solution would be to write an algorithm for every option (only given U, only given R) and then logically select which option to execute.
You may also want to consider using a module like SymPy, which has a solver module that may be more up your alley.

How do I create Symbols in SymPy based on user input?

I am trying to create a python programme that takes a function from the user (in terms of x) and returns its derivative using SymPy. However, when I enter letters other than x, SymPy throws an error of undefined symbols. I want it to treat letters apart from x as constant.
For example, if a user enters a*x**2 + bx, they should get 2*a*x + b, and if they enter z*x**2 + px, they should get 2*z*x + p. How can I treat letters apart from 'x' as constants without having to hard-code every letter as a symbol?
I hope my question is clear. Feel free to ask for any clarifications if required.
You should first parse the user input and collect all symbols. To parse string to sympy expression use sympy.sympify. I assume you want to get derivative only W.R.T x. The full code will be:
import sympy as sp
expr = sp.sympify(input('enter expression: '))
print('Derivative w.r.t x: ', sp.diff(expr, 'x'))

I am writing a program that accepts user input in order to differentiate a function

In order to find the maximums and minimums of a function, I am writing a program that accepts a polynomial imputed from the user and finds where the derivative = 0.
from sympy import Symbol, Derivative
from sympy import symbols, Eq, solve
import sympy as sy
import numpy as np
import math
x= Symbol('x', real = True)
function= x**4 +7*x**2 +8
deriv= Derivative(function, x)
yprime = deriv.doit()
y = symbols('x')
eq1 = Eq(yprime,0)
sol = solve(eq1, )
The only reason that the code above is able to take the derivative and find solutions is because the coefficients and exponents are integers. If I ask for user input {e.g., function = input("What is your function: ")}, then the whole thing will become a string and SymPy can not take the derivative.
Is it possible to turn the coefficients and exponents into integers and leave the rest of the function as a string so that I can take the derivative?
If your equation can be arbitrarily complicated, you might want to use eval to parse it from Python syntax. Now, eval is generally unsafe to use on untrusted user input, but a user replying to an input() prompt is probably trusted (since they're usually sitting at the computer running the code).
So one option is:
function = eval(input("What is your function: "))
If placed just below the definition of x, it will allow that variable to be used in the equation. You could also provide a namespace for eval to use, rather than letting it use your function's local namespace (e.g. function = eval(input(...), {'x': Symbol('x', real=True)})).
If your problem space is more limited, and you only need to handle equations that are polynomials with integer coefficients, then you could write your own logic to input the equation in a much more simplified form. For instance, you could loop, asking for the coefficients in order (probably from the lowest exponent to the highest). Try something like this:
import itertools
from sympy import Symbol
x = Symbol('x', real = True)
function = 0
for exponent in itertools.count():
coef = input(f"Enter coefficient for x**{exponent} (or give an empty value to be done): ")
if not coef:
break
function += int(coef) * x**exponent
print("Polynomial so far:", function)
For the example equation in your question, you'd enter 8, 0, 7, 0, 1 and finally an empty input.
The better thing to do is to turn your string into a SymPy expression. As long as the user uses SymPy/python syntax, sympyify will convert it for you:
>>> from sympy import sympify, solve
>>> user='3*x**2-1'
>>> eq = sympify(user)
>>> x = eq.free_symbols.pop() # assuming there is 1 symbol
>>> solve(eq.diff(x))
[0]

Associated Legendre Function

Hi I am writing Python code which returns the associated Legendre function.
Using numpy poly1d function on this part,
firstTerm = (np.poly1d([-1,0,1]))**(m/2.0) # HELP!
It yields an error since it can only be raised to integer.
Is there any other alternative where I can raise the desired function to power 1/2 and etc.?
The reason you can't raise your poly1d to half-integer power is that that would not be a polynomial, since it would contain square roots.
While in principle you could orthogonalize the functions yourself, or construct the functions from something like sympy.special.legendre, but your safest bet is symbolic math. And hey, we already have sympy.functions.special.polynomials.assoc_legendre! Since symbolic math is slow, you should probably use sympy.lambdify to turn each function into a numerical one:
import sympy as sym
x = sym.symbols('x')
n = 3
m = 1
legfun_sym = sym.functions.special.polynomials.assoc_legendre(n,m,x)
legfun_num = sym.lambdify(x,legfun_sym)
print(legfun_sym)
print(legfun_num)
x0 = 0.25
print(legfun_sym.evalf(subs={x:x0}) - legfun_num(x0))
This prints
-sqrt(-x**2 + 1)*(15*x**2/2 - 3/2)
<function <lambda> at 0x7f0a091976e0>
-1.11022302462516e-16
which seems to make sense (the first is the symbolic function at x, the second shows that lambdify indeed creates a lambda from the function, and the last one is the numerical difference of the two functions at the pseudorandom point x0 = 0.25, and is clearly zero within machine precision).

Categories