Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to evaluate parts of an expression, but not other parts?

44 views
Skip to first unread message

Julian Francis

unread,
Nov 5, 2011, 5:46:17 AM11/5/11
to
Dear all,

I'd like to use the TreePlot function to visualise the expression of a
dynamic programming problem I am working on.

If I have something like: ( (a+b) + (c+d )

Mathematica helpfully simplifies this to: a + b + c + d

But I'd prefer it to be in the original form.

I can't write Hold[ ( (a+b) + (c+d) )] because I do want a,b,c & d to
be evaluated.

I want to write something like:
Hold[ ( (Evaluate[a]+Evaluate[b]) + (Evaluate[c]+Evaluate[d]) ) ]

But this just leaves the Evaluate expressions unevaluated.

Any help greatly appreciated.

Thanks,
Julian.

Bob Hanlon

unread,
Nov 6, 2011, 5:58:20 AM11/6/11
to
a = f[x];
b = g[x];
c = 2 f[x];
d = f[x] + 3 g[x];

expr = Hold[((a + b) + (c + d))];

ReplacePart[expr, {
Position[expr, Literal[a]] -> a,
Position[expr, Literal[b]] -> b,
Position[expr, Literal[c]] -> c,
Position[expr, Literal[d]] -> d}]

Hold[(f[x] + g[x]) + (2 f[x] + (f[x] + 3 g[x]))]


Bob Hanlon

Andrzej Kozlowski

unread,
Nov 6, 2011, 6:00:24 AM11/6/11
to

On 5 Nov 2011, at 10:45, Julian Francis wrote:

> Dear all,
>
> I'd like to use the TreePlot function to visualise the expression of a
> dynamic programming problem I am working on.
>
> If I have something like: ( (a+b) + (c+d )
>
> Mathematica helpfully simplifies this to: a + b + c + d
>
> But I'd prefer it to be in the original form.
>
> I can't write Hold[ ( (a+b) + (c+d) )] because I do want a,b,c & d to
> be evaluated.
>
> I want to write something like:
> Hold[ ( (Evaluate[a]+Evaluate[b]) + (Evaluate[c]+Evaluate[d]) ) ]
>
> But this just leaves the Evaluate expressions unevaluated.
>
> Any help greatly appreciated.
>
> Thanks,
> Julian.
>


Well, there may be a simpler way, but here is one that comes to my mind:

a = x; b = y; c = z; d = w;

HoldForm @@ Apply[Hold, Hold[(a + b) + (c + d)], {2}] /. p_Hold :> With[{w = Plus @@ p}, w /; True]

HoldForm[(x + y) + (w + z)]

Andrzej Kozlowski=

Andrzej Kozlowski

unread,
Nov 6, 2011, 6:00:54 AM11/6/11
to
A slightly simpler way (using the same idea) is:


HoldForm[Hold[a + b] + Hold[c + d]] /. p_Hold :> With[{w = Plus @@ p}, w /; True]

Silvia

unread,
Nov 6, 2011, 6:01:25 AM11/6/11
to
maybe you can use a Rule list to replace a, b, c, d outside the HoldForm. e.g.

HoldForm[(a + b) + (c + d)] /. {a -> Sin[Pi/4]}

David Park

unread,
Nov 6, 2011, 6:02:26 AM11/6/11
to
I'm sure that you will obtain some answers to do this with plain
Mathematica, but the Presentations package does have routines that allow
selective manipulation of expressions.

Along with HoldForm your can use EvaluateAt or EvaluateAtPattern to do
selective evaluations of held expressions. You can also use
CreateSubexpression, OperateSubexlression and ReleaseSubexpressions to tag
and group things together to prevent Mathematica from mixing there elements
with other elements outside the subexpressions. Tagged Subexpressions also
show the tag in a tooltip when the mouse hovers over the Subexpression. We
also have MapLevelParts that allows an operation to be performed on selected
level parts in an expression (usually a sum, product or list).

So, as a simple example we could do:

<<Presentations`

a = 1; b = 2; c = 3; d = 4;
HoldForm[a + b] + HoldForm[c + d]
% // EvaluateAt[{1, 1}]
% // EvaluateAt[{2, 1}]
% // ReleaseHold

(a+b)+(c+d)

3+(c+d)

3+7

10

Using tagged Subexpressions we could do the following. We can also specify
that a subexpression should always show parentheses.

a = 1; b = 2; c = 3; d = 4;
CreateSubexpression[HoldForm[a + b], True, tag1] +
CreateSubexpression[HoldForm[c + d], True, tag2]
% // OperateSubexpression[ReleaseHold, tag1]
% // OperateSubexpression[ReleaseHold, tag2]
% // ReleaseSubexpressions[All]

(a+b)+(c+d)

(3)+(c+d)

(3)+(7)

10

If we want to show the individual values before they are combined in a
Subexpression we could use nested Subexpressions and the following more
complicated construction.

Clear[a, b, c, d]
step1 = Plus @@
MapThread[
CreateSubexpression[#1, #2] &, {HoldForm /@ {a, b, c, d}, {taga,
tagb, tagc, tagd}}]
a = 1; b = 2; c = 3; d = 4;
step2 = step1 //
MapLevelParts[CreateSubexpression[#, tagcd] &, {{3, 4}}];
step3 = step2 //
MapLevelParts[CreateSubexpression[#, tagab] &, {{1, 2}}]
step4 = Fold[OperateSubexpression[ReleaseHold, #2][#1] &,
step3, {taga, tagb, tagc, tagd}]
step5 = Fold[ReleaseSubexpressions[#2][#1] &,
step4, {taga, tagb, tagc, tagd}]
FixedPoint[ReleaseSubexpressions[All], step5]

(a)+(b)+(c)+(d)

((a)+(b))+((c)+(d))

((1)+(2))+((3)+(4))

(3)+(7)

10


David Park
djm...@comcast.net
http://home.comcast.net/~djmpark/

Rui

unread,
Nov 7, 2011, 5:52:13 AM11/7/11
to
What about

ReleaseHold[
Hold[(a + b) + (c + d)] /.
i_Symbol /; Context[i] === "System`" :> Hold[i]]

or maybe

ReleaseHold[
Hold[(a + b) + (c + d)] /.
i_Symbol /; Context[i] =!= "Global`" :> Hold[i]]

andre.robin3

unread,
Nov 7, 2011, 5:51:12 AM11/7/11
to
EvaluateAt[] is not part of Mathematica.

So far I kown it was a idea from Villegas (from Wolfram, see his
presentation
"workingwith unevaluated expression". It is not for beginners).
Ted Ersek also has developped a EvaluateAt[].

For such a problem I suggest rather to try to use Mathematica
existing functions. (there are so many !)



"David Park" <djm...@comcast.net> a écrit dans le message de news:
j95pg2$m87$1...@smc.vnet.net...

Alexey Popkov

unread,
Nov 8, 2011, 7:14:43 AM11/8/11
to
Hi Julian,

Please see strongly related thread on Stack Overflow:

http://stackoverflow.com/questions/6633236/replace-inside-held-expression

Two techniques are presented and discussed there:

1) The Trott-Strzebonski in-place evaluation technique

http://library.wolfram.com/conferences/devconf99/villegas/UnevaluatedExpressions/Links/index_lnk_30.html

2) An undocumented, but very convenient, way to make replacements in
held expressions using RuleCondition:

In[3]:= Hold[{1, 2, 3, 4, 5}] /. n_Integer :> RuleCondition[n^2,
OddQ[n]]
Out[3]= Hold[{1, 2, 9, 4, 25}]

HTH,
Alexey

Andrzej Kozlowski

unread,
Nov 8, 2011, 7:15:14 AM11/8/11
to
It is called the Strzebonski-Trott (or Trott-Strzebonski) trick - after
the people who first noticed it (or at least made it public). Villegas
just reported it (with proper credit).

Andrzej Kozlowski


On 7 Nov 2011, at 11:50, andre.robin3 wrote:

> EvaluateAt[] is not part of Mathematica.
>
> So far I kown it was a idea from Villegas (from Wolfram, see his
> presentation
> "workingwith unevaluated expression". It is not for beginners).
> Ted Ersek also has developped a EvaluateAt[].
>
> For such a problem I suggest rather to try to use Mathematica
> existing functions. (there are so many !)
>
>
>
> "David Park" <djm...@comcast.net> a =E9crit dans le message de news:
> j95pg2$m87$1...@smc.vnet.net...

andre.robin3

unread,
Nov 8, 2011, 7:20:51 AM11/8/11
to
sorry, I didn't saw the introducing text in the mail from David Park
yesterday.
All is OK.

"andre.robin3" <andre....@wanadoo.fr> a écrit dans le message de news:
j98d70$3ka$1...@smc.vnet.net...

Julian Francis

unread,
Nov 9, 2011, 6:41:52 AM11/9/11
to
Thank you all for your suggestions.

I have just realised I can probably get the effect I am looking for by
just not using the built in Mathematica Plus function. If I call the
function MyPlus instead,
then MyPlus[ MyPlus[a,b] , MyPlus[c,d] ] does the evaluation for
a,b,c,d but doesn't try to combine the MyPlus's together. Not
surprisingly as it can't presumably
without any other definitions.

I think it's pretty simple, and does what I want.

I will have a look at some of your other Hold solutions (just in case
I want to use this elsewhere to actually evaluate whole expressions
and do want the Plus's to be evaluated).

Once again, thank you all.

Kind regards,
Julian.

0 new messages