I am trying to substitute an expression that is the output of a solved system of equations and am getting errors.
q,a,b,c=symbols('q,a,b,c')
def p(q):
return a-b*q
some_equation=eqn1-eqn2
new_equation=sol(some_equation,q)
New equation returns
[(a-c)/(2*b)]
when I use p(q).subs(q,new_equation) I get p(q) and return gives me a type error no matter what I do. Xreplace throws a Sympify error. Any suggestions to get what should be a simple sub to work???
Sympy's solve always returns a Python list of solutions. There can be zero, one or multiple solutions to a general equation. subs needs one concrete value from the list, it can not work with the list as a whole. Therefore, you need to iterate through the list to do the substitutions. If you are certain that there is only one solution, you can just use solutions[0]:
from sympy import symbols, solve, Eq
q, a, b, c = symbols('q a b c')
def p(q):
return a - b * q
some_equation = p(q) - c
solutions = solve(some_equation, q)
print("solutions:", solutions)
for sol in solutions:
print("solution for q =", sol, " --> p(q) =", p(q).subs(q, sol))
Output:
solutions: [(a - c)/b]
solution for q = (a - c)/b --> p(q) = c
Note that instead of writing p as a function of q, you can also write it directly as a sympy expression: p = a - b * q. Also note that although you can write the equation as some_equation = p(q) - c, sympy's canonical way to write such equations is some_equation = Eq(p(q), c).
Here is another example, which has two solutions. It also uses simplify() because more complicated expressions by default are only simplified just a little bit.
p = a * q ** 2 + b * q
some_equation = Eq(p, c)
solutions = solve(some_equation, q)
print("solutions:", solutions)
for sol in solutions:
print("solution for q =", sol, " --> p(q) =", p.subs(q, sol).simplify())
Output:
solutions: [(-b + sqrt(4*a*c + b**2))/(2*a), -(b + sqrt(4*a*c + b**2))/(2*a)]
solution for q = (-b + sqrt(4*a*c + b**2))/(2*a) --> p(q) = c
solution for q = -(b + sqrt(4*a*c + b**2))/(2*a) --> p(q) = c
i am trying to solve a matrix that has 6x6 matrices as it's entries(elements)
i tried multiplying the inverse of gen to the solution matrix, but i don't trust the correctness of the answer am getting.
from sympy import Eq, solve_linear_system, Matrix,count_ops,Mul,horner
import sympy as sp
a, b, c, d, e,f = sp.symbols('a b c d e f')
ad = Matrix(([43.4,26.5,115,-40.5,52.4,0.921],
[3.78,62.9,127,-67.6,110,4.80],
[41.25,75.0,213,-88.9, 131, 5.88],
[-10.6,-68.4,-120,64.6,-132,-8.49],
[6.5,74.3,121,-72.8,179,29.7],
[1.2,30.7,49.7,-28.7,91,29.9]))
fb= Matrix(([1,0,0,0,0,0],
[0,1,0,0,0,0],
[0,0,1,0,0,0],
[0,0,0,1,0,0],
[0,0,0,0,1,0],
[0,0,0,0,0,1]))
ab = Matrix(([-0.0057],
[0.0006],
[-0.0037],
[0.0009],
[0.0025],
[0.0042]))
az = sp.symbols('az')
bz = sp.symbols('bz')
fz = sp.symbols('fz')
gen = Matrix(([az, fz, 0, 0, 0, 0,bz],
[fz,az,fz,0,0,0,bz],
[0,fz,az,fz,0,0,bz],
[0,0,fz,az,fz,0,bz],
[0,0,0,fz,az,fz,bz],
[0,0,0,0,fz,az,bz]))
answer = solve_linear_system(gen,a,b,c,d,e,f)
first_solution = answer[a]
df = count_ops(first_solution)
print(df,first_solution)
disolved = zip(first_solution.simplify().as_numer_denom(),(1,-1))
dft = Mul(*[horner(b)**e for b,e in disolved])
dff = count_ops(dft)
print(dff,dft)
_1st_solution = dft.subs({az:ad,fz:fb,bz:ab},simultaneous = True).doit()
print(_1st_solution)
when i ran my code it raised sympy.matrices.common.ShapeError
You have to be careful when using horner with expressions containing commutative symbols that are actually noncommutative (in your case because they represent matrices). Your dft expression is
(az**2*bz - bz*fz**2)/(az*(az*(az + fz) - 2*fz**2) - fz**3)
but should maybe be
(az**2 - fz**2)*(az*(az*(az + fz) - 2*fz**2) - fz**3)**(-1)*bz
You would have received a correct expression if you had created the symbols as noncommutative (as shown below).
But you can't use horner with non-commutative symbols, so I just rearranged the expression by hand; you will have to check to see that the ordering is right. As an alternative to doing the factoring by hand you might also try using factor_nc to help you -- but it won't handle horner like expression factoring:
>>> ax, bz, fz = symbols('az bz fz, commutative=False)
>>> (az**2*bz - fz**2*bz)
az**2*bz - fz**2*bz
>>> factor_nc(_)
(az**2 - fz**2)*bz
Working on a problem with polynomials with complex coefficients,
I am stuck with the following problem:
Let's say I have a polynomial P = λ^16*z + λ^15*z^2, where λ is complex.
I want to simplify having the following constraint: λ^14 = 1.
So, plugging in, we should get:
P = λ^2*z + λ*z^2.
I have tried P.subs(λ**14,1) but it doesn't work, because it assumes λ is real I guess. So it returns the original expression: P = λ^16*z + λ^15*z^2, without factoring out λ^14...
I don't know any simple way to achieve what you want in sympy, but you could substitute each value explicitly:
p = (λ**16)*z + (λ**15)*(z**2)
p = p.subs(λ**16, λ**2).subs(λ**15, λ**1)
>>> z**2*λ + z*λ**2
Why subs fails to work here:
subs only substitutes an expression x**m in x**n when m is a factor of n, e.g.:
p.subs(λ, 1)
>>> z**2 + z
p.subs(λ**2, 1)
>>> z**2*λ**15 + z
p.subs(λ**3, 1)
>>> z**2 + z*λ**16
p.subs(λ**6, 1)
>>> z**2*λ**15 + z*λ**16
etc.
If you assume that λ is real, this works:
lambda_, z = sym.symbols('lambda z', real=True)
print((lambda_**16*z + lambda_**15*z**2).subs(lambda_**14, 1))
z**2 + z
Edit:
It shouldn't actually work anyway because λ may be negative. What you want is only true if λ is a positive number.
You can use the ratsimpmodprime() function to reduce a polynomial modulo a set of other polynomials. There is also the reduce() function, which does something similar.
>>> P = λ**16*z + λ**15*z**2
>>> ratsimpmodprime(P, [λ**14 - 1])
z**2*λ + z*λ**2
This works:
P.simplify().subs(λ**15,1).expand()
I found this to be tricky to explain, but I'll do my best through an example.
Consider the expression assigned to the variable grad below
from sympy import *
a, x, b = symbols("a x b")
y_pred = a * x
loss = log(1 + exp(- b * y_pred))
grad = diff(loss, x, 1)
grad has the following expression:
-a*b*exp(-a*b*x)/(1 + exp(-a*b*x))
Now I want to manipulate grad in two ways.
1) I want sympy to try rewrite the expression grad such that none of its terms look like
exp(-a*b*x)/(1 + exp(-a*b*x)).
2) I also want it to try to rewrite the expression such that it has at least one term that look like this 1./(1 + exp(a*b*x)).
So at the end, grad becomes:
-a*b/(1 + exp(a*b*x)
Note that 1./(1 + exp(a*b*x)) is equivalent to exp(-a*b*x)/(1 + exp(-a*b*x)) but I don't want to mention that to sympy explicitly :).
I'm not sure if this is feasible at all, but it would be interesting to know whether it's possible to do this to some extent.
cancel does this
In [16]: cancel(grad)
Out[16]:
-a⋅b
──────────
a⋅b⋅x
ℯ + 1
This works because it sees the expression as -a*b*(1/A)/(1 + 1/A), where A = exp(a*b*x), and cancel rewrites rational functions as canceled p/q (see the section on cancel in the SymPy tutorial for more information).
Note that this only works because it uses A = exp(a*b*x) instead of A = exp(-a*b*x). So for instance, cancel won't do the similar simplification here
In [17]: cancel(-a*b*exp(a*b*x)/(1 + exp(a*b*x)))
Out[17]:
a⋅b⋅x
-a⋅b⋅ℯ
────────────
a⋅b⋅x
ℯ + 1
Are you just looking for simplify?
>>> grad
-a*b*exp(-a*b*x)/(1 + exp(-a*b*x))
>>> simplify(grad)
-a*b/(exp(a*b*x) + 1)
How do i implement this kind of equation in python dC/dt = r + kI - dC where the left hand side are constants and the right hand side are varibles?
i am relatively new to python and as such can't really do much.
from sympy.solvers import ode
r=float(input("enter r:"))
k=float(input("enter k:"))
I=float(input("enter I:"))
d=float(input("enter d:"))
C=float(input("enter C:"))
dC/dt=x
x=r + kI-dC
print(x)
what it just does equate the values of x and not any differential, would like help getting this to work.
if possible i would like to get answer specifying the using of sympy,
but all answers are truly appreciated.
You asigned values to all the variables that are on the rhs of x so when you show x you see the value that it took on with the variables that you defined. Rather than input values, why not try solve the ode symbolically if possible?
>>> from sympy import *
>>> var('r k I d C t')
(r, k, I, d, C, t)
>>> eq = Eq(C(t).diff(t), r + k*I + d*C(t)) # note d*C(t) not d*C
>>> ans = dsolve(eq); ans
C(t) == (-I*k - r + exp(d*(C1 + t)))/d
Now you can substitute in values for the variables to see the result:
>>> ans.subs({k: 0})
C(t) == (-r + exp(d*(C1 + t)))/d