rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
INode.m
1 classdef INode < handle
2  % Interface for a node in a DataTree.
3  %
4  % A DataTree consists of nodes with an arbitrary number of children or
5  % DataTree.ILeafNode's which store data. In the abstract version of a DataTree,
6  % non-leaf nodes can be one of:
7  % - DataTree.IdMapNode,
8  % - DataTree.TpartNode or
9  % - DataTree.PpartNode.
10  % and leaf elements are always of type DataTree.ILeafNode.
11  %
12  % Each of these nodes specify information about the data stored in the leaf
13  % nodes.
14  %
15  % Considering e.g. the tree configuration
16  % @dot
17  % digraph example {
18  % node [shape=record, fontname=Helvetica, fontsize=10];
19  % nIdMapNode [label="{DataTree.IdMapNode|{implicit|explicit}}"URL="\ref DataTree.IdMapNode"];
20  % nTpartNode [label="{DataTree.TpartNode|{[0:10]|[11:30]|[31:50]}}"URL="\ref DataTree.TpartNode"];
21  % l1 [label="Leaf"];
22  % l2 [label="Leaf"];
23  % l3 [label="Leaf",color=red];
24  % l4 [label="Leaf"];
25  % nIdMapNode -> nTpartNode [label = "1"];
26  % nIdMapNode -> l1 [label = "2"];
27  % nTpartNode -> l2 [label = "[1,1]"];
28  % nTpartNode -> l3 [label = "[1,2]"];
29  % nTpartNode -> l4 [label = "[1,3]"];
30  % }
31  % @enddot
32  % the red leaf element is tagged with the id "implicit" and valid inside the
33  % time slice interval `[11,30]`. Children are numbered consecutively and can
34  % be received by using a concatenation of indices. The read leaf element
35  % could for example be reached via
36  % @code
37  % red_leaf = get(idmap_root, [1,2]);
38  % @endcode
39  %
40  % where the index vector is obtainable via a call to the get_index() method
41  % @code
42  % index = get_index(idmap_root, "implicit", [], 23);
43  % @endcode
44  %
45  % There exist generic specializations for DataTrees representing detailed
46  % data (Greedy.DataTree.Detailed.INode, Greedy.DataTree.Detailed.ILeafNode) and reduced data
47  % (Greedy.User.RbReducedDataDefault) which have no extra functionality for non-leaf node
48  % elements.
49 
50  methods(Abstract)
51 
52  % function data = get(this, index);
53  % Access to a child of the current node
54  %
55  % Access a children node by an index which is usually retrieved by a call
56  % to get_index()
57  %
58  % Parameters:
59  % index: vector describing the father-child relation
60  %
61  % Return values:
62  % data: the children node of type INode
63  data = get(this, index);
64 
65  % function index = get_index(this, id, mu, nt);
66  % Obtains the leaf index vector that best fits the child description given
67  % by the three arguments.
68  %
69  % @todo add get_indices method returning indices in a range
70  %
71  % The leaf child description consists of an
72  % - id string,
73  % - a parameter vector and
74  % - a time step number.
75  %
76  % Parameters:
77  % id: a string id filtered through an DataTree.IdMapNode in the tree hierarchy.
78  % mu: a parameter vector filtered through a DataTree.PpartNode instance in the
79  % tree hierarchy.
80  % nt: an integer corresponding to a time step index filtered through a
81  % DataTree.TpartNode instance in the tree hierarchy.
82  %
83  % Return values:
84  % index: the most-specific (longest possible) index vector leading to a
85  % DataTree.ILeafNode element matching the child description.
86  index = get_index(this, id, mu, nt);
87 
88  % function tree = create_tree(this, creator, ids, mu_cube, tslice, basepath);
89  % Creates a new tree from a subtree specified by ids, parameter and time index
90  % regions
91  %
92  % The method creates a new DataTree for all nodes tagged by an id in
93  % \a ids, lying in the time slice given by \a tslice and inside the
94  % parameter space region given by \a mu_rect. At each of these nodes a
95  % method from a \a creator is called to build the tree.
96  %
97  % Parameters:
98  % creator: an object of type DataTree.ICreator creating the new tree.
99  % ids: a cell array of ids which shall be filtered. An empty cell array
100  % means that all ids are accepted. (default = [])
101  % mu_cube: a '1x2'-cell array of vectors '{ lower_left, upper_right }'
102  % specifying the lower left and the upper right corner of a cube
103  % in the parameter space for filtering parameter vectors. An
104  % empty array disables the filtering (default = []).
105  % tslice: a 2D vector specifying an interval of time step indices for
106  % time slicing. An empty vector disables the filtering (default =
107  % [])
108  % basepath: a vector specifying the relation of the current node to the
109  % parent node at which the merge began.
110  %
111  % Return values:
112  % tree: the newly created tree of type DataTree.INode
113  tree = create_tree(this, creator, ids, mu_cube, tslice, basepath);
114 
115  % function children = length(this);
116  % Returns the number of children of the node
117  %
118  % For leaf elements this method should return 0.
119  %
120  % Return values:
121  % children: the number of childres of the current node
122  children = length(this);
123 
124  % function this = set(this, index, value);
125  % Sets a child at the given path in the tree hierarchy.
126  %
127  % Usually this method is used to set a leaf data node with attached data.
128  %
129  % Parameters:
130  % index: the path index where the node shall be injected
131  % value: the node that shall be attached as a child
132  %
133  % Return values:
134  % this: the modified DataTree node.
135  this = set(this, index, value);
136 
137  end
138 
139  methods
140 
141  function leaf_func(this, funcptr, ids, mu_cube, tslice)
142  % applies a function to all leafs of a DataTree
143  %
144  % Parameters:
145  % funcptr: function handle of the function to be applied to all leaf elements.
146  % ids: ID filter. See create_tree() for details.
147  % mu_cube: parameter filter. See create_tree() for details.
148  % tslice: time filter. See create_tree() for details.
149 
150  if nargin < 3
151  ids = [];
152  end
153  if nargin < 4
154  mu_cube = [];
155  end
156  if nargin < 5
157  tslice = [];
158  end
159  if nargin < 6
160  basepath = [];
161  end
162 
163  create_tree(this, DataTree.NullCreator(funcptr), ids, mu_cube, tslice, basepath);
164 
165  end
166 
167  function tree = create_scalar_tree(this, funcptr, ids, mu_cube, tslice)
168  % function tree = create_scalar_tree(this, funcptr, ids, mu_cube, tslice)
169  % copies the current trees with different leafs. These leafs are computes
170  % by a function returning scalar values.
171  %
172  % For example, one can extract a field available in all leafs with this
173  % function, like the reduced basis size 'N' in a reduced data structure.
174  %
175  % Parameters:
176  % funcptr: function handle of the function to be applied to all leaf elements.
177  % ids: ID filter. See create_tree() for details.
178  % mu_cube: parameter filter. See create_tree() for details.
179  % tslice: time filter. See create_tree() for details.
180 
181  if nargin < 3
182  ids = [];
183  end
184  if nargin < 4
185  mu_cube = [];
186  end
187  if nargin < 5
188  tslice = [];
189  end
190  basepath = [];
191 
192  tree = create_tree(this, DataTree.ScalarCreator(funcptr), ids, mu_cube, tslice, basepath);
193  end
194 
195  function start_index = traverse_start(this)
196  % function start_index = traverse_start(this)
197  % Start iterator for a full traverse of the DataTree.
198  %
199  % Use this method to get a start index for a tree traversal.
200  % Subsequently, indices can be obtained by calls to traverse_next().
201  % Every node is touched during a traversal, until an empty index is
202  % returned.
203  %
204  % Return values:
205  % start_index: the start index vector for tree traversal.
206  if length(this) > 0
207  start_index = [1, traverse_start(get(this, 1))];
208  else
209  start_index = [];
210  end
211  end
212 
213  function next_index = traverse_next(this, this_index)
214  % function next_index = traverse_next(this, this_index)
215  % iterator for a full traverse of the DataTree.
216  %
217  % Use this method to get the next index for a tree traversal.
218  % Every node is touched during a traversal, until an empty index is
219  % returned.
220  %
221  % Parameters:
222  % this_index: previous index.
223  %
224  % Return values:
225  % next_index: the next index vector for tree traversal. Empty vector
226  % after the last node.
227  if length(this_index) > 1
228  next_index = [this_index(1), traverse_next(get(this, this_index(2)), this_index(2:end))];
229  if length(next_index) > 1
230  return;
231  else
232  this_index = next_index;
233  end
234  end
235  next_index = [this_index, traverse_start(get(this, 1))];
236  if length(next_index) > 1
237  return;
238  end
239  if this_index < length(this)
240  next_index = this_index + 1;
241  else
242  next_index = [];
243  end
244  end
245 
246 % function first = first_leaf_index(this, ids, mu_cube, tslice)
247 % % function first = first_leaf_index(this)
248 % % returns the first (left-most) index for an iteration of the leafs of the data tree.
249 % %
250 % % For a full leaf iteration use next_leaf_index().
251 % %
252 % % Return values:
253 % % first: index of the first leaf element
254 
255 
256 % if nargin < 2
257 % ids = [];
258 % end
259 % if nargin < 3
260 % mu_cube = [];
261 % end
262 % if nargin < 4
263 % tslice = [];
264 % end
265 
266 % if ~isa(this, 'INode') || isa(this, 'DataTree.ILeafNode')
267 % first = [];
268 % else
269 % nextchild_index = get_first_index_match(this, ids, mu_cube, tslice);
270 % if nextchild_index == -1
271 % first = -1;
272 % return;
273 % end
274 % nextchild = get(this, nextchild_index);
275 % if ~isa(nextchild, 'INode') || isa(nextchild, 'DataTree.ILeafNode')
276 % first = nextchild_index;
277 % else
278 % next_part = first_leaf_index(nextchild, ids, mu_cube, tslice);
279 % first = [nextchild_index, next_part];
280 % if next_part == -1
281 % first = 1;
282 % end
283 % end
284 % end
285 % end
286 
287 % function next = next_leaf_index(this, current, ids, mu_cube, tslice)
288 % % function next = next_leaf_index(this, current, ids, mu_cube, time_slice)
289 % % returns indices for a leaf element iteration
290 % %
291 % % Get the first index with first_leaf_index()
292 % %
293 % % Parameters:
294 % % current: index of last leaf element returned by next_leaf_index()
295 % % respectively first_leaf_index()
296 % %
297 % % Return values:
298 % % next: index of leaf element right of current.
299 % %
300 
301 
302 % if nargin < 2
303 % ids = [];
304 % end
305 % if nargin < 3
306 % mu_cube = [];
307 % end
308 % if nargin < 4
309 % tslice = [];
310 % end
311 
312 % if isempty(current)
313 % % current is a root and leaf element => no more leafs
314 % next = -1;
315 % else
316 % next = [];
317 % % are we _not_ directly above the current leaf?
318 % if length(current) > 1
319 % next_tmp = next_leaf_index(get(this, current(1)), current(2:end-i), ids, mu_cube, tslice);
320 % if next_tmp ~= -1
321 % next = [current(1), next_tmp];
322 % end
323 
324 % end
325 
326 % % 2. here we are: all children of current(1) are already iterated or
327 % % current(1) is a leaf, so we can find the next child of 'this'.
328 % if isempty(next)
329 % % get the next candidate...
330 % nextchild_index = get_first_index_match(this, ids, mu_cube, tslice, current(1));
331 % if nextchild_index == -1
332 % % there is no candidate on this level...
333 % next = -1;
334 % else
335 % % get the candidate
336 % nextchild = get(this, nextchild_index);
337 
338 % if ~isa(nextchild, 'INode') || isa(nextchild, 'DataTree.ILeafNode')
339 % % it is a leaf element
340 % next = nextchild_index;
341 % else
342 % % another tree, find all its leafs...
343 % next = [ nextchild_index, first_leaf_index(nextchild, ids, mu_cube, tslice) ];
344 % end
345 % end
346 % end
347 % end
348 
349 % end
350 
351 % function indices = get_indices(this, ids, mu_cube, tslice)
352 
353 % if nargin < 2
354 % ids = [];
355 % end
356 % if nargin < 3
357 % mu_cube = [];
358 % end
359 % if nargin < 4
360 % tslice = [];
361 % end
362 
363 % indices = {};
364 % index = first_leaf_index(this, ids, mu_cube, tslice);
365 % while index ~= -1
366 % indices = [indices, { index }];
367 % index = next_leaf_index(this, index, ids, mu_cube, tslice);
368 % end
369 % end
370 %
371 
372  function description = get_active_leaf_description(this, model, ids)
373  % function description = get_active_leaf_description(this, model, ids)
374  % returns an enumeration of all leaves' basepath index vectors with a
375  % description of their parents.
376  %
377  % Parameters:
378  % model: a reduced or detailed model of type .IModel holding
379  % information about the selected parameters and maybe the time
380  % instant.
381  % ids: ID filter. See create_tree() for details.
382  %
383  % Optional fields of model:
384  % descr: ModelDescr object specifying the problem discretization
385  % descr.t: current time step number
386 
387  tslice = [];
388  if isfield(model.descr, 't')
389  tslice = [model.descr.t, model.descr.t];
390  end
391  mu_cube = [get_mu(model), get_mu(model)];
392  if nargin <= 2
393  ids = [];
394  end
395 
396  description = create_tree(this, DataTree.LeafDescription, ids, mu_cube, tslice, []);
397  end
399  function description = get_leaf_description(this, ids, mu_cube, tslice)
400  % function description = get_leaf_description(this, ids, mu_cube, tslice)
401  % returns an enumeration of all leaves' basepath index vectors with a
402  % description of their parents.
403  %
404  % Parameters:
405  % ids: ID filter. See create_tree() for details.
406  % mu_cube: parameter filter. See create_tree() for details.
407  % tslice: time filter. See create_tree() for details.
408 
409  if nargin < 2
410  ids = [];
411  end
412  if nargin < 3
413  mu_cube = [];
414  end
415  if nargin < 4
416  tslice = [];
417  end
418  basepath = [];
419 
420  description = create_tree(this, DataTree.LeafDescription, ids, mu_cube, tslice, basepath);
421  end
422 
423 % function leaf_func(this, funcptr, ids, mu_cube, time_slices)
424 
425 % leaf_indices = get_indices(this, ids, mu_cube, time_slices);
426 % for i = 1:length(leaf_indices)
427 % leaf = get(this, leaf_indices(i));
428 % funcptr(leaf);
429 % end
430 % end
431 
432  function tstop = index_valid_till(this, index)
433  % function tstop = index_valid_till(this, index)
434  % Returns the last valid time step index of a time slice
435  %
436  % This method can be used to obtain the last time slice index for the
437  % node given by 'get(this, index)'
438  %
439  % Parameters:
440  % index: the index vector of the child for which the time slice shall be
441  % analyzed.
442  %
443  % Return values:
444  % tstop: last valid time step index
445  if ~isempty(index)
446  tstop = index_valid_till(get(this, index(1)), index(2:end));
447  else
448  tstop = Inf;
449  end
450  end
451 
452  function data = get_by_description(this, id, mu, nt)
453  % function data = get_by_description(this, id, mu, nt)
454  % A combination of get_index() and get()
455  %
456  % This methods gets the child node described by \a id, \a mu and \a nt.
457  %
458  % Parameters:
459  % id: a string id filtered through an DataTree.IdMapNode in the tree hierarchy.
460  % mu: a parameter vector filtered through a DataTree.PpartNode instance in the
461  % tree hierarchy.
462  % nt: an integer corresponding to a time step index filtered through a
463  % DataTree.TpartNode instance in the tree hierarchy.
464  %
465  % Return values:
466  % data: the children node of type INode
467 
468  if nargin < 3
469  mu = [];
470  end
471  if nargin < 4
472  nt = [];
473  end
474  data = get(this, get_index(this, id, mu, nt));
475  end
476 
477  function active_leaf_index = get_active_leaf_index(this, model, id)
478  % function active_leaf_index = get_active_leaf_index(this, model[, id])
479  % retuns the leaf element index for the current IDetailedModel configuration.
480  %
481  % Parameters:
482  % model: a reduced or detailed model of type ::IModel holding
483  % information about the selected parameters and maybe the time
484  % instant.
485  % id: optional parameter defining a special ID that shall be
486  % attached to the leaf element.
487  %
488  % Return values:
489  % active_leaf_index: leaf element index to be returned.
490  %
491  % Optional fields of model:
492  % descr: ModelDescr object specifying the problem discretization
493  % descr.t: current time step number
494  %
495  % @todo rename this method to get_leaf_index
496  nt = [];
497  if isfield(model.descr, 't')
498  nt = model.descr.t;
499  end
500  if nargin <= 2
501  id = [];
502  end
503  active_leaf_index = get_by_description(this, id, get_mu(model), nt);
504  end
505 
506  function active_leaf = get_active_leaf(this, model, id)
507  % function active_leaf = get_active_leaf(this, model[, id])
508  % retuns the leaf element for the current IDetailedModel configuration.
509  %
510  % Parameters:
511  % model: a reduced or detailed model of type ::IModel holding
512  % information about the selected parameters and maybe the time
513  % instant.
514  % id: optional parameter defining a special ID that shall be
515  % attached to the leaf element.
516  %
517  % Return values:
518  % active_leaf: leaf element of type ::DataTreeLeafNode to be
519  % returned.
520  %
521  % Optional fields of model:
522  % descr: ModelDescr object specifying the problem discretization
523  % descr.t: current time step number
524  %
525  % @todo rename this method to get_leaf
526 
527  nt = [];
528  if isfield(model.descr, 't')
529  nt = model.descr.t;
530  end
531  if nargin <= 2
532  id = [];
533  end
534  active_leaf = get_active_leaf(get_by_description(this, id, get_mu(model), nt), model);
535  end
537  function display(this, fn, basepath, name)
538  % function display(this, fn, basepath, name)
539  % overwrites the standard display method for DataTree objects
540  %
541  % Parameters:
542  % fn: Optional filename under which a dot-file depicting the tree
543  % structure is stored.
544  % basepath: only used in recursive calls of this method
545  % name: only used in recursive calls of this method
546  if nargin == 1
547  fn = [];
548  end
549  if nargin <= 2
550  basepath = [];
551  end
552  if nargin <= 3
553  name = inputname(1);
554  end
555  lines = disp_node(this, basepath, fn);
556  disp([repmat(' |', 1, length(basepath)),'-- <a href="matlab: htdoc(''', class(this), ''')">', class(this), '</a>']);
557  disp('');
558  if length(lines) > 8
559  disp([repmat(' |', 1, length(basepath)), ...
560  ' <a href="matlab: display(get(',...
561  name, ',', mat2str(basepath), ...
562  '))">get(', name, ',', mat2str(basepath), ')</a>']);
563  else
564  for i = 1:length(lines)
565  lfind = strfind(lines{1}, '<a href');
566  if i == 1 && lfind(1) == 1
567  continue
568  end
569  disp([repmat(' |', 1, length(basepath)), ' ', lines{i}]);
570  end
571  end
572  for i = 1:length(this)
573  child = get(this, i);
574  if isa(child, 'DataTree.INode')
575  display(child, fn, [basepath, i], name);
576  else
577  disp(child);
578  end
579  end
580  end
581 
582  function lines = disp_node(this, basepath, fn)
583  % function lines = disp_node(this, basepath, fn)
584  % returns a cell array of strings with information on the node.
585  %
586  % The default implementation adds the output of the 'disp' command.
587  %
588  % Parameters:
589  % basepath: the index path needed to reach this element from the root.
590  % fn: a file name string for a dot file that can be generated
591  %
592  % Return values:
593  % lines: the cell array of strings
594 
595  disp_text = evalc('disp(this)');
596  lno = 1;
597  while(~isempty(disp_text))
598  [lines{lno}, disp_text] = strtok(disp_text, sprintf('\n'));
599  lno = lno + 1;
600  end
601 
602  end
603 
604  end
605 
606 end
DataTree.ICreator implementation which does not create a tree, but a cell array of descriptions for a...
Data Tree element which can be filtered by ids
Definition: IdMapNode.m:18
Interface for a leaf node of a data tree.
Definition: ILeafNode.m:18
This is the common interface for all models, detailed and reduced ones.
Definition: IModel.m:17
function htdoc(topic)
opens mtoc++ documentation in a browser
Definition: htdoc.m:17
Interface for a node in a DataTree.
Definition: INode.m:18
Definition: leaf.m:17
Struct with control fields for the analytical PDE functions, the discretization and the parametrizati...
Definition: dummyclasses.c:15
Data Tree element which can be filtered by time instants.
Definition: TpartNode.m:18
This is the interface for a detailed model providing methods to compute high dimensional simulation s...