How to simplify logarithm of exponent in sympy? - python

When I type
import sympy as sp
x = sp.Symbol('x')
sp.simplify(sp.log(sp.exp(x)))
I obtain
log(e^x)
Instead of x. I know that "there are no guarantees" on this function.
Question. Is there some specific simplification (through series expansion or whatsoever) to convert logarithm of exponent into identity function?

You have to set x to real type and your code will work:
import sympy as sp
x = sp.Symbol('x', real=True)
print(sp.simplify(sp.log(sp.exp(x))))
Output: x.
For complex x result of this formula is not always is equal to x. Example is here.

If you want to force the simplification, expand can help because it offers the force keyword which basically makes certain assumptions like this for you without you having to declare your variables as real. But be careful with the result -- you will not want to use it when those assumptions are not warranted.
>>> log(exp(x)).expand(force=True)
x

You can also set the argument "inverse" to "True" in the simplify function:
>>> simplify(log(exp(x)), inverse=True)
x

Related

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]

How to return a finite (float) value with nonlinsolve in SymPy?

I am very new to programming, and had to use sympy for a school project.
I think I get that using nonlinsolve to return an angle gives an ImageSet with the angle + 2n*pi. However I want it to return only the value of the angle (in the interval [0,pi/2]), and as one value and not an interval.
from sympy import nonlinsolve, symbols,cos
x=symbols('x')
print(nonlinsolve([cos(x)-1],[x]).args[0][0])
I want the result to be 0 and not 2*n*pi.
Clarification : I know that the result is correct, but I only want one value, that I can use algebraically, and I don't know how Sympy works (how to manipulate ImageSets)
So I might be wrong because i dont use sympy, but the solution that solvers return seems to be corect to me.
ImageSet(Lambda(_n, 2*_n*pi), Integers)
From what I understand solver returned lambda function. Cosinus is a cyclic function which means it reapeats it's value every 2PI. So the solver says first solution (_n = 0) is 0, second (_n = 1) is 2pi and so on.
look at the function plot and it will hopefully make sense:
Wolfram Alpha - (cos(x) - 1)
EDIT: I think you need to use intersect method of imageset like this( note that intersect returns all the intersections, here i selected just the first one):
from sympy import nonlinsolve, symbols,cos, Interval
import math
x = symbols('x')
f = nonlinsolve([cos(x)-1], [x]).args[0][0]
sol = f.intersect(Interval(0, math.pi/2)).args[0]
print(sol)

Subsitute a matrix M by (-M) in SymPy and display it unambiguously

Suppose I have the following matrix expression:
import sympy
sympy.init_printing(use_unicode=True)
x = sympy.MatrixSymbol('x', 2, 2)
y = sympy.MatrixSymbol('y', 2, 2)
a = x * y
I would like to substitute the second matrix with the same matrix times negative one:
a.subs(y, (-y))
If x and y were regular SymPy symbols, this would show as -xy. But in this case it shows as x - y. Even though upon substitution of matrix values it evaluates correctly (i.e. as -xy), this demonstration quickly becomes ambiguous. How do I make it display correctly?
When sympy.init_printing() is not called, it displays unambiguously as x\*(-y).
I use this in Jupyter.
This is a bug in SymPy's LaTeX printer: it does not consider that MatMul(Integer(-1), MatrixSymbol(...)) needs parentheses in a product.
Until the bug is fixed, a workaround is to use "pretty" printing instead of LaTeX:
sympy.init_printing(use_latex=False)
resulting in x⋅(-y). Pretty-print is generally more readable than str output like x*(-y).
The big is fixed in the current master branch and therefore should not appear in SymPy versions above 1.3.

sympy solveset returns FiniteSet in one case but a Complement in another case

So I am starting with an equality of an equation and a fraction that I use to solve for both x and y:
mrs = y/x
ratio = 2/5
x = sympy.solveset(sympy.Eq(mrs, ratio), x)
y = sympy.solveset(sympy.Eq(mrs, ratio), y)
In the end, solving for y returns:
{2*x/5}
Which is a FiniteSet
But solving for x returns:
{5*y/2} \ {0}
Which is a Complement
I don't get why solving for one variable gives me a FiniteSet when solving for the other doesn't do the same? Also, would there be a way to solve for the other variable so as to get a FiniteSet instead of a Complement?
What do you expect as a result? Could you solve this problem by hand and write the expected solution? And why would you want a FiniteSet as solution?
I myself can not come up with a better notation than sympy, since x=0 needs to be excluded.
When you continue working with the solutions sympy can easily work with both, FiniteSet and Complement. Mathematically those are not completely different structures. The difference is that sympy somehow needs to represent these solutions internally and can not use the same construction for everything, but rather uses small building blocks to create the solution. The result you get with type(x) is symply the last building block used.
EDIT: Some math here: x=0 does not solve the equation y/x=2/5 for any y. So this must be excluded from the solutionset.
If you solve for y, then x=0 is already excluded since y/0 is not well defined.
If you solve for y, then y=0 is a priori possible, since 0/x=0 for x!=0. Thus sympy needs to exclude x=0 manually, which it does by removing 0 from the set of solutions.
Now, since we know that x=0 can never be a solution of the equation we can exclude it before even trying to solve the equation. Therefore we do
x = sympy.symbols('x', real=True, nonzero=True)
right at the beginning of the example (before the definition of mrs). The rest can remain unchanged.

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