Special trees and special methods

Contents

This is a bit of an interlude. We list here the methods that generate trees and in a particular way that do not fit with the rest of the tutorial.

We will use a subtree of the lineage tree as an example:

lineage = tree.example;
t = lineage.subtree(19);
disp(t.tostring)
                EMS                 
     +-----------+-----+            
     |                 |            
    MS                 E            
  +--+--+        +-----+-----+      
  |     |        |           |      
MS.a  MS.p      E.a         E.p     
              +--+--+     +--+--+   
              |     |     |     |   
            E.al  E.ar  E.pl  E.pr  

Special trees

There are a few special trees that can be generated from a mother tree. They will have the same structure, but have different content, reflecting some properties of the mother tree.

Actually, right now there is only one such tree, which is the depth tree. The depth tree simply holds the depth of each node. The depth itself is defined as the number of edges you must follow upward from the node to reach the root:

dt = t.depthtree;
disp(dt.tostring)
        0         
  +-----+--+      
  |        |      
  1        1      
 ++-+   +--+--+   
 |  |   |     |   
 2  2   2     2   
       ++-+  ++-+ 
       |  |  |  | 
       3  3  3  3 

Special methods

The methods we have seen in the Operators section of the tutorial just compute a result depending only on the "local" node. They do not take into account the tree structure, such as the node's parent and children.

One method does that: recursivecumfun. At each node, this method applies a function to all the children of a node, store the results there, and repeat recursively from bottom to top.

For instance, one way to compute the total number of children a node has (including itself) is the following:

ot = tree(t, 1); % Create a copy-tree filled with ones
nc = ot.recursivecumfun(@(x) sum(x) + 1);
disp( [ t.tostring nc.tostring ] )
                EMS                        11         
     +-----------+-----+              +-----+--+      
     |                 |              |        |      
    MS                 E              3        7      
  +--+--+        +-----+-----+       ++-+   +--+--+   
  |     |        |           |       |  |   |     |   
MS.a  MS.p      E.a         E.p      1  1   3     3   
              +--+--+     +--+--+          ++-+  ++-+ 
              |     |     |     |          |  |  |  | 
            E.al  E.ar  E.pl  E.pr         1  1  1  1 

Note that for this method, the resulting tree depends only on the structure of the input and of the content of its leaf nodes. The content of the other nodes is ignored by construction.

Condensing / decondensing a tree

Sometimes, I have trees where most of the nodes have only one child, with the exact same content. This happens for instance when you capture the life of a cell in several discrete frames. When the cell, observed in one frame, does not divide, I simply add a single node to the parent node, and resume. This can lead to trees that are like this:

t = tree('AB');
[t, index] = t.addnode(0, 'AB');
[t, index] = t.addnode(index, 'AB');
[t, index] = t.addnode(index, 'AB');

[t, ia] = t.addnode(index, 'ABa');
[t, ia] = t.addnode(ia, 'ABa');
[t, ia] = t.addnode(ia, 'ABa');
[t, ia] = t.addnode(ia, 'ABa');

[t, ib] = t.addnode(index, 'ABb');
[t, ib] = t.addnode(ib, 'ABb');
[t, ib] = t.addnode(ib, 'ABb');
[t, ib] = t.addnode(ib, 'ABb');
[t, ib] = t.addnode(ib, 'ABb');
[t, ib] = t.addnode(ib, 'ABb');

disp(t.tostring)
   AB     
          
    |     
   AB     
          
    |     
   AB     
  +-+--+  
  |    |  
 ABa  ABb 
  |    |  
  |    |  
 ABa  ABb 
  |    |  
  |    |  
 ABa  ABb 
  |    |  
  |    |  
 ABa  ABb 
       |  
       |  
      ABb 
       |  
       |  
      ABb 

Condensing allows to simplify the content tree, and extract the repetition length:

[vt, lt] = condense(t);
disp([ vt.tostring lt.tostring ])
   AB       3   
  +-+--+   ++-+ 
  |    |   |  | 
 ABa  ABb  4  6 

De-condensing is of course just the opposite:

nt = decondense(vt, lt);
disp(nt.tostring)
   AB     
          
    |     
   AB     
          
    |     
   AB     
  +-+--+  
  |    |  
 ABa  ABb 
  |    |  
  |    |  
 ABa  ABb 
  |    |  
  |    |  
 ABa  ABb 
  |    |  
  |    |  
 ABa  ABb 
       |  
       |  
      ABb 
       |  
       |  
      ABb 

Back to main page.