In SymPy, there is a useful feature to create a dictionary of coefficients for a given expression.
However, I'm encountering an irritating bug (/feature?) whereby square roots are considered to be part of the variable, and not part of the coefficient value.
Minimum example:
from sympy import sqrt, symbols
k, t = symbols('k, t')
d = 1.5*t + 2.5*sqrt(2)*k
d.as_coefficients_dict()
This returns:
{𝑡:1.5, sqrt(2)*𝑘:2.5}
When instead, the sqrt(2) should be considered as part of the coefficient. Thus, I expected to see the result:
{𝑡:1.5, 𝑘:2.5*sqrt(2)}
NB, I'm using the latest SymPy version 1.4
Is this a bug? Or an alternative way to use the function to get the expected value please?
EDIT: I amended the question to note that I am using the Sympy sqrt function. I also tried using NumPy's np.sqrt, which evaluates correctly, but gives the full numerical value rather than a nice neat sqrt(2) for the value of the k coefficient.
The documentation explicitly states:
Return a dictionary mapping terms to their Rational coefficient.
So to start with, this is the expected behavior. To see this, you can note that the sqrt is not the problem, rather it is the fact that the coefficient is irrational. If we take a rational coefficient, we get your expected behavior:
>>> from sympy import sqrt, symbols
>>> k, t = symbols('k, t')
>>> d = 1.5*t + 2.5*sqrt(4)*k
>>> d.as_coefficients_dict()
{k: 5.00000000000000, t: 1.50000000000000}
One way to solve your problem is to explicitly inquire about each coefficient with the given variables:
>>> from sympy import sqrt, symbols
>>> k, t = symbols('k, t')
>>> d = 1.5*t + 2.5*sqrt(2)*k
>>> {sym : d.coeff(sym) for sym in (k, t)}
{k: 2.5*sqrt(2), t: 1.50000000000000}
Related
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)
according to this graph: desmos
print(solve('x**2 + x - 1/x'))
# [-1/3 + (-1/2 - sqrt(3)*I/2)*(sqrt(69)/18 + 25/54)**(1/3) + 1/(9*(-1/2 - sqrt(3)*I/2)*(sqrt(69)/18 + 25/54)**(1/3)), -1/3 + 1/(9*(-1/2 + sqrt(3)*I/2)*(sqrt(69)/18 + 25/54)**(1/3)) + (-1/2 + sqrt(3)*I/2)*(sqrt(69)/18 + 25/54)**(1/3), -1/3 + 1/(9*(sqrt(69)/18 + 25/54)**(1/3)) + (sqrt(69)/18 + 25/54)**(1/3)]
I was expecting [0.755, 0.57], but, I got something I cannot use in my future program. I desire to get a list of floats as result, so refer to this post, I did following, but I got some even more weird:
def solver(solved, rit=3):
res = []
for val in solved:
if isinstance(val, core.numbers.Add):
flt = val.as_two_terms()[0]
flt = round(flt, rit)
else:
flt = round(val, rit)
if not isinstance(flt, core.numbers.Add):
res.append(flt)
return res
print(solver(solve('x**2 + x - 1/x')))
# [-0.333, -0.333, -0.333]
Now I am really disappointed with sympy, I wonder if there is an accurate way to get a list of floats as result, or I will code my own gradient descent algorithm to find the roots and intersection.
sym.solve solves an equation for the independent variable. If you provide an expression, it'll assume the equation sym.Eq(expr, 0). But this only gives you the x values. You have to substitute said solutions to find the y value.
Your equation has 3 solutions. A conjugate pair of complex solutions and a real one. The latter is where your two graphs meet.
import sympy as sym
x = sym.Symbol('x')
# better to represent it like the equation it is
eq = sym.Eq(x**2, 1/x - x)
sol = sym.solve(eq)
for s in sol:
if s.is_real:
s = s.evalf()
print(s, eq.lhs.subs({x: s})) # eq.rhs works too
There are a variety of things you can do to get the solution. If you know the approximate root location and you want a numerical answer, nsolve is simplest since it has no requirements on the type of expression:
>>> from sympy import nsolve, symbols
>>> x = symbols('x')
>>> eq = x**2 + x - 1/x
>>> nsolve(eq, 1)
0.754877666246693
You can try a guess near 0.57 but it will go to the same solution. So is there really a second real roots? You can't use real_roots on this expression because it isn't in polynomial form. But if you split it into numerator and denominator you can check for the roots of the numerator:
>>> n, d = eq.as_numer_denom()
>>> from sympy import real_roots
>>> real_roots(n)
[CRootOf(x**3 + x**2 - 1, 0)]
So there is only one real root for that expression, the one that nroots gave you.
Note: the answer that solve gives is an exact solution to the cubic equation and it can't figure out definitively which ones are a solution to the equation so it returns all three. If you evaluate them you will find that only one of them is real. But since you don't need the symbolic solution, just stick to nroots.
I am trying to solve simultaneous equations for x and y, I am not getting any result (code just keeps on running). I feel the error is related to using sqrt in the equations but not sure. Can someone help me figure this out?
from __future__ import division
from sympy import Symbol,sqrt,solve
x = Symbol('x')
y = Symbol('y')
z = Symbol('z')
a = Symbol('a')
b = Symbol('b')
c = Symbol('c')
d = Symbol('d')
e = Symbol('e')
f = Symbol('f')
g = Symbol('g')
h = Symbol('h')
print (solve((sqrt((c-a)**2+(d-b)**2)+sqrt((x-c)**2+(y-d)**2)-2*sqrt((x-a)**2+(y-b)**2),(y-b)*(e-a)-(x-a)*(f-b)) ,x,y))
This is a(nother) problem were you have to rely on the A of CAS and let SymPy assist you instead of relying on SymPy (in it's current state) to do all the work. The following assumes that eqs is a list of the two equations you want to solve as you gave in the OP.
Notice that the 2nd equation is linear in both symbols. Solve for y and substitute into the first equation.
>>> yis = solve(eqs[1], y)[0]
>>> eq0 = eqs[0].subs(y,yis)
This gives an expression that has a lot of symbols in it and that slows things down. It also has two terms with sqrt that depend on x. Replace those arguments of the sqrt with Dummy symbols and then unrad the expression to get it in polynomial form, restore replacements and factor:
>>> from sympy.solvers.solvers import unrad, S
>>> reps = {i.base:Dummy() for i in eq0.atoms(Pow) if i.has(x) and i.exp==S.Half}
>>> ireps = {v:k for k,v in reps.items()}
>>> poly = unrad(eq0.xreplace(reps), *reps.values())[0].xreplace(ireps).factor()
Using factor is an expensive process to always use, but if you know the problem is going to take a long time without it, it is worth a try. In this case a quartic reduces to a product of quadratics which are easy to solve and don't require checking or simplification:
>>> xis = solve(poly, x)
There are three solutions for x and each of these can be substituted into the expression for y to get the three solutions. The solutions are large enough so they are not shown here.
>>> count_ops(xis)
386
I am trying to calculate some polynomials given an input numerator and denominator polynomials as coefficient arrays.
How can I create my polynomials from these arrays?
E.g:
Inputs:
den= [2,3,4]
num= [1,3]
Output:
(s+3)/(s^2+3*s+4)
I need to use symbols because I will further need to divide the results by other polynomials and perform further polynomial computations.
P.S Is sympy suitable for this? I would usually solve things like this in matlab but I want to expand my knowledge.
You can do the following:
den = [2, 3, 4]
num = [1, 3]
x = symbols('x')
Poly(num, x)/Poly(den, x)
This creates Poly objects for the numerator and denominator (not just expressions). The coefficients are listed from the highest power of x.
Note that the result of division is an ordinary expression, since there is no RationalFunction type in SymPy. If you want to apply the tools from the polys module to the numerator and denominator, keep them separate as a tuple.
I think what you want is (s+3)/(2*s^2+3*s+4), there is a typo in your original expression. And in Python, ^ is not power, power is **.
You just need a ordinary Python list comprehension:
from sympy import poly
from sympy.abc import s
den_ = sum(co*s**i for i, co in enumerate(reversed(den)))
num_ = sum(co*s**i for i, co in enumerate(reversed(num)))
res = num_/den_
SymPy does a wonderful work keeping track of all the operations I do to my symbolic expressions. But a the moment of printing the result for latex output I would like to enforce a certain ordering of the term. This is just for convention, and unfortunately that convention is not alphabetical on the symbol name(as reasonably sympy does)
import sympy as sp
sp.init_printing()
U,tp, z, d = sp.symbols('U t_\perp z d')
# do many operations with those symbols
# the final expression is:
z+tp**2+U+U/(z-3*tp)+d
My problem is that SymPy presents the expression ordered as
U + U/(-3*t_\perp + z) + d + t_\perp**2 + z
But this ordering is not the convention in my field. For us z has to be the leftmost expression, then tp, then U even if it is capitalized, d is the most irrelevant and is put at the right. All this variables hold a particular meaning and that is the reason we write them in such order, and the reason in the code variables are named in such way.
I don't want to rename z to a and as suggested in Prevent Sympy from rearranging the equation and then at the moment of printing transform that a into z. In Force SymPy to keep the order of terms there is a hint I can write a sorting function but I could not find documentation about it.
If you can put the terms in the order you want then setting the order flag for the Latex printer to 'none' will print them in that order.
>>> import sympy as sp
>>> sp.init_printing()
>>> U,tp, z, d = sp.symbols('U t_\perp z d')
>>> eq=z+tp**2+U+U/(z-3*tp)+d
Here we put them in order (knowing the power of tp is 2) and rebuild as an Add with evaluate=False to keep the order unchanged
>>> p = Add(*[eq.coeff(i)*i for i in (z, U, tp**2, d)],evaluate=False)
And now we print that expression with a printer instance with order='none':
>>> from sympy.printing.latex import LatexPrinter
>>> s=LatexPrinter(dict(order='none'))
>>> s._print_Add(p)
z + U \left(1 + \frac{1}{z - 3 t_\perp}\right) + t_\perp^{2} + d