5
$\begingroup$

Documentation states

A negative level -n consists of all parts of expr with depth n.

However, it is not clear what do level specifications {m, n} with negative m or n mean.

I made several guesses, like

{-m, n} means “in all subexpressions of depth m, all subexpressions on levels n or before”

that were disproven by counterexamples (e.g., Level[h[1, h[2, h[3]]], {-2, 2}] does not incude 3) but I don't think I should have been guessing in the first place. Still, documentation does not provide an exhaustive set of examples on this.

The question is,

How should levelspecs {m, -n}, {-m, n}, {-m, -n} be interpreted, in English?

P.S. I included tag “list-manipulation” only because it was the one used in this question. No existing tag actually looks appropriate.

$\endgroup$
  • $\begingroup$ I don't think that this question is a duplicate of that question because as the OP stresses, this question specifically addresses negative levelspec ranges, not the basic concept of levels. $\endgroup$ – Alexey Popkov May 31 '15 at 0:07
3
$\begingroup$

Here is my trial:

  1. The levelspec {2, -2} means "all subexpressions which can be specified by at least 2 indices down to subexpressions with depth not lesser than 2". In the expression a[1, b[2, c[3]]] we have only three subexpressions which can be extracted by using two indices:

    Level[a[1, b[2, c[3]]], {2}, Heads -> True]
    
    {b, 2, c[3]}
    

    These indices are {2, 0}, {2, 1}, {2, 2} correspondingly:

    Extract[a[1, b[2, c[3]]], {{2, 0}, {2, 1}, {2, 2}}]
    
    {b, 2, c[3]}
    

    There are only 2 subexpressions which can be specified using 3 indices:

    Level[a[1, b[2, c[3]]], {3}, Heads -> True]
    
    {c, 3}
    

    Both these subexpressions have depth 1:

    Depth /@ {c, 3}
    
    {1, 1}
    

    So these subexpressions will not be included when the minimal depth is 2. The only subexpression which can be specified by using at least 2 indices and which has depth not lesser than 2 is c[3]:

    Level[a[1, b[2, c[3]]], {2, -2}, Heads -> True]
    
    {c[3]}
    

    If we add a deeper level, it will be also included:

    Level[a[1, b[2, c[3, d[4]]]], {2, -2}, Heads -> True]
    
    {d[4], c[3, d[4]]}
    
  2. In the levelspec {-2, 2} we should count from negative values up to positive, so it means all subexpressions which have depth mo more than 2 and which can be specified by using no more than 2 indices. Now both subexpressions with depth 1 (atomic) and 2 will be included:

    Level[a[1, b[2, c[3]]], {-2, 2}, Heads -> True]
    
    {a, 1, b, 2, c[3]}
    

    If we add a deeper level, we get only atomic subexpressions because now there is no subexpression with maximum depth 2 which can be specified by no more than 2 indices:

    Level[a[1, b[2, c[3, d[4]]]], {-2, 2}, Heads -> True]
    
    {a, 1, b, 2}
    

In the other words, in the levelspec {-2, 2} we have minimum negative levelspec specified as -2 (which means that depth more than 2 is not allowed) and maximum positive levelspec specified as 2 (which means that no more than 2 indices are allowed). Similarly, in the levelspec {2, -2} we have minimum positive levelspec specified as 2 (i.e. not lesser than 2 indices) and maximum negative levelspect specified as -2 (i.e. depth not lesser than 2).

$\endgroup$
  • 1
    $\begingroup$ I see. In {-m, n} case, I counted the positive levelspec from the root of the (found) m-depth subexpressions, while I should have counted from the top of the original expression (or, equivalently, to put the “positive” restriction first, despite it being written second). To wrap it up: 1. {m, -n}: on levels ≥ m, all subexpressions of depth ≥ n 2. {-m, n}: on levels ≤ n, all subexpressions of depth ≤ m 3. {-m, -n}: all subexpressions with depth between n and m. NB: 1 and 2 hold for {0, -n} and {-m, 0}, respectively. $\endgroup$ – Akater May 31 '15 at 0:19
  • $\begingroup$ @Akater Well written, +1. $\endgroup$ – Alexey Popkov May 31 '15 at 0:25
0
$\begingroup$

The topic has probably been addressed before in this forum. Maybe these examples and the table here will help.

fTest = h[1, h[2, h[3]]];
Map[g, fTest, {2}]
Map[g, fTest, {2, -1}]

Level and position table

  • Some notes from the DC:

Level[expr,{-1}] gives a list of all "atomic" objects in expr.

A positive level n consists of all parts of expr specified by n indices.

A negative level -n consists of all parts of expr with depth n.

Level 0 corresponds to the whole expression.

With the option setting Heads->True, Level includes heads of expressions and their parts.

Level traverses expressions in depth-first order, so that the subexpressions in the final list are ordered lexicographically by their indices.

Understanding the relationships between Levels, Depth, Position and related topics is probably best done through experimentation and reading - which I'm sure you've done. I admit this is not the easiest topic understand. If interested I can provide code for the table presented above.

$\endgroup$
  • $\begingroup$ I don't see how this is relevant. The table doesn't even feature explicitly the ranged levelspec. If you understand negative ranges, how would you describe in words which parts of expr would g be mapped onto in Map[g, expr, {2, -1}]? $\endgroup$ – Akater May 30 '15 at 22:35

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.