general expression substitution in sympy - sympy

I have two univariate functions, f(x) and g(x), and I'd like to substitute g(x) = y to rewrite f(x) as some f2(y).
Here is a simple example that works:
In [240]: x = Symbol('x')
In [241]: y = Symbol('y')
In [242]: f = abs(x)**2 + 6*abs(x) + 5
In [243]: g = abs(x)
In [244]: f.subs({g: y})
Out[244]: y**2 + 6*y + 5
But now, if I try a slightly more complex example, it fails:
In [245]: h = abs(x) + 1
In [246]: f.subs({h: y})
Out[246]: Abs(x)**2 + 6*Abs(x) + 5
Is there a general approach that works for this problem?

The expression abs(x)**2 + 6*abs(x) + 5 does not actually contain abs(x) + 1 anywhere, so there is nothing to substitute for.
One can imagine changing it to abs(x)**2 + 5*(abs(x) + 1) + abs(x), with the substitution result being abs(x)**2 + 5*y + abs(x). Or maybe changing it to abs(x)**2 + 6*(abs(x) + 1) - 1, with the result being abs(x)**2 + 6*y - 1. There are other choices too. What should the result be?
There is no general approach to this task because it's not a well-defined task to begin with.
In contrast, the substitution f.subs(abs(x), y-1) is a clear instruction to replace all occurrences of abs(x) in the expression tree with y-1. It returns 6*y + (y - 1)**2 - 1.
The substitution above of abs(x) + 1 in abs(x)**2 + 6*abs(x) + 5 is a clear instruction too: to find exact occurrences of the expression abs(x) + 1 in the syntax tree of the expression abs(x)**2 + 6*abs(x) + 5, and replace those subtrees with the syntax tree of the expression abs(x) + 1. There is a caveat about heuristics though.
Aside: in addition to subs SymPy has a method .replace which supports wildcards, but I don't expect it to help here. In my experience, it is overeager to replace:
>>> a = Wild('a')
>>> b = Wild('b')
>>> f.replace(a*(abs(x) + 1) + b, a*y + b)
5*y/(Abs(x) + 1) + 6*y*Abs(x*y)/(Abs(x) + 1)**2 + (Abs(x*y)/(Abs(x) + 1))**(2*y/(Abs(x) + 1))
Eliminate a variable
There is no "eliminate" in SymPy. One can attempt to emulate it with solve by introducing another variable, e.g.,
fn = Symbol('fn')
solve([Eq(fn, f), Eq(abs(x) + 1, y)], [fn, x])
which attempts to solve for "fn" and "x", and therefore the solution for "fn" is an expression without x. If this works
In fact, it does not work with abs(); solving for something that sits inside an absolute value is not implemented in SymPy. Here is a workaround.
fn, ax = symbols('fn ax')
solve([Eq(fn, f.subs(abs(x), ax)), Eq(ax + 1, y)], [fn, ax])
This outputs [(y*(y + 4), y - 1)] where the first term is what you want; a solution for fn.

Related

How in sympy Disable unnecessary parenthesis?

Tell me please, How to forbid to open brackets? For example,
8 * (x + 1) It should be that way, not 8 * x + 8
Using evaluate = False doesn't help
The global evaluate flag will allow you to do this in the most natural manner:
>>> with evaluate(False):
... 8*(x+1)
...
8*(x + 1)
Otherwise, Mul(8, x + 1, evaluate=False) is a lower level way to do this. And conversion from a string (already in that form) is possible as
>>> S('8*(x+1)',evaluate=False)
8*(x + 1)
In general, SymPy will convert the expression to its internal format, which includes some minimal simplifications. For example, sqrt is represented internally as Pow(x,1/2). Also, some reordering of terms may happen.
In your specific case, you could try:
from sympy import factor
from sympy.abc import x, y
y = x + 1
g = 8 * y
g = factor(g)
print(g) # "8 * (x + 1)"
But, if for example you have g = y * y, SymPy will either represent it as a second power ((x + 1)**2), or expand it to x**2 + 2*x + 1.
PS: See also this answer by SymPy's maintainer for some possible workarounds. (It might complicate things later when you would like to evaluate or simplify this expression in other calculations.)
How about sympy.collect_const(sympy.S("8 * (x + 1)"), 8)?
In general you might be interested in some of these expression manipulations: https://docs.sympy.org/0.7.1/modules/simplify/simplify.html

Derivative of a function with different formulas on different intervals

Is there a canonical way of declaring a function by parts in Sympy? I tried
import sympy
import sympy.functions.special.delta_functions as special
sympy.init_printing()
x = sympy.symbols('x', real=True)
V = x*x * (special.Heaviside(x + 1) - special.Heaviside(x - 1)) \
+ (1 + 2*sympy.log(x)) * special.Heaviside(x - 1) \
+ (1 + 2*sympy.log(-x)) * special.Heaviside(-x - 1)
which defines a differentiable function, but
print(V.diff(x).simplify())
# Prints: (x*(x**2*(-DiracDelta(x - 1) + DiracDelta(x + 1)) - 2*x*(Heaviside(x - 1) - Heaviside(x + 1)) - (2*log(-x) + 1)*DiracDelta(x + 1) + (2*log(x) + 1)*DiracDelta(x - 1)) + 2*Heaviside(-x - 1) + 2*Heaviside(x - 1))/x
Is there a way to somehow tell Sympy to simplify DiracDelta(x - a)*f(x) to DiracDelta(x - a)*f(a)?
Piecewise-defined functions are implemented by Piecewise class. Your function would be expressed as
V = sympy.Piecewise((1 + 2*sympy.log(-x), x < -1),
(x**2, x < 1),
(1 + 2*sympy.log(x), True))
print(V.diff(x))
which prints Piecewise((2/x, x < -1), (2*x, x < 1), (2/x, True))
The (expr, cond) pairs in Piecewise are processed in the order given: the first cond that evaluates to True (if the preceding evaluated to False) causes the corresponding expr to be returned.

How can i define my own ordering function to order expressions for print in sympy ?

I read this asmeurer's answer. He said that i can define a funtion to order my expression.How can i do that? I don't have enough reputation to comment in the answer.I want to make a function that sort the expression by symbol and it's degree like this:
...exp=m*x**3 + 3*m**2*x + x**2 + 1
...print(sort(exp,x))
m*x**3 + x**2 + 3*m**2*x + 1
...print(sort(exp,m))
3*x*m**2 + 3*x**3*m + x**2 + 1

I need some help shortening this regular expression

I currently try to get into regular expressions for school and have to work on the task to shorten this regular expression:
r = 0(e + 0 + 1)* + (e + 1)(1 + 0)* + e
with e being the empty word epsilon.
So far I got to this:
r = 0(0 + 1)* + 1(1 + 0)* + e
considering the rule
r* = (e + r)*
However, I don't really know how to continue. If it wasn't for the kleene star operators, I could use the distributive law, but that won't apply here. I can't really figure out a suitable law to continue on with this regex.
Any helpful tips?
Edit:
I think I got one step further by forming r to
r = 0(1 + 0)* + 1(1 + 0)* + e
and then being able to combine it to
r = (0 + 1)(0 + 1)* + e
Is that correct?
Also, we could then say
r = (0+1)*
which should be the final form
I'd say that your own deduction is correct except for one thing. Taking your original
r = 0(e + 0 + 1)* + (e + 1)(1 + 0)* + e
removing e which according to you is empty, leaves
r = 0(0 + 1)* + 1(1 + 0)*
or in plain words 0 followed by any number of 0 or 1 or 1 followed by any number of 1 or 0.
So the left side states that there has to be at least a 0 and the right side that there has to be a 1. That means that there must be at least a 0 or a 1. Now, your flavor of regex is one I've never seen so I don't know how to express one or more in your flavor (it's normally a +) so I'll express it in regular regex, which would be
r = [01]+
which simply means at least one0 or 1 repeated any number of times.
Regards.

what does + sign after variable mean?

what will be the output of following code
int x,a=3;
x=+ +a+ + +a+ + +5;
printf("%d %d",x,a);
ouput is: 11 3. I want to know how? and what does + sign after a means?
I think DrYap has it right.
x = + + a + + + a + + + 5;
is the same as:
x = + (+ a) + (+ (+ a)) + (+ (+ 5));
The key points here are:
1) c, c++ don't have + as a postfix operator, so we know we have to interpret it as a prefix
2) monadic + binds more tightly (is higher precedence) than dyadic +
Funny isn't it ? If these were - signs it wouldn't look so strange. Monadic +/- is just a leading sign, or to put it another way, "+x" is the same as "0+x".
The + after a just gets seen as a + before the next value. If you use consistent spacing it is the same as:
x = + + a + + + a + + + 5;
But not all the +s are necessary so it will act the same as doing:
x = a + a + 5;
The value of a is unchanged because you have never used the incrementing operator which is ++ with no white space between the two + symbols. + and ++ are two separate operators.
Since the + operators are never two next to each other but always separated by a white space the statement
x=+ +a+ + +a+ + +5; is actually read as
x=+ (nothing)+a+(nothing) +(nothing) +a+(nothing) +(nothing) +5;
so basically the final equation becomes of the sort
x=a+a+5; and hence the result.
The code seems to be equivalent to:
x= (+(+(a)))+ (+ (+(a)))+ (+(+(5)));
I.e. x = a + a + 5. Which is 11. You know that you can put + or - sign before number, right? Now those + merely indicate sign of variable. Since sign is +, variable remains unchanged I.e. "+5" means "5", so "+a" means "a", and "+ +a" means "+(+a)" which means "a". In same fashion you could write x = + + + 3 + + + + 3 + + + + 5. Or x = - + + - 3 + - + - 3 - - + 5;.
x=+ +a+ + +a+ + +5 : This is equivalent to
x = x=+ +a+ + +a+ + +5 or
we can write it as x = + (+ a) + (+ (+ a)) + (+ (+ 5))
and the +'s are only indicating the signs which will be finally evaluated as
x = a + a + 5.