Distribute derivative of sum with constant term after substitution - python

If I do
import sympy
k, V, Vprime = sympy.symbols('k, V, Vprime')
print sympy.diff(k + V(t), t)
I get Derivative(V(t), t) as I expect - the derivative distributes and the constant term has zero derivative.
However, if I construct an equivalent expression via substitution, simplify does not distribute the derivative. How can I get the same result via substitution as when I evaluate the expression directly?
sympy.diff(Vprime(t)).subs({Vprime(t): k + V(t)}).simplify()
returns Derivative(k + V(t), t).

The solution to this problem is provided by the doit method, which says it "Evaluate(s) objects that are not evaluated by default like limits, integrals, sums and products.":
sympy.diff(Vprime(t)).subs({Vprime(t): k + V(t)}).doit()
yields
Derivative(V(t), t)

Related

While solving a cubic equation, how do I divide a cubic polynomial by a linear one (Python 3)?

I'm making a solver of cubic equations in Python that includes division of polynomials.
from sympy import symbols
# Coefficients
a = int(input("1st coef: "))
b = int(input("2nd coef: "))
c = int(input("3rd coef: "))
d = int(input("Const: "))
# Polynomial of x
def P(x):
return a*x**3 + b*x**2 + c*x + d
x = symbols('x')
# Find 1 root by Cardano
R = (3*a*c - b**2) / (9*a**2)
Q = (3*b**3 - 9*a*b*c + 27*a**2*d) / (54*a**3)
Delta = R**3 + Q**2
y = (-Q + sqrt(Delta))**(1/3) + (-Q - sqrt(Delta))**(1/3)
x_1 = y - b/(3*a)
# Division
P(x) / (x - x_1) = p(x)
print(p(x)) # Just a placeholder
The program returns an error: "cannot assign to operator" and highlights the P(x) after the # Division comment (worded poorly, yes, but I'm from Russia so idc).
What I tried doing was to assign a variable to a polynomial and then dividing:
z = P(x)
w = x - x_1
p = z / w
print(p)
But alas: it just returns a plain old quotient (a = 1, b = 4, c = -9, d = -36):
(x**3 + 4*x**2 - 9*x - 36)/(x - 2.94254537742264)
Does anyone out here knows what to do in this situation (not to mention the non-exact value of x_1: the roots of x^3+4x^2-9x-36=0 are 3, -4, and -3, no floaty-irrational-messy-ugly things in sight)?
tl;dr: Polynomial division confusion and non-exact roots
I am not sure what exactly your question is but here is an attempt at an answer
The line
P(x) / (x - x_1) = p(x)
is problematic for multiple reasons. First of all it's important to know that the = operator in python (and a lot of other modern programming languages) is an assignment operator. You seem to come from more of a math background, so consider it to be something like the := operator. The direction of this is always fixed, i.e. with a = b you are always assigning the value of b to the variable a. In your case you are basically assigning an expression the value of p which does not make much sense:
Python can't assign anything to an expression (At least not as far as I know)
p(x) is not yet defined
The second problem is that you are mixing python functions with math functions.
A python function looks something like this:
def some_function(some_parameter)
print("Some important Thing!: ", some_parameter)
some_return_value = 42
return some_return_value
It (can) take some variable(s) as input, do a bunch of things with them, and then (can) return something else. They are generally called with the bracket operator (). I.e. some_function(42) translates to execute some_function and substitute the first parameter with the value 42. An expression in sympy however is as far as python is concerned just an object/variable.
So basically you could have just written P = a*x**3 + b*x**2 + c*x + d. What your P(x) function is doing is basically taking the expression a*x**3 + b*x**2 + c*x + d, substituting x for whatever you have put in the brackets, and then giving it back in as a sympy expression. (It's important to understand, that the x in your P python function has nothing to do with the x you define later! Because of that, one usually tries to avoid such "false friends" in coding)
Also, a math function in sympy is really just an expression formed from sympy symbols. As far as sympy is concerned, the return value of the P function is a (mathematical) function of the symbols a,b,c,d and the symbol you put into the brackets. This is why, whenever you want to integrate or differentiate, you will need to specify by which symbol to do that.
So the line should have looked something like this.
p = P(x) / (x - x_1)
Or you leave replace the P(x) function with P = a*x**3 + b*x**2 + c*x + d and end up with
p = P / (x - x_1)
Thirdly if you would like to have the expression simplified you should take a look here (https://docs.sympy.org/latest/tutorial/simplification.html). There are multiple ways here of simplifying expressions, depending on what sort of expression you want as a result. To make for faster code sympy will only simplify your expression if you specifically ask for it.
You might however be disappointed with the results, as the line
y = (-Q + sqrt(Delta))**(1/3) + (-Q - sqrt(Delta))**(1/3)
will do an implicit conversion to floating point numbers, and you are going to end up with rounding problems. To blame is the (1/3) part which will evaluate to 0.33333333 before ever seeing sympy. One possible fix for this would be
y = (-Q + sqrt(Delta))**(sympy.Rational(1,3)) + (-Q - sqrt(Delta))**(sympy.Rational(1,3))
(You might need to add import sympy at the top)
Generally, it might be worth learning a bit more about python. It's a language that mostly tries to get out of your way with annoying technical details. This unfortunately however also means that things can get very confusing when using libraries like sympy, that heavily rely on stuff like classes and operator overloading. Learning a bit more python might give you a better idea about what's going on under the hood, and might make the distinction between python stuff and sympy specific stuff easier. Basically, you want to make sure to read and understand this (https://docs.sympy.org/latest/gotchas.html).
Let me know if you have any questions, or need some resources :)

sympy solve function gives wrong result

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.

Modular inverse of a function in sympy

For a certain project, I'm using sympy to calculate expressions modulo another function. These functions all have binary coefficients (so x^2 + 2x = x^2$). Their application is in Galois Fields.
My issue is that when using the the sympy rem function with inverses (for example x**-1), is simply returns the inverse of the number (so in this case the answer is 1/x) rather than returning the modular inverse.
Due to the below comment, here is some further clarification. An oversimplified version of what I'm doing is:
from sympy import *
x = symbols('x')
f = raw_input() #here f = '(x^3 + x)*(x + 1)^2 + (x^2 + x)/(x^3) + (x)^-1'
expand(f)
>>> x**5 + 2*x**4 + 2*x**3 + 2*x**2 + x + 2/x + x**(-2)
#this is what I'm currently doing
rem(expand('(x^3 + x)*(x + 1)^2 + (x^2 + x)/(x^3) + (x)^-1'), 'x^2')
>>> x + 2/x + x**(-2)
#not the answer I am looking for, as I want all the degrees to be positive
This remainder function doesn't act as a mod function (ie doesn't keep things as positive powers of x), and I'm trying to find a replacement for it. I want to avoid parsing through the expression searching for inverse mods and just have the function deal with that on it's own. I might be missing a parameter, or just looking at a completely different function.
PS: I know that the ability to compute an expression mod another expression, while simultaneously treating inverses as modular inverses exists in sympy since I did it while testing that sympy will be enough for our purposes but didn't save the code back then.
First off, it's better to immediately convert your string into a SymPy expression with sympify. Passing strings to SymPy functions is bad practice.
When you use a polynomial like x + 1/x, SymPy treats this as a polynomial in x and 1/x.
In [73]: Poly(x + 1/x)
Out[73]: Poly(x + (1/x), x, 1/x, domain='ZZ')
I believe ratsimpmodprime does what you want. You should also be able to pass domain=GF(2), but it seems there are some bugs that prevent that from working.

Need to create function in Python that finds all complex and real roots of z^n=x(so the nth-roots of x)

beginner programmer here. I have been assigned to create a function 'Roots' that takes two parameters x and n(n has to be an integer) and then calculates all complex and real roots of the equation z^n=x. However, the only module/package I can use is math. Also, I have been told that the certain aspects of the following function 'Power_complex' play a big role into creating 'Roots':
def Power_complex(re, im, n): #calculates the n-th power of a complex number(lets call this a), where 're' is the real part and 'im' the imaginary part
import math
r=math.sqrt((re)**2+(im)**2) #calculates modulus
h=math.atan2(re,im) #calculates argument(angle)
ren=(r**n)*math.cos(h*n) #calculates the real part of a^n
imn=(r**n)*math.sin(h*n) #calculates the imaginary part of a^n
return ren, imn
print '(',re, '+', im, 'i',')','^',n,'=',ren,'+',imn,'i' #displays the result
Also, I need to somehow implement a for loop into 'Roots'.
I have been pondering over this for hours, but alas I really can't figure it out and am hoping one of you can help me out here.
BTW my python version is 2.7.10
The expression for the solutions is ( explained here ):
when
In the case that z^n is real, equal to the x in your question, then r = |x| and the angle is 0 or pi for positive and negative values, respectively.
So you make the modulus and argument as you have done, then make every solution corresponding to a value of k
z = [r**(1./n) * exp(1j * (theta + 2*pi*k) / n ) for k in range(n)]
This line uses a Python technique called list comprehension. An eqvivalent way of doing it (that you may be more familiar to) could be:
z = []
for k in range(n):
nthroot = r**(1./n) * exp( 1j * (theta + 2*pi*k) / n )
z.append(nthroot)
Printing them out could be done in the same fashion, using a for-loop:
for i in range(len(z)):
print "Root #%d = %g + i*%g" % (i, z[i].real, z[i].imag)
Note that the exp-function used must be from the module cmath (math can't handle complex numbers). If you are not allowed to use cmath, then I suggest you rewrite the expression for the solutions to the form without modulus and argument.

Scipy, optimize a function with argument dependent constraints

I am trying to use negative of scipy.optimize.minimize to maximize a function f (a, b, c, d). d is a numpy.array of guess variables.
I am trying to put some bounds on each d. And also a constraint on each d such that (d1 * a1 + d2 * a2 + ... + d3 * a3) < some_Value (a being the other argument to the subject function f).
My problem is how do I define this constraint as an argument to the maximize function.
I could not find any maximize function in the library so we're using the negative of minimize with minimize documentation over here.
Please consider asking for clarifications if the question is not clear enough.
It's not totally clear from your description which of the parameters of f you are optimizing over. For the purposes of this example I'm going to use x to refer to the vector of parameters you are optimizing over, and a to refer to another parameter vector of the same length which is held constant.
Now let's suppose you wanted to enforce the following inequality constraint:
10 <= x[0] * a[0] + x[1] * a[1] + ... + x[n] * a[n]
First you must define a function that accepts x and a and returns a value that is non-negative when the constraint is met. In this case we could use:
lambda x, a: (x * a).sum() - 10
or equivalently:
lambda x, a: x.dot(a) - 10
Constraints are passed to minimize in a dict (or a sequence of dicts if you have multiple constraints to apply):
con = {'type': 'ineq',
'fun': lambda x, a: a.dot(x) - 10,
'jac': lambda x, a: a,
'args': (a,)}
For greater efficiency I've also defined a function that returns the Jacobian (the sequence of partial derivatives of the constraint function w.r.t. each parameter in x), although this is not essential - if unspecified it will be estimated via first-order finite differences.
Your call to minimize would then look something like:
res = minimize(f, x0, args=(a,), method='SLSQP', constraints=con)
You can find another complete example of constrained optimization using SLSQP in the official documentation here.

Categories

Resources