9
$\begingroup$

For some expressions, TreeForm may grow very long. I'm only interested in the top levels of the expression. How can I get the tree form of only the first levels an expression?

For example: how to get the first levels of this expression in tree form?

Nest[1/(1 + #) (1 - #) &, w, 5]

TreeLevel of the above expression

$\endgroup$
0

5 Answers 5

7
$\begingroup$

Can use something like this:

ClearAll[showTopTree];
showTopTree[expr_, level_] :=
  Module[{myHold}, 
     SetAttributes[myHold, HoldAll];
     Function[code,
       TreeForm[Unevaluated@Unevaluated@code],
       HoldAll] @@
    (Hold[#] &@
      DeleteCases[MapAll[myHold, expr], _, {2*level, Infinity}] //.
           myHold[x__] :> x)];

Pretty ugly, but seems to work:

expr = Nest[1/(1 + #) (1 - #) &, w, 5]
Manipulate[showTopTree[expr, n], {n, 1, Depth[expr], 1}]

GraphicsGrid[Partition[showTopTree[expr, #] & /@ Range[6], 3]]

enter image description here

$\endgroup$
6
$\begingroup$

You can use the second argument of TreeForm to display and expression to a certain depth, so for your example you could do TreeForm[Nest[1/(1 + #) (1 - #) &, w, 5], 1] (although the result isn't very pretty in this case)

Mathematica graphics

Edit

Instead of using TreeForm you could also construct a graph of the expression using ExpressionTreePlot in the GraphUtilities` package and use that to extract the desired subtree.

Needs["GraphUtilities`"];
exprTree[expr_] :=
 Module[{g, edges, labels},
  g = ExpressionTreePlot[expr, Top];
  edges = Rule @@@ Cases[g, Line[a_] :> a, Infinity][[1]];
  labels = Cases[g, Text[a_, b_] :> (b -> a[[1, 1]]), Infinity];
  {edges, labels}]

subTree[expr_, d_, pos_: Top] := Module[{edges, labels, sub},
  {edges, labels} = exprTree[expr];
  sub = NeighborhoodSubgraph[edges, 1, d];
  TreePlot[sub, pos, VertexRenderingFunction ->
    Function[{p, v}, 
     Text[Framed[Style[v /. labels, FontSize -> 10], 
       Background -> Lighter[Gray, .8]], p]]]]

Example:

subTree[Nest[1/(1 + #) (1 - #) &, w, 5], 4]

Mathematica graphics

Here, I've chosen the style of VertexRenderingFunction in the definition of subTree to mimic the style of TreeForm but you could choose you own style for displaying the vertex labels.

$\endgroup$
3
$\begingroup$

The solutions seem a bit complicated. What about this one?

myTreeForm[expr_, dep_] := Map[Head, TreeForm[expr, dep], {dep + 1}];
a = Nest[1/(1 + #) (1 - #) &, w, 5];

myTreeForm[a, 1]
myTreeForm[a, 2]
myTreeForm[a, 3]

enter image description here

enter image description here

enter image description here

$\endgroup$
2
$\begingroup$
ClearAll[trimmedTree]
trimmedTree[expr_, level_, o : OptionsPattern[]] :=  Module[{
  g = GraphComputation`ExpressionGraph[expr, o, GraphStyle -> "DiagramGold" ], g2},
  g2 = SetProperty[g, VertexLabels -> (v_ :> 
     Placed[PropertyValue[{g, v}, VertexLabels] , Center])];
  VertexDelete[g2, _?(GraphDistance[g2, 1, #] > level &)]]

Examples:

trimmedTree[{{{a, b}, c}, d}, #, ImageSize -> 200] & /@ {1, 2, 3} // Row

enter image description here

trimmedTree[Nest[1/(1 + #) (1 - #) &, w, 5], #, 
   VertexSize->{"Scaled", .14}, ImageSize -> #2]&@@@{{1, 250},{2, 300},{3, 300}} // Row

enter image description here

$\endgroup$
0
2
$\begingroup$

Using the new-in-version-12.1 function ExpressionGraph you can trim the expression tree using the second argument:

  • ExpressionGraph[expr, n] gives the tree graph only down to level n.

Example:

expr = Nest[1/(1 + #) (1 - #) &, w, 5];

ExpressionGraph[expr, 4,  VertexLabels -> Placed[Automatic, Below], ImageSize -> Large]

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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