6
$\begingroup$

For example, given: x + 2 x y - x y + y I need to put it in this form: x (1 + 2 y) - y (x - 1).

But Mathematica will simplify (automatically) x + 2 x y - x y + y -> x + x y + y and I will not be able to group this expression as I need (I need to factor (1 + 2 y)).

The main question is how to prevent Mathematica simplifying, or how to factor out x (1 + 2 y) from this expression: x + x y + y?

Alternatively, how to put x + x y + y into x (1 + 2 y) - y (x - 1)?

$\endgroup$

3 Answers 3

7
$\begingroup$

You raise a very good question. One way to do that is as follows. Let us hold for a moment a part of your expression:

expr1 = Hold[x + 2 x*y] - x*y + y;

Now one may apply Collect to it to extract y out of parentheses in the part that is not held, and after that release hold:

expr2 = Collect[expr1, y] // ReleaseHold

The result is here:

(* x + (1 - x) y + 2 x y *)

Now we need to protect the expression (1 - x) y from simplification with the rest of expression. This term is second:

expr2[[2]]
    (* (1 - x) y *)

We can map Hold onto it, Collect terms ~x and finally release hold:

expr3 = Collect[MapAt[Hold, expr2, {2}], x] // ReleaseHold

That is the result:

(*  (1 - x) y + x (1 + 2 y) *)

However, there is a subpackage "Manipulations" of the package "Presentations" to be used as the Mathematica add-on of David Park that does such things easier. Check here: http://home.comcast.net/~djmpark/index.html

To address your question placed in the comment. These expressions I will use several times:

Clear[expr1, expr2, expr3, expr4, expr3A, expr3B, expr4A, expr4B, 
  expr5, expr5A, expr5B];

Assume we have the expression you are asking about:

expr1 = x + x*y + y;

and we know that we want to represent it in the form: (1-x)y+x(1+2 y). All this only has sense, if this expression is a part of some more complex expression, and we want to operate it completely on-screen without going to the paper. If it is a self-standing expression, as simple as expr1, it is, of course, more easy to retype it in the final form.

So, let us start. There are several ways.

  1. Using Hold-Collect approach

This makes the expression like the one you want, but prevents Mathematica to simplify it:

expr2 = expr1 + x*y - Hold[x*y]

The results is:

(*  x + y + 2 x y - Hold[x y] *)

Then you can factor the part that is not held by application Collect to the whole expression:

expr3 = Collect[expr2, x] // ReleaseHold

the result is:

(*  y - x y + x (1 + 2 y)     *)

Like that we factored one part of the expression, and released the held part. Now we can hold the already factored part and then factor the rest (as in the previous example):

expr4 = MapAt[Hold, expr3, {3}]
expr5 = Collect[expr4, y] // ReleaseHold

The result is

(* y - x y + Hold[x (1 + 2 y)] ) ( (1 - x) y + x (1 + 2 y) *)

  1. Using rules

    Clear[expr1, expr2, expr3, expr4, expr3A, expr3B, expr4A, expr4B, expr5, expr5A, expr5B];

    expr1 = x + x*y + y;

    expr2 = expr1 /. x + x*y + z__ -> Hold[x + 2*x*y] - x*y + z

(I ma sorry, I tried hard to transform few lines above into a code, but it does not work)

Like this we effectively add and subtract the term x*y to the expression. The result is:

(*  y - x y + Hold[x + 2 x y]  *)

expr3 = Collect[expr2, y] // ReleaseHold
(*  x + (1 - x) y + 2 x y  *) 

Now we have two possible ways. The way a) is to follow the rule-based approach:

expr4A = expr3 /. x + 2 x*y + z__ -> x (1 + 2 y) + z

The result is:

(*  (1 - x) y + x (1 + 2 y)  *)

Done.

The way b) is to further follow the Hold-Collect approach:

expr3 = Collect[expr2, y] // ReleaseHold
(*  x + (1 - x) y + 2 x y  *)

and

expr4A = Collect[MapAt[Hold, expr3, {2}], x] // ReleaseHold

(*   (1 - x) y + x (1 + 2 y)   *)

Done.

3) The list-based approach. The idea is to first transform your expression into list. The list terms will not be simplified without your permission. You operate this list, and later transform it back to a sum.

Clear[expr1, expr2, expr3, expr4, expr3A, expr3B, expr4A, expr4B, 
  expr5, expr5A, expr5B];

expr1 = x + x*y + y;

The following transforms the expression into a list:

expr2 = List @@ expr1
(* {x, y, x y} *)

Now we need to effectively add and subtract the term x*y. Let us insert -x*y close to the first term, x, and x*y as a last term, x*y, so that later it is more convenient to group terms x with -x*y and y with x*y and another x*y:

expr3 = Insert[Insert[expr2, -x*y, {2}], x*y, {5}]
    (*  {x, -x y, y, x y, x y}  *)

Now we can take the terms which will become the sub-expressions in question and can operate them separately:

expr4A = Take[expr3, 2]
expr4B = Take[expr3, -3]
(*  {x, -x y}  *)
(*   {y, x y, x y}  *)

Now we can transform each of them into sums, and then factorize them. In this case one may equally factorize either with Collect or with Factor. Let us do it with Factor:

expr5A = Plus @@ expr4A // Factor
expr5B = Plus @@ expr4B // Factor
(*  -x (-1 + y)  *)
(*  (1 + 2 x) y  *)

Now we already almost have it. The problem is now to add one to another and to avoid simplification. Here again Hold may be used:

expr6 = (Hold@expr5A + Hold@expr5B) // ReleaseHold
(*  x (1 - y) + (1 + 2 x) y  *)

Done.

Just to conclude, there are probably other approaches, I just gave those that immediately came into head. These operations seem a bit cumbersome at the first glance, but I know by experience, that when doing complex and long analytical calculations it pays off, since you avoid small but malignant errors, like forgotten minuses, or extra factors 2 and alike. Have fun!

$\endgroup$
3
  • $\begingroup$ thank you, a very nice solution to use Hold[], but what if I do not know a priori, where should I put "Hold[]"? In my real problem, I have already "simplified" (like x+xy+y) expression, but I need to extract some particular factor (1+2y). Is it possible to apply Hold[] on the entire expression to get this? (I'm going to check it and post my result) $\endgroup$ Commented Jun 6, 2013 at 12:24
  • $\begingroup$ I will look at "Manipulations" package. Thanks! $\endgroup$ Commented Jun 6, 2013 at 12:31
  • $\begingroup$ @Andrew Kor "...what if I do not know a priori, where should I put "Hold[]"?" Then you do it by trail and error. In general you put Hold on at least one item which takes part in the simplification. As soon as you did it, simplification cannot take place any more. Please find the example in the section "Using Hold-Collect approach" of my answer above. $\endgroup$ Commented Jun 7, 2013 at 7:06
4
$\begingroup$

I wonder whether this is a special case or this is an example of a large class of similar problems. If the latter, then there is not a unique way to decompose x^2 + x y + y^2 into a (1 + 2y) + b (x - 1) -- or perhaps the desired form is `a (1 + 2y) + b y.

But if the problem is to get the particular expression x (1 + 2 y) out of x^2 + x y + y^2, then the easiest way I can imagine is

Factor[(x + x y + y) - x (1 + 2 y)] + x (1 + 2 y)
-(-1 + x) y + x (1 + 2 y)

(Or possibly

Expand[x + x y + y - x (1 + 2 y)] + x (1 + 2 y)
 y - x y + x (1 + 2 y)

which is not quite the same as the indicated answer in the question.)


If the question is more general, the following will decompose a polynomial into the form a (1 + 2y) + b (x - 1), unless a and b are 0, 1 or -1. The example below show two more ways to get 1 + 2y "factored out" of the polynomial. Note that Last[%] below is 0, which indicates that there was no remainder, and may be omitted. But one should check that the remainder is 0.

basis = {x - 1, 1 + 2 y}
PolynomialReduce[x + x y + y, basis, {x, y}]
First[%] . basis + Last[%]
{{1 + y, 1}, 0}
1 + 2 y + (-1 + x) (1 + y)

Or

basis = {1 + 2 y, x - 1};
PolynomialReduce[x + x y + y, basis, {x, y}]
First[%].basis + Last[%]
{{1/2 + x/2, 1/2}, 0}
1/2 (-1 + x) + (1/2 + x/2) (1 + 2 y)

One can also keep the terms separated in a List. Then they won't combine if a and b happen to be 0, 1, or -1.

basis = {x - 1, 1 + 2 y}
PolynomialReduce[x + x y + y, basis, {x, y}]
First[%] basis
{{1 + y, 1}, 0}
{(-1 + x) (1 + y), 1 + 2 y}
$\endgroup$
3
  • $\begingroup$ +1 PolynomialReduce is nailed. But does OP a priori knows the x - 1 part in the basis? $\endgroup$
    – Silvia
    Commented Jan 28, 2014 at 3:06
  • $\begingroup$ I think I understood the OP to state that in the first sentence - it was over seven months ago. If not, then basis = GroebnerBasis[{x + 2 x y - x y + y, 1 + 2 y}, {x, y}] does the same thing. $\endgroup$
    – Michael E2
    Commented Jan 28, 2014 at 3:56
  • $\begingroup$ Ahh.. didn't notice the time. Was brought here by the flag on chao's answer... Anyway +1. $\endgroup$
    – Silvia
    Commented Jan 28, 2014 at 4:24
0
$\begingroup$

it's really easy with mathematica :)

Mathematica Expression forms

and for the first problem why not entering it as this form x(1+2y)-y(x-1) from begining then mathematica won't substract it.

$\endgroup$
2
  • $\begingroup$ Ghaffarian Shira, I do not have this x(1+2y)-y(x-1) expression at all. In the beginning I have some very huge expression and when I want to ExpandAll[], Mathematica during this process combines all similar terms. So I do not pass through the step when "x(1+2y)-y(x-1)" is available. I already see the "final" x+xy+y result. So my question is how to stop doing this automatic simplification or how to extract the factor (1+2y) from "simplified" x+xy+y expression. Could you please show me how "it's really easy with mathematica :)"? $\endgroup$ Commented Jun 6, 2013 at 12:31
  • $\begingroup$ i think you already have the answer. Hold pauses combining. Could you please show me how "it's really easy with mathematica :)"? it was in the link below complete mathematica tutorial, on expression forms. $\endgroup$ Commented Jun 9, 2013 at 17:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.