# Is there a way to simplify a symbolic expression at assignment, once-for-all?

I have a series of symbolic function calls that could be greatly simplified using some assumptions. I think I would like for these assumptions to be used in the definition of the function so that they would propagate downward through my notebook.

There are two main ways to apply assumptions.

Case 1: Apply assumptions and simplify when defining a function.

f1[x_] := Simplify[Sqrt[x^2],x>0];
g1[x_] := Simplify[f1[x]^3 + f1[x]^2,x>0];
g1[a]


Case 2: Apply assumptions and simplify only when evaluating a function.

f2[x_] := Sqrt[x^2];
g2[x_] := f2[x]^3+f2[x]^2;
Simplify[g2[a],a>0]


In both cases, the result is a^3+a^2, and I suspect that for this simple example, there is no functional difference between simplifying at function definition (Case 1) or at evaluation (Case 2). However, in far more complex symbolic functions that call other complex symbolic functions, and where these functions are called many times, I can imagine there being a difference.

I would expect that if an expression could be simplified as early as possible (Case 1), it would reduce the amount of simplification that would need to be done later. However, I am concerned that the := assignment would cause the Simplify[] to happen repeatedly down the road. Here's what I am afraid of in Case 1:

 Simplify[Simplify[Sqrt[x],x>0]^3 + Simplify[Sqrt[x],x>0]^2,x>0];


I'm also worried that if I were to call Simplify[] at some final evaluation (Case 2), the expression would be too complicated and ugly for Mathematica to handle in a human timeframe—at least for the expressions I am working with.

One inelegant solution to this would be to manually set the variables, as in the following , which we may as well call Case 3:

In[1]
Simplify[Sqrt[x^2],x>0]

Out[1]
x

In[2]    (* Manually copy the results of Out[1] to a new function definition in In[2] *)
f3[x_]:= x;
Simplify[f1[x]^3 + f1[x]^2,x>0]

Out[2]
x^3 + x^2

In[3]    (* Manually copy the results of Out[2] to a new function definition in In[3] *)
g3[x_]:= x^3 + x^2;
g3[a]


The questions:

• Is there a way to tell Mathematica to simplify early, once-for-all, without it calling Simplify[] redundantly?
• Is it better to simplify early or not? If not, why?
• When one defines a function as in Case 1, does the Simplify[] get called every time?
• In your example you might just as well use a direct (not delayed) definition , f1[x_] = Simplify[Sqrt[x^2],x>0]. This question would be improved (for future reference ) if you could think up an example where Simplify does something useful, yet the function requires a delayed definition. – george2079 Mar 9 '15 at 19:51

You can use Evaluate to "force evaluation of the right-hand side of a delayed definition" (as stated in its documentation).
For example

f[x_] := Simplify[Sqrt[x^2], x > 0]
Definition@f

f[x_] := Simplify[Sqrt[x^2], x > 0]

g[x_] := Evaluate@Simplify[Sqrt[x^2], x > 0]
Definition@g

g[x_] := x

• Awesome! Thanks! – jvriesem Mar 9 '15 at 19:38
• This solution works effectively as Set. You can use = instead of := then, if you like it drawbacks(if you had x defined in previous statements, for example (x=3), than you'll have g[x_]:= 3 – Vladimir Mar 10 '15 at 8:54
• Thanks @Vladimir. That's actually what I was thinking of initially: using the standard assignment operator =. I was afraid that it wouldn't allow a symbolic function to remain symbolic somehow. If I don't set x=3, but only use g[x_]=x, will it always work? – jvriesem Mar 10 '15 at 17:27
• @jvriesem Yes, but I would rather recommend Block[{x},g[x_]=x], which stores old x value, temporarily unsets it, and then after right bracket resets the old value to x. Just to be sure! – Vladimir Mar 12 '15 at 1:09
• @jvriesem Yes, not set or set to a value only for the code in its second argument. You can find more details and examples in this tutorial. – Karsten 7. Mar 16 '15 at 20:07