Does Mathematica have a built-in tool that allows one to operate on both sides of an equation?

Geogebra has a very neat CAS view that allows one to solve an equation step by step in the following fashion:

$\quad \quad \quad \quad \quad \quad \quad \quad \quad$

You type an equation and can then apply operations to both sides of the equation, as shown in step 2. Does Mathematica have some built in functionality that allows the user to do the same? It's possible to program something to do it, but I'd like to know if Mathematica already has this feature. The help section on equation manipulation does not contain information about this.

• A start: Thread[(3 x + 8 == 16)/16, Equal] – J. M.'s technical difficulties Jun 26 '15 at 5:05
• Or eqn=3x+8==16; Map[1/16*#&,eqn], or Distribute[1/16 eqn,Equal] – Jens Jun 26 '15 at 5:06
• In Maple, all this works out of the box as is. I always wondered why in Mathematica these things are so much harder. Here is screen shot from my Maple session now !Mathematica graphics (ofcourse, there are things that are much harder to do in Maple than in Mathematica as well) – Nasser Jun 26 '15 at 22:41
• Per Nasser's 2017 answer below, there are now (as of v. 11.3) built-in commands for this like ApplySides[], likely making many of the other answers obsolete. – Jess Riedel Sep 25 '19 at 2:33

Working off of m_goldberg's idea, we can make it look a little nicer by using $Pre and $PrePrint to make equations behave as lists but still display as equations:

CASViewOn[] := (
$Pre = If[Head[#] === Equal, List @@ #, #] &;$PrePrint = If[Head[#] === List, Equal @@ #, #] &;
);
CASViewOff[] := (
$Pre =.;$PrePrint =.;
);


Now we can do

CASViewOn[]

3 x + 8 == 16

8 + 3 x == 16

% - 8

3 x == 8

%/3

x == 8/3

CASViewOff[]


Here's another way: write the equations using an undefined operator like DotEqual (entered with esc.=esc) and then define the threading behavior that we want.

Define automatic threading for arithmetic operations with

DotEqual /: ((f : Plus | Times | Divide | Power)[x___, DotEqual[y__], z___]) :=
DotEqual @@ f @@ ({x, {y}, z} /. DotEqual -> List)


Now we can do

3 x^2 + 1 ≐ 5

1 + 3 x^2 ≐ 5

% - 1

3 x^2 ≐ 4

%/3

x^2 ≐ 4/3

Sqrt[%] // PowerExpand

x ≐ 2/Sqrt[3]


Also we can add or multiply by another equation:

% + (2 y - x ≐ 0)

2 y ≐ 2/Sqrt[3]


Convert to a regular equation with

% /. DotEqual -> Equal

2 y == 2/Sqrt[3]


Yes, it has. This is your example equation:

    eq1 = 3 x + 8 == 16

(*  8 + 3 x == 16  *)


Here is its TreeForm:

TreeForm[eq1]


As you see, there are two elements on the first level:

    eq1[[1]]
eq1[[2]]

(*  8 + 3 x

16   *)


which are the left- and right-hand parts of the equation. Any equation in Mma has such a form, that is, left- and right-hand parts as the only elements in the first level. In order to apply an operation to the both parts of this equation one needs, therefore, to map this operation onto the equation like the following: Map[OperationInQuestion, eq1]. The peculiarity is that all the operations we might want to map are dyadic operations, that is the operator has two arguments. To handle this one needs to use the "slot-ampersand" (#-&) notation. For example, if we need to multiply the both sides of the equation by the same factor, factor we need to use the Times[#,factor]& operator of multiplication. The whole operator acting on the equation will have the form Map[Times[#,factor]&, equation].

Let us now turn to your example equation eq1, and I will demonstrate how all this works. Let us first divide the both parts of eq1 by 16:

 eq2 = Map[Expand[Divide[#, 16]] &, eq1]

(* 1/2 + (3 x)/16 == 1  *)


I also wraped it by Expandjust to open the parentheses. Let us now add -1/2 to the both parts:

 eq3 = Map[Plus[#, -1/2] &, eq2]

(*  (3 x)/16 == 1/2  *)


Let us now divide it by 3/16:

    eq4 = Map[Divide[#, 3/16] &, eq3]

(*   x == 8/3   *)


Like this one may treat any equation.

Have fun!

• Frankly, I would write eq2 = Map[Expand[Divide[#, 16]] &, eq1] in practice as eq2 = Expand[#/16] & /@ eq1. Was there a specific (non-educational) point in writing Divide and Plus explicitly? – kirma Jun 27 '15 at 6:13
• agree @kirma, I was kind of surprised by the code above myself... I wouldn't even bother with Expand, I'd just use eq2 = #/16 & /@ eq1 – user11734 Jun 27 '15 at 21:48
• @vaxquis Well, that is up to you. After some (rather short) it will become obvious. I would like to point out that such step-by-step operating on expressions (and not oly equations) I use not for teaching purpose at all. Using these as well as others tricks (not shown in my answer) I make my calculations in theoretical physics. Very efficient too. – Alexei Boulbitch Jun 28 '15 at 8:43
• @AlexeiBoulbitch Yes, my point was that although full forms are correct and identical to short forms, it is pretty unlikely a seasoned user would write Plus or Divide explicitly (otherwise than as a demonstration) on these cases. Maybe I'm just a bit too nit-picky... :) – kirma Jun 28 '15 at 9:36
• @kirma: you're not nit-picky; I've had this problem with some students, taught the "schooly" way of full expressions, for loops, unpure functions etc. When shown a real Mathematica code, with actual operator usage, they would tilt their heads and say "WTF is that? How does that even work? ..." - even more, they would rewrite each and every line of the code to their "understandable" form, replacing eg. ∫ with Integrate[], π symbol with Pi, every /@ with for loop over the array index... I see those "Wittgenstein's ladders" a severe teaching/learning obstacle. – user11734 Jun 28 '15 at 13:10

I usually find it easier to do this kind of manual equation munging by first converting the equation to a list, carrying out the operations on the list (convenient because math operations thread over lists), and then converting back to an equation when done.

Example

List @@ (3 x + 8 == 16)


{8 + 3 x, 16}

% - 8

{3 x, 8}

%/3

{x, 8/3}

Equal @@ %

x == 8/3

• changing the heads to simplify the operations to the bare minimum... just brilliant! – user11734 Jun 27 '15 at 21:52
• @m_goldberg I agree, I also often use this trick. There are, however, two different situations: (1) when without transforming to the list the operation cannot be done, and (2) when one can do the same either with or without going to a list. The first case arises, if Mma might make an undesireble simplification of terms in the course of transformation. In such a case the list form prevents it. – Alexei Boulbitch Jun 28 '15 at 8:53
• @m_goldberg I discovered this page and tried your command List @@ 3 x + 8 == 16, but Mathematica (10.3.0.0 on Mac OS X 10.11.1) returned *8 + 3x == 16. Has something changed? Also, I am searching for a page in Mathematica Stack Exchange that shows how to do a variety of manipulations like these. If you are familiar with the location, can you add a comment with the link? Thanks. – David Dec 13 '15 at 4:29
• @m_goldberg Aha. This worked: List @@ (3 x + 8 == 16). – David Dec 13 '15 at 4:31
• @David. Yes, you found a bug in my answer. I omitted the parentheses. Thanks for pointing it out. I will correct the answer. – m_goldberg Dec 13 '15 at 4:34

This is interesting. I just happened to see the Wolfram design video for 11.3 features, posted here https://www.twitch.tv/videos/207012986 and starting at 45:05, there is almost 30 minutes discussion on new functions just to work on both sides of equations and inequalities. I happened to have screen shots of these new commands (taken from the video, so they might not be too clear). There are basically 5 new commands

AddSides, SubtraceSides, MultiplySides, DivideSides, ApplySides

Some usage examples by Wolfram

This is an example using these function to complete the squares in the help

It all looks very useful. We have to wait for 11.3 to see them. I hope they will be all there.

EqualThread, MathSource 0209-124 has been fulfilling that need for me since the 90's. I put it in my Init file.

<< EqualThread.m

eq = 3 x + 8 == 16;

eq/6 // Apart
(* x/2+4/3==8/3 *)

eq - 8
(* 3 x==8 *)

Log[(eq - 8)/3]
(* Log[x] == Log[8/3] *)
`

etc. It seems to work in all MMa versions.

I don't know why Wolfram did not build it into the Kernel. Maybe they found problems, but it has always worked for me.