1 %> @brief Cascade
block: sequence of blocks represented by a
block
3 %> Cascade blocks can mimic the behaviour of linear transformation blocks (
fcon_linear; such
as PCA)
if it contains one or more such blocks.
4 %> It has all the properties that a
fcon_linear block has, however its valid functioning will depend on the component blocks.
5 %> The loadings matrix is calculated by multiplying the loadings matrix of successive component blocks.
9 %> @arg boot: all component blocks booted
10 %> @arg train: after training first
block, training data is inputted into it to
get the training data to the second block etc
11 %> @arg use: output of (k-1)-th block is inputted into k-th block
16 %> Cell of @c block objects
18 %> =1. Whether to cross-calculate outputs when it is the
case. The
case is: in training; and the component block is level 1
19 %> (trainable); and the component block is not the last block. If @c flag_crossc is
false, the same dataset will be used
20 %> to train and to calculate the block output.
22 %> SGS to
do the cross-calculations when necessary. If needed and empty, a
default one will be used
27 % These properties have their getters and are read-only
29 %> Loadings matrix. @ref
fcon_linear mimicking. Calculates loadings matrix by multiplying
30 %> (<code>L = block1.L*block2.L*...</code>).
34 %> Loadings feature names. @ref
fcon_linear mimicking.
36 %> Feature x-axis. @ref
fcon_linear mimicking. Retrieves the @c L_fea_x from the first block.
38 %> x-axis name. @ref
fcon_linear mimicking. Retrieves the @c xname from the first block.
43 %> Class labels. @ref
clssr mimicking. Retrieves the @c classlabels
property from the last block.
45 %> Feature indexes. @ref
fsel mimicking. Retrieves the @c v
property from the last block.
47 %> Decision threshold. @ref
decider mimicking. Retriever the @c decisionthreshold
property from some
decider it finds along the
51 properties(SetAccess=
protected)
54 %> Whether the block is able to mimic a @ref
fcon_linear. This is calculated at boot time.
56 %> Whether the block is able to mimic a @ref
decider. This is calculated at boot time.
58 %> Index of first linear block. This is calculated at boot time.
60 %> Index of
decider. This is calculated at boot time.
66 properties(Access=
private)
67 %> Whether an error should be thrown
if an invalid
property is accessed. Because
block_cascade_base can mimic several other classes,
68 %> but
this is dependand on its component blocks, many properties can be invalid. However, giving errors all the time can be annoying
69 %>
if the purpose is just to display properties, such
as when one types the variable name at MATLAB command window.
70 %> If flag_give_error is
false, all numeric properties will
return a NaN when they are invalid
76 o.classtitle = 'Block Cascade';
82 function z = get.no_blocks(o)
90 % function z = get.fea_names(o)
91 % z = o.get_fea_names();
94 function z = get.L_fea_x(o)
98 function z = get.xname(o)
102 function z = get.xunit(o)
106 function z = get.yname(o)
110 function z = get.yunit(o)
114 %> Other getters call yet another function, I don't know exactly why. I won't do this here because this may be
115 %> called many times.
116 function z = get.classlabels(o)
120 %> Retrieves @c v from last block.
121 function z =
get.v(o)
125 %> Retrieves @c decisionthreshold from the
decider that
if finds
129 irerror(
'Cascade block cannot mimic a decider!');
134 z = o.blocks{o.idx_decider}.decisionthreshold;
141 function blk = extract_fcon_linear_fixed(o)
144 blk.copy_axes_from(o);
152 %---------------------------------------------------------------------------------------------------------
157 function z = get_L_fea_x(o)
158 if numel(o.blocks) == 0
160 irerror('Cascade block is empty!');
165 if ~o.flag_fcon_linear
167 irerror('Cascade block cannot mimic a linear block!');
178 function z = get_xname(o)
179 if numel(o.blocks) == 0
181 irerror('Cascade block is empty!');
186 if ~o.flag_fcon_linear
188 irerror('Cascade block cannot mimic a linear block!');
200 %> Feature names: takes the xname property from the first linear block
201 function z = get_xunit(o)
202 if numel(o.blocks) == 0
204 irerror('Cascade block is empty!');
209 if ~o.flag_fcon_linear
211 irerror('Cascade block cannot mimic a linear block!');
222 %> y-name: takes the yname property from the last block that has it
224 %> @return yname. Defaults to an empty
string.
225 function z = get_yname(o)
227 for i = numel(o.blocks):-1:1
228 if isprop(o.blocks{i},
'yname')
229 z = o.blocks{i}.yname;
235 %> y-unit: takes the yunit
property from the last block that has it
237 %> @
return yunit. Defaults to an empty
string.
238 function z = get_yunit(o)
240 for i = numel(o.blocks):-1:1
241 if isprop(o.blocks{i},
'yunit')
242 z = o.blocks{i}.yunit;
249 % %> Feature names: takes the fea_names
property from the first linear block
250 %
function z = get_fea_names(o)
251 %
if numel(o.blocks) == 0
252 %
if o.flag_give_error
253 %
irerror(
'Cascade block is empty!');
258 % b = o.get_linear1();
263 %> @brief Calls get_methodname() for all blocks
264 %> @param flag_short=0
265 function s = get_methodname(o, flag_short)
266 if nargin < 2 || isempty(flag_short)
270 for i = 1:length(o.blocks)
275 s = [s b.get_methodname(flag_short)];
282 %> Calls the get_L_fea_names from the first block that has
this method (SEARCHING BACKWARDS)
283 function a = get_L_fea_names(o, idxs)
285 nb = numel(o.blocks);
288 irerror(
'Cascade block is empty!');
294 if ismethod(b,
'get_L_fea_names')
295 a = b.get_L_fea_names(idxs);
303 %> Cascades blocks' loadings matrices. Works only if one or all blocks provide one loadings matrix of course, i.e., they
304 %> all represent linear transforms.
305 function L = get_loadings(o)
306 if ~o.flag_fcon_linear
308 irerror('Cascade block cannot mimic a linear block!');
316 for i = o.idx_linear1:length(o.blocks)
317 if ~ismember(properties(o.blocks{i}),
'L')
318 irerror(sprintf('Block ''%s'' does not have property ''L''!', o.blocks{i}.classtitle));
321 if i == o.idx_linear1
339 %---------------------------------------------------------------------------------------------------------
342 methods(Access=
protected)
343 %> BLock needs to keep up-to-date with contents
344 function o = assert_checked(o)
350 function o = do_check(o)
351 idx1temp = 0; % Index of first linear block
352 flag_cannot = 0; % Cannot be a linear block
355 for i = 1:length(o.blocks)
356 if isa(o.blocks{i},
'block_cascade_base')
357 o.blocks{i} = o.blocks{i}.do_check();
360 if isa(o.blocks{i},
'fcon_linear') || isa(o.blocks{i},
'block_cascade_base') && o.blocks{i}.flag_fcon_linear
368 if ~o.flag_decider && isa(o.blocks{i},
'decider')
373 level = max(level, o.blocks{i}.flag_trainable);
376 o.flag_fcon_linear = ~flag_cannot && idx1temp > 0;
377 if o.flag_fcon_linear
378 o.idx_linear1 = idx1temp;
381 o.flag_trainable = level;
386 %> Boots every encapsulated block
387 function o = do_boot(o)
390 for i = 1:length(o.blocks)
391 o.blocks{i} = o.blocks{i}.boot();
395 %> Trains every encapsulated block
396 %> @todo think about stacked generalization
397 function o = do_train(o, data)
398 o = o.assert_checked();
400 flag_crossc_first = 1;
402 for i = 1:o.no_blocks
403 % Sequence here is cross-calculate; train; use.
405 % Cross-calculate and use are mutually exclusive.
407 % Note that cross-calculation could go after but I put it before to make it more robust to blocks that don't boot propertly
410 if i < o.no_blocks && o.flag_crossc && o.blocks{i}.flag_trainable > 0
411 % Creates block blsp_crossc
if it is the first time the cross-calculated will be performed in
this training
function
413 block_crossc = blsp_crossc();
414 if ~isempty(o.sgs_crossc)
415 block_crossc.
sgs = o.sgs_crossc;
417 flag_crossc_first = 0;
420 block_crossc.mold = o.blocks{i};
421 data_next = block_crossc.use(data);
425 if o.blocks{i}.flag_trainable > 0
426 o.blocks{i} = o.blocks{i}.train(data);
430 if i < o.no_blocks && (~o.flag_crossc || o.blocks{i}.flag_trainable == 0)
431 data_next = o.blocks{i}.use(data);
440 %> output of (k-1)-th block is inputted into k-th block. Final output is the output of the end-th block.
443 function data = do_use(o, data)
444 o = o.assert_checked();
446 for i = 1:length(o.blocks)
448 if isa(blk,
'blmisc_rowsout')
449 % Skips outlier removers in use stage
451 data = o.blocks{i}.
use(data);
456 %> Makes sure that the block can mimic a linear block
457 function o = assert_fcon_linear(o)
458 if ~o.flag_fcon_linear
459 irerror('Cascade block cannot mimic a linear block!');
464 % % % % % % % %> Makes sure that the block can mimic a linear block
465 % % % % % % % function o = assert_decider_(o)
466 % % % % % % % if ~o.flag_decider
471 %> Retrieves the first linear block
472 function b = get_linear1(o)
473 o = o.assert_checked();
475 o.assert_fcon_linear();
476 b = o.blocks{o.idx_linear1};
480 function s = do_get_report(o)
481 s = do_get_report@block(o);
483 len = length(o.blocks);
485 stemp = sprintf('Component Block %d/%d', i, len);
486 stemp2 = repmat('-', 1, length(stemp));
487 s = cat(2, s, sprintf('\n\n /%s\\\n| %s |\n \\%s/\n', stemp2, stemp, stemp2), o.blocks{i}.get_report());
Feature Construction - Linear Transformations base class.
Base Sub-dataset Generation Specification (SGS) class.
Outlier Removal base class.
Property decisionthreshold
=0. Minimum maximum probability. If not reached, assigned class will be -1, which means "refuse-to-de...
Feature Selection (FSel) class.
function get_L_fea_names(in o, in idxs)
Property classlabels
Class labels. clssr mimicking. Retrieves the classlabels property from the last block.
Block that resolves estimato posterior probabilities into classes.
function use(in o, in data)
Applies block to data.
Loadings vector specified directly.
Analysis Session (AS) base class.
function uip_block_cascade_base(in varargin)
Cascade block: sequence of blocks represented by a block.