How to tell Sympy that one symbol is "greater than other" - sympy

Suppose I have two symbols
x,y=symbols('x y')
My objective is to tell Sympy that x is always greater than y (x>y). Is there any way to achieve this?

There is no way to do this directly. The assumptions module does not support relations, and it's not (yet) integrated with the rest of SymPy anyway, so its assumptions won't help you, say, simplify an integral.
The workaround is to introduce a symbol expressing the difference of two symbols, and declare that to be positive. For example,
y = symbols('y')
p = symbols('p', positive=True)
x = y + p
Now SymPy knows that x > y:
>>> (x > y).simplify()
True
How useful this is in computations that involve x depends on whether doing .subs(x, y + p) will turn it into something that simplifies.
It's often easier to directly replace a condition with True or False, as I did here.

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

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()

Remove real element from list - SML

I have written the following code:
fun remove_element(nil, elem) = raise Empty
| remove_element(hd::tl, elem) = if(hd=elem) then tl else hd::remove_element(tl, elem);
but that function (which removed element elem from list) works for int. I need to make it work for real numbers, but I can't do it. I have tried a lot of ways of rewriting the function and also I used :real but these bring me errors.
Any suggestions?
Thank you
The accepted answer should have allowed you to finish your assignment, so I will show two other approaches for variations of your problem without worrying about doing your homework for you. As Kevin Johnson said, it isn't possible to directly compare two reals. It is possible to do so indirectly since a=b if and only if a<=b and b<=a. Often this is a bug, especially if the list in question is of numbers produced by numerical computations. But -- there are some situations where it makes sense to compare reals for equality so you should certainly be able to do so as long as you are clear that this is what you want. This leads to the following modification of your code:
fun remove_real([],x:real) = []
| remove_real(y::ys,x) =
if (y <= x andalso y >= x) then
remove_real(ys,x)
else
y::remove_real(ys,x);
A few points:
1) I changed it to remove all occurrences of the element from the list rather than just the first occurrence. This involved changing the basis case to returning the empty list since [] with y removed is just [] rather than an error situation. Also, rather than simply returning the tail if the element is found I return the recursive call applied to the tail to remove any additional occurrences later on. You could easily modify the code to make it closer to your original code.
2) I needed to put the explicit type annotation x:real so that SML could infer that the list was of type real list rather than type int list.
3) I replaced nil by [] for aesthetic reasons
4) I replaced your pattern hd::tl by y::ys. For one thing, hd and tl are built-in functions -- I see no reason to bind those identifiers to anything else, even if it is just local to a function definition. For another thing, the less visual clutter in a pattern the better.
5) I made more use of white space. Partially a matter of taste, but I think that fairly complicated clauses (like your second line) should be split across multiple lines.
If you want to go the route of including an error tolerance for comparing reals, I think that it makes most sense to include the tolerance as an explicit parameter. I find |x-y| < e to be more natural than two inequalities. Unfortunately, the built-in abs only applies to ints. If x - y is real then the expression
if x - y < 0.0 then y - x else x - y
returns the absolute value of x - y (it flips the sign in the case that it is neagative). As an added bonus -- the comparison with 0.0 rather than 0 is all that SML needs to infer the type. This leads to:
fun remove_elem([],x,tol) = []
| remove_elem(y::ys,x,tol) =
if (if x - y < 0.0 then y - x else x - y) < tol then
remove_elem(ys,x,tol)
else
y::remove_elem(ys,x,tol);
Typical output:
- remove_real([2.0, 3.1, 3.14, 3.145, 3.14], 3.14);
val it = [2.0,3.1,3.145] : real list
- remove_elem([2.0, 3.1, 3.14, 3.145, 3.14], 3.14,0.01);
val it = [2.0,3.1] : real list
- remove_elem([2.0, 3.1, 3.14, 3.145, 3.14], 3.14,0.001);
val it = [2.0,3.1,3.145] : real list
The issue is here: hd=elem
In languages like ML and Javascript, you cannot directly compare two reals as reals are bound to rounding errors.
You have to use a lambda range and define an interval instead. elem - lambda < hd andalso elem + lambda > hd

Ocaml fixed point implementation

I'm trying to figure out how to implement fixed point iteration in Ocaml. That is, given a function f and an x, I want to calculate what the final value of what f(f(f(x)...)) will be.
So for example, if my function is x/2 and my x=50, my answer should be 0.
So far, I have
let rec computed_fixed_point eq f x =
if (x == f x) then
x
else
computed_fixed_point eq f (f x)
This works for the function x/2 and x=50 (giving me 0), but for functions that go off to infinity or something other than 0, it doesn't seem to work.
Can another give me some advice? Thanks!
It's a little hard to understand the rationale of this problem. Not every function is going to have a fixed point. For example fun x -> (x + 1) mod 5. Not every function with a fixed point will reach the fixed point by repeated application from a distinct starting point. (I just did some googling, and fixed points like this are called "attractive fixed points".)
Here are some comments:
You shouldn't use ==, which is the physical equality operator. You possibly want to use =, equality of values.
However, I don't see what the eq parameter is for. Perhaps the caller is allowed to specify what equality to use. If so, you should use this instead of ==.

Haskell Beginner: Currying/List Associativity

From Learn You a Haskell:
Think about this list: [5]. That’s just syntactic sugar for 5:[]. On
the left side of the :, there’s a value; on the right side, there’s a
list. In this case, it’s an empty list. Now how about the list [4,5]?
Well, that desugars to 4:(5:[]). Looking at the first :, we see that
it also has an element on its left side and a list, (5:[]), on its
right side.
The same goes for a list like 3:(4:(5:6:[])), which could be written
either like that or like 3:4:5:6:[] (because : is right-associative)
or [3,4,5,6].
For the bolded part, I was expecting the growing list to culminate in 3:(4:(5:(6:[]))). This has something to do with my lack of understanding of currying, associativity, or both. Can someone tell me the flaw in my thinking?
Multiplication is associative. This means that (x * y) * z is the same as x * (y * z). However, : is not associative.
However, the terms "left-associative" and "right-associative" are different, and unrelated to the term "associative".
If * is left-associative, then x * y * z is the same thing as (x * y) * z. The parentheses are redundant.
If * is right-associative, then x * y * z is the same thing as x * (y * z). The parentheses are redundant.
Currying has nothing to do with this.
Since : is right-associative, [3,4,5,6] can be written as:
3:(4:(5:(6:[])))
3:4:(5:(6:[]))
3:(4:5:(6:[]))
3:4:5:(6:[])
3:(4:(5:6:[]))
3:4:(5:6:[])
3:(4:5:6:[])
3:4:5:6:[]
It's just a typo. There should be a parenthesis in the example (but it is the same behaviour without one, because of the associativity).
You say "I was expecting the growing list to culminate in 3:(4:(5:(6:[])))".
Indeed you are right. If you want to eliminate all syntactic sugar from [3,4,5,6], you will get 3:(4:(5:(6:[])))
You are puzzled by the fact that as you state in the comment in your question "the book says 3:(4:(5:6:[]))".
Again, you are right to be. In the interest of keeping presentation uniform, it shouldn't; this was probably a typo.
As far as Haskell syntax and semantics go though, there is nothing wrong with writing 3:(4:(5:6:[])) instead of 3:(4:(5:(6:[]))). What this boils down to is the question of whether 5:6:[] is the same as 5:(6:[]) or not. By the definition of right-associativity it is. Because : is right associative x:y:z = x:(y:z).
Just to add a geeky note here: by taking advantage of :'s right-associativity (i.e. not using parentheses), one can write 3:(4:(5:(6:[]))) quite concisely: 3:4:5:6:[]. This is only a single character longer than its syntactically sugared [3,4,5,6].
See also: http://en.wikipedia.org/wiki/Operator_associativity for more info on associativity.