IRootLab
An Open-Source MATLAB toolbox for vibrational biospectroscopy
block.m
Go to the documentation of this file.
1 %> @brief Base Block class
2 classdef block < irobj
3  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4  %%% Potentially re-set when inheriting a block
5  properties(SetAccess=protected)
6  %> ='irdata'. (High-Level setting) Class or classes (can be string or cell of strings) that the block can deal with.
7  %> Allows for @c objtool and @c datatool to know (when appropriate) which blocks are applicable to the selected object(s).
8  inputclass = 'irdata';
9  %> =0. (High-Level setting and internal function) Whether or not the block is bootable.
10  flag_bootable = 0;
11  %> =0. (High-Level + internal function). Whether or not the block can be trained, or completely non-data-based.
12  flag_trainable = 0;
13 
14  %> =0. (internal function). Whether or not the block accepts incremental training. The meaning is:
15  %> @arg If YES, it means that the block can adapt/evolve everytime its train() method is called
16  %> @arg If NO, the block can be trained only once, and calling its train() method many times can lead to unpredictable results
17  flag_incrtrain = 0;
18 
19 
20  %> =1. (internal function) If true, dataset number of features will be checked upon training and using. Ignored if o.flag_trainable is 0.
21  flag_fixednf = 1;
22  %> =0. (internal function) If true, dataset number of observations will be checked upon training and using. Ignored if o.flag_trainable is 0.
23  flag_fixedno = 0;
24 
25  %> =0. (High-Level setting (@ref gencode)) Whether block allows/expects multiple objects as input.
26  flag_multiin = 0;
27  %> =1. (High-Level setting (@ref gencode)) Whether the block generates any output at all (counterexample: @ref vis blocks)
28  flag_out = 1;
29 
30  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31  %%% How to deal with the question of inliers/outliers!
32 
33  %> If true, train() will pass on to do_train() a dataset with inliers only.
34  %> If this flag is true, @ref flag_train_require_inliers will be ignored, because @ref flag_train_inliers_only being true is one way to solve the "inliers requirement".
35  flag_train_inliers_only = 0;
36 
37  %> =1. If true, train() will give an error if the dataset has outliers. This is true by default, because the developer should
38  %> be aware of outliers being inputted into a training algorithm.
39  flag_train_require_inliers = 1;
40  end;
41 
42 
43  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
44  %%% Internal operation
45  properties(SetAccess=protected)
46  %> =-1. Number of features. Cleared at boot(), assigned or reinforced at train().
47  nf = -1;
48  %> =-1. Number of observations.
49  no = -1;
50  %> =0. Set to 1 by train() if training is successful; set back to 0 after booting.
51  flag_trained = 0;
52  %> =0. Set to 1 by boot() after booting the block
53  flag_booted = 0;
54 
55  %> Trainings time
56  time_train = 0;
57  %> Use time
58  time_use = 0;
59  end;
60 
61  methods(Access=private)
62 
63  %block_assert_trained: Makes sure that the block is trained [before used]
64  function o = assert_trained(o)
65  if o.flag_trainable > 0 && ~o.flag_trained
66  irerror(sprintf('Tried to use block of class ´%s´ before training', class(o)));
67  end;
68  end;
69 
70  %block_assert_nf: Makes sure that the number of features is compatible with the block
71  function o = assert_nonf(o, data)
72  if o.flag_trainable > 0
73  if o.flag_fixednf
74  for i = 1:length(data)
75  if o.nf ~= data(i).nf
76  irerror(sprintf('Incorrect number of features: %d (should be %d)', data(i).nf, o.nf));
77  end;
78  end;
79  end;
80  if o.flag_fixedno
81  for i = 1:length(data)
82  if o.no ~= data(i).no
83  irerror(sprintf('Incorrect number of observations: %d (should be %d)', data(i).no, o.no));
84  end;
85  end;
86  end;
87  end;
88  end;
89 
90  end;
91 
92 
93  methods(Access=protected)
94  % "do" method is for pure implementation of the related functionality, opposed to its public counterpart
95  % which deals with bureaucracy
96  function o = do_train(o, data) %#ok<INUSD>
97  end;
98 
99  % "do" method is for pure implementation of the related functionality, opposed to its public counterpart
100  % which deals with bureaucracy
101  function data = do_use(o, data)
102  end;
103 
104 
105  %> @brief Boots the block
106  %>
107  %> Abstract. Booting accounts for clearing any recordings; model structure; stored data etc from the object so that it can
108  %> be re-used anew.
109  function o = do_boot(o)
110  end;
111  end;
112 
113 
114 
115  methods
116  function o = block()
117  o.classtitle = 'Block';
118  end;
119  end;
120 
121 
122 
123 
124  methods
125  %> Abstract. Method to get the per-feature grades. BMTool stuff.
126  function z = get_grades(o, params)
127  irerror('Block does not calculate per-feature grades!');
128  end;
129 
130  %> Abstract. Method to get block title based on passed parameters. BMTool stuff.
131  function z = get_gradeslegend(o, params)
132  if ~isstr(o.title)
133  z = [o.classtitle];
134  else
135  z = o.title;
136  end;
137  end;
138 
139  %> @brief Applies block to data.
140  function varargout = use(o, data)
141  % BTW there is no point in the "o =" i.e. the assignment, because the block won't output itself anyway
142  o.assert_trained();
143  o.assert_nonf(data);
144 
145  t = tic();
146  o.time_use = 0;
147  out = o.do_use(data);
148  if o.time_use == 0
149  % Default time recording
150  o.time_use = toc(t);
151  end;
152  if nargout == 1
153  varargout = {out};
154  else
155  varargout = {o, out};
156  end;
157  end;
158 
159 
160  %> @brief Trains block.
161  function o = train(o, data, varargin)
162  if o.flag_bootable && ~o.flag_booted
163  irerror('Block needs to be booted first!');
164  end;
165 
166  if o.flag_trainable > 0
167  if o.flag_trained && o.flag_incrtrain
168  o.assert_nonf(data);
169  end
170 
171  if (o.flag_train_inliers_only || o.flag_train_require_inliers) && any(data.classes < 0)
172  if o.flag_train_inliers_only
173  data = data_select_inliers(data);
174  else
175  irerror(sprintf('Dataset contains rows with class < 0, but block of class "%s" requires dataset with inliers only (select inliers first)!', class(o)));
176  end;
177  end;
178 
179  o.no = data(1).no; % Please note that if do_train() gives an error, this won't have effect
180  o.nf = data(1).nf;
181 
182  o.time_train = 0;
183  t = tic();
184  o = o.do_train(data, varargin{:});
185  if o.time_train == 0
186  % Default time recording
187  o.time_train = toc(t);
188  end;
189  end;
190  o.flag_trained = 1;
191  end;
192 
193  %> @brief Configures the structure to deal with new type of data
194  %>
195  %> Booting accounts for clearing any recordings; model structure; stored data etc from the object so that it can
196  %> be re-used anew.
197  function o = boot(o)
198  o.nf = -1;
199  o.flag_trained = 0;
200 
201  o = o.do_boot();
202 
203  o.flag_booted = 1;
204  end;
205  end;
206 
207 end
function irerror(in s)
function objtool(in varargin)
Visualization base class.
Definition: vis.m:4
Base Block class.
Definition: block.m:2
function data_select_inliers(in data)
Analysis Session (AS) base class.
Definition: as.m:6
Base class.
Definition: irobj.m:33
MATLAB code generation to create, boot, train and use blocks.
Definition: gencode.m:9