Simplify expression with assumptions involving relations between variables in SymPy - sympy

Is it possible to simplify an expression in SymPy, if we know that variables satisfy certain equation?
For example in Mathematica we can write something like this:
Simplify[a+b-c, a+b==c]
Of course in this case it is possible to solve for a and make a substitution. However, for the long expressions making a global substitution might not make a sense. If the goal is to produce the shortest expression possible, one might need to apply substitution for the certain terms and leave the rest untouched or solve for b instead of a.
I think sympy.assumptions module cannot impose restrictions mutually on the several variables.
Is it possible to achieve the functionality of Mathematica's Simplify[expr, assum] in any other way in SymPy?
Or is there any other open-source project which can do something like this?

SymPy's current assumptions system can not handle relationships between variables although that is being worked on. There are a couple of ways that you can do this though.
The ratsimpmodprime function simplifies an expression that is polynomial in some symbols based on knowing that the symbols themselves satisfy polynomial equations. We can use this to make a function that simplifies the example you showed:
In [26]: a, b, c = symbols('a:c')
In [27]: polysimp = lambda expr, eqs: ratsimpmodprime(expr, groebner(eqs).exprs)
In [28]: polysimp(a + b - c, [a + b - c])
Out[28]: 0
In [29]: polysimp(a + b, [a + b - c])
Out[29]: c
In [31]: polysimp(a**4 + b - c, [a**2 - b, b - c])
Out[31]:
2
c
You can also introduce a new symbol and solve for that along with the other equations as a combined system:
In [33]: solve([z - (a + b - c), a + b - c])[z]
Out[33]: 0
This method has the advantage that you can choose which symbols you want to eliminate e.g.:
In [38]: solve([z - (a + b), a + b - c], [z, c])[z]
Out[38]: a + b
In [39]: solve([z - (a + b), a + b - c], [z, b])[z]
Out[39]: c
Either answer is valid since a + b == c so the expected output from "simplifying" is ambiguous.

Related

Modify an expression involving derivatives of functions by changing variables

I am attempting to make a YouTube video in which I demonstrate how SymPy can be used to verify the steps in the derivation of a solution to Schrodinger's equation. There is an expression involving derivatives"
u=symbols('u')(r)
diff(u,r,2)
and a change of variables (a is constant):
r=a*x
or
u.subs(r,a*x)
and I want to get back something like:
diff(u,x,2)/a**2
I understand that I may need something like
u=Function('u')(x)
or
u=Symbol('u', class=Function)
But I have already defined u:
u=Function('u')(r)
I have been unable to get anything to work. If I differentiate u with respect to x, I get zero because (apparently) SymPy sees u as depending on r but not x. I do not understand the Sympy Function class.
This works for built-in functions like cos:
diff(cos(a*x),x)
returns
-a*sin(a*x)
I just want the same behavior for my abstract function u.
Substituting for the independent variable in a differential equation is something that is difficult or not yet properly supported in sympy. You can do this:
In [9]: u = Function('u')
In [10]: r = Symbol('r')
In [11]: u(r)
Out[11]: u(r)
In [12]: u(r).diff(r)
Out[12]:
d
──(u(r))
dr
In [13]: a, x = symbols('a, x')
In [15]: u(r).diff(r).subs(r, a*x)
Out[15]:
⎛d ⎞│
⎜──(u(r))⎟│
⎝dr ⎠│r=a⋅x
Part of the problem is that sympy doesn't have a way to represent u' as the derivative of the single argument function u without differentiating with respect to a symbol.
What is needed is something like dchange from Maple:
https://github.com/sympy/sympy/issues/17590
There are complicated ways to make this work in sympy if needed but those are probably not suitable for a youtube video. I suggest to skip over this section in the video :)
In [1]: u = Function('u')
In [2]: a, r, x = symbols('a, r, x')
In [3]: expr = u(r).diff(r, 2)
In [4]: expr
Out[4]:
2
d
───(u(r))
2
dr
In [5]: expr.subs(u(r).diff(r, 2), 1/a**2 * u(x).diff(x, 2)) # cheating
Out[5]:
2
d
───(u(x))
2
dx
─────────
2
a

Build MILP constraint from if-else statements

I need to build a MILP (Mixed integer linear programming) constraint form this if-else statement:
with beta is a constant.
if (a > b) then c = beta else c = 0
How can I build the statement to MILP constraint. Are there any techniques for solving this problem. Thank you.
I am assuming that a, b, and c are all decision variables here. To build your constraint, you need to add a new binary variable -- let's call it x -- that will equal 1 if a > b and 0 otherwise. You also need a large constant M. Then add the following constraints:
Mx >= a - b
M(1-x) >= b - a
x in {0,1}
The logic is: If a > b, then x must equal 1 by the first constraint (and x may equal 1 by the second constraint). If b > a, then 1-x must equal 1 by the second constraint, i.e., x must equal 0 (and x may equal 0 by the first constraint).
Next, we need a constraint that says, if x = 1, then c = beta, otherwise, c = 0:
c = beta * x
Note: The logic above allows c to equal either 0 or beta if a = b; the solver will decide. Do you need c to equal 0 if a = b?
Another note: In "big-M"-type formulations like this one, it's always best to keep M as small as possible while maintaining the validity of the constraints. In this case, this means setting M to the largest possible (or plausible) difference between a and b. If your model is small, it won't matter much, but if you have lots of these decision variables, then it can matter a lot.

Regular Language Closure Unconcatenation

I'm trying to find an operation that can take a regular language and "unconcatenate" it with another. For example:
a*L - a* = L | where L is a regular language
I know that difference (subtraction) isn't the operation I want. But I believe I'm getting my point across.
Another way to look at it is if there have a set L that is logically equal to (A ∪ B), but we do not have access to A. So if we can only use L, B, and derivations of such, can we somehow derive A. Basically:
L - B = A | L = (A ∪ B)
I have put plenty of thought into this problem, using many variations of compliment, intersection, and other closure properties of regular languages, but I simply can't figure it out.
The best I've managed to come up with is:
A = ((L - B) ∪ (A ∩ B) | L = (A ∪ B)
However this requires A on the right side.
If L = A U B, define an operator - such that L - B = A.
The problem with this is that the operator - is not well-defined: Given L and B, there are potentially several languages which satisfy L = A U B. In particular, if A is a subset of L and any (possibly improper) superset of L \ B, then A is a solution; that is, if A = (L \ B) U C, where C is a (possibly improper) subset of B, then L - B might as well be equal to that set.
Now, you could define - to mean the set of all such A, and in that case, you could make this workable using set difference, union and power set operators. Then, L - B = Q where Q = {(L \ B) U {}, (L \ B) U {B[0]}, ..., (L \ B) U B = L}.
You can make this well-defined if you specify - always returns the "smallest" element of Q (for finite sets, the one with the fewest elements; for infinite sets, the one which is a subset of all other sets) in which case you recover simply L \ B.
If L = B.A, define an operator - such that L - B = A.
A similar problem exists here: there may be several languages which, when appended to B, give L. For example, consider B = a*, and two choices for A: a* and {e}, the language containing only the empty set. You can show without much effort that a* a* = a* e, so L is the same either way, B is the same, and L - B must now produce two different values: either a* or {e}.

How to rewrite an expression in terms of an other expression in sympy

EDIT: I am not asking how to solve an equation in terms of a given variable (as in this supposed duplicated question), but how to represent an expression in terms of an other one, as specified in the question.
I believe it is the "duplicated" question to have a misleading title.
I am very new with SymPy. I have an expression that, once expressed in terms to an other expression, should become very nice.
The problem is that I don't know how to "force" to express the original expression in terms of the other one.
This is a basic example:
import sympy as sp
sp.init_printing(use_unicode=True)
a,b,c = sp.symbols('a b c')
A = a+b+c
B = a+c
C = A.subs(a+c,B) # Expected/wanted: C = B+b
C
A.rewrite(B)
A and B could be rather complex expressions. For reference, this is my real-case scenario:
import sympy as sp
sp.init_printing(use_unicode=True)
t, w, r = sp.symbols('t w r')
S = sp.Function('S')(t)
V = (S-w*(1+r)**t)/(((1+r)**t)-1)
V
St = -(r + 1)**t*(w - S)*sp.log(r + 1)/((r + 1)**t - 1)
St
Once I write St in terms of V, I should be able to simplify to get just
St = rS(t)+rV
But I am unable to do it in SymPy.
First note that when you do something like
a,b,c = sp.symbols('a b c')
A = a+b+c
B = a+c
variables A, B are not new Sympy symbols that Sympy can understand and operate on, rather, they are aliases for the Sympy expressions a+b+c and a+c, respectively. Therefore, A.subs(a+c,B) is essentially the same as A.subs(a+c,a+c), which is, of course, meaningless. You get the idea of why A.rewrite(B) is also of no use.
I do not think that calls like expr.subs({complicated_mutlivariable_formula: new_variable}) work in Sympy. One way to do what you want is to first solve the equation complicated_mutlivariable_formula = new_variable with respect to one of the "old" variables, and, assuming a unique solution exist, use subs() to substitute this variable.
Applying this approach for the second example:
# sympy Symbol A will be used to represent expression V
A = sp.symbols('A')
# Solve the equation V==A with respect to w, which has a unique solution as a function of A
w_A = sp.solve(sp.Eq(V,A), w)[0]
# Now substitute w
St.subs({w:w_A}).simplify()

Interleaving in OCaml

I am trying to create a function which interleaves a pair of triples such as ((6, 3, 2), ( 4, 5 ,1)) and create a 6-tuple out of this interleaving.
I made some research but could understand how interleaving is supposed to work so I tried something on my own end ended up with a code that is creating a 6-tuple but not in the right interleaved way. This is my code
let interleave ((a, b, c), (a', b', c')) =
let sort2 (a, b) = if a > b then (a, b) else (b, a) in
let sort3 (a, b, c) =
let (a, b) = sort2 (a, b) in
let (b, c) = sort2 (b, c) in
let (a, b) = sort2 (a, b) in
(a, b, c) in
let touch ((x), (y)) =
let (x) = sort3 (x) in
let (y) = sort3 (y) in
((x),(y)) in
let ((a, b, c), (a', b', c')) = touch ((a, b, c), (a', b', c')) in
(a, b', a', b, c, c');;
Can someone please explain to me how with what functions I can achieve a proper form of interleaving. I haven't learned about recursions and lists in case you would ask why I am trying to do it this way.
Thank you already.
The problem statement uses the word "max" without defining it. If you use the built-in compare function of OCaml as your definition, it uses lexicographic order. So you want the largest value (of the 6 values) in the first position in the 6-tuple, the second largest value next, and so on.
This should be pretty easy given your previously established skill with the sorting of tuples.
For what it's worth, there doesn't seem to be much value in preserving the identities of the two 3-tuples. Once inside the outermost function you can just work with the 6 values as a 6-tuple. Or so it would seem to me.
Update
From your example (should probably have given it at the beginning :-) it's pretty clear what you're being asked to do. You want to end up with a sequence in which the elements of the original tuples are in their original order, but they can be interleaved arbitrarily. This is often called a "shuffle" (or a merge). You have to find the shuffle that has the maximum value lexicographically.
If you reason this out, it amounts to taking whichever value is largest from the front of the two tuples and putting it next in the output.
This is much easier to do with lists.
Now that I understand what your end-goal is . . .
Since tuples of n elements are different types for different n's, you need to define helper functions for manipulating different sizes of tuples.
One approach, that basically mimics a recursive function over lists (but requires many extra functions because of tuples all having different types), is to have two sets of helper functions:
functions that prepend a value to an existing tuple: prepend_to_2, up through prepend_to_5. For example,
let prepend_to_3 (a, (b, c, d)) = (a, b, c, d)
functions that interleave two tuples of each possible size up to 3: interleave_1_1, interleave_1_2, interleave_1_3, interleave_2_2, interleave_2_3, and interleave_3_3. (Note that we don't need e.g. interleave_2_1, because we can just call interleave_1_2 with the arguments in the opposite order.) For example,
let interleave_2_2 ((a, b), (a', b')) =
if a > a'
then prepend_to_3 (a, interleave_1_2 (b, (a', b')))
else prepend_to_3 (a', interleave_1_2 (b', (a, b)))
(Do you see how that works?)
Then interleave is just interleave_3_3.
With lists and recursion this would be much simpler, since a single function can operate on lists of any length, so you don't need multiple different copies of the same logic.