Mercurial > forge
view extra/control-devel/inst/@iddata/cat.m @ 9945:5291eef2375e octave-forge
control-devel: texinfo help for iddata
author | paramaniac |
---|---|
date | Mon, 02 Apr 2012 15:17:42 +0000 |
parents | 321b9b4da87b |
children | 031647737003 |
line wrap: on
line source
## Copyright (C) 2012 Lukas F. Reichlin ## ## This file is part of LTI Syncope. ## ## LTI Syncope is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## LTI Syncope is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with LTI Syncope. If not, see <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{dat} =} cat (@var{dim}, @var{dat1}, @var{dat2}, @dots{}) ## Concatenate iddata sets along dimension @var{dim}. ## ## @strong{Inputs} ## @table @var ## @item dim ## Dimension along which the concatenation takes place. ## @table @var ## @item 1 ## Concatenate samples. ## The samples are concatenated in the following way: ## @code{dat.y@{e@} = [dat1.y@{e@}; dat2.y@{e@}; @dots{}]} ## @code{dat.u@{e@} = [dat1.u@{e@}; dat2.u@{e@}; @dots{}]} ## where @var{e} denotes the experiment. ## The number of experiments, outputs and inputs must be equal for all datasets. ## Equivalent to @command{vertcat}. ## ## @item 2 ## Concatenate inputs and outputs. ## The outputs and inputs are concatenated in the following way: ## @code{dat.y@{e@} = [dat1.y@{e@}, dat2.y@{e@}, @dots{}]} ## @code{dat.u@{e@} = [dat1.u@{e@}, dat2.u@{e@}, @dots{}]} ## where @var{e} denotes the experiment. ## The number of experiments and samples must be equal for all datasets. ## Equivalent to @command{horzcat}. ## ## @item 3 ## Concatenate experiments. ## The experiments are concatenated in the following way: ## @code{dat.y = [dat1.y; dat2.y; @dots{}]} ## @code{dat.u = [dat1.u; dat2.u; @dots{}]} ## The number of outputs and inputs must be equal for all datasets. ## Equivalent to @command{merge}. ## @end table ## ## @item dat1, dat2, @dots{} ## iddata sets to be concatenated. ## @end table ## ## @strong{Outputs} ## @table @var ## @item dat ## Concatenated iddata set. ## @end table ## ## @seealso{horzcat, merge, vertcat} ## @end deftypefn ## Author: Lukas Reichlin <lukas.reichlin@gmail.com> ## Created: March 2012 ## Version: 0.1 function dat = cat (dim, varargin) ## I think this code is pretty elegant because it works for ## any number of arguments and without a single for-loop :-) ## if this overloaded cat method is called, it is guaranteed that ## * nargin > 0 ## * at least one argument is an iddata object if (! is_real_scalar (dim)) print_usage (); endif ## store all datasets in a single struct 'tmp' ## tmp is not a valid iddata set anymore, ## but it doesn't matter, we want just a struct tmp = cellfun (@iddata, varargin); [n, p, m, e] = cellfun (@size, varargin, "uniformoutput", false); ## TODO: dat = iddata (ones (100, 3)); ## dat = cat (1, dat, zeros (4, 3), dat) ## default values for metadata ## some of them are overwritten in the switch statement below expname = tmp(1).expname; outname = tmp(1).outname; outunit = tmp(1).outunit; inname = tmp(1).inname; inunit = tmp(1).inunit; switch (dim) case 1 # vertcat - catenate samples check_experiments (tmp, e); check_outputs (tmp, p); check_inputs (tmp, m); y = cellfun (@vertcat, tmp.y, "uniformoutput", false); u = cellfun (@vertcat, tmp.u, "uniformoutput", false); ## note that this also works for time series (u = {}) case 2 # horzcat - catenate channels check_experiments (tmp, e); check_samples (n); y = cellfun (@horzcat, tmp.y, "uniformoutput", false); u = cellfun (@horzcat, tmp.u, "uniformoutput", false); outname = vertcat (tmp.outname); outunit = vertcat (tmp.outunit); inname = vertcat (tmp.inname); inunit = vertcat (tmp.inunit); case 3 # merge - catenate experiments check_outputs (tmp, p); check_inputs (tmp, m); y = vertcat (tmp.y); u = vertcat (tmp.u); expname = vertcat (tmp.expname); otherwise error ("iddata: cat: '%d' is an invalid dimension", dim); endswitch dat = iddata (y, u); ## copy metadata dat.expname = expname; dat.outname = outname; dat.outunit = outunit; dat.inname = inname; dat.inunit = inunit; endfunction function check_experiments (tmp, e) if (numel (e) > 1 && ! isequal (e{:})) # isequal doesn't work with less than 2 arguments error ("iddata: cat: number of experiments don't match [%s]", \ num2str (cell2mat (e), "%d ")); endif if (! compare_strings (tmp.expname)) warning ("iddata: cat: experiment names don't match") endif endfunction function check_outputs (tmp, p) if (numel (p) > 1 && ! isequal (p{:})) error ("iddata: cat: number of outputs don't match [%s]", \ num2str (cell2mat (p), "%d ")); endif if (! compare_strings (tmp.outname)) warning ("iddata: cat: output names don't match") endif if (! compare_strings (tmp.outunit)) warning ("iddata: cat: output units don't match") endif endfunction function check_inputs (tmp, m) if (numel (m) > 1 && ! isequal (m{:})) error ("iddata: cat: number of inputs don't match [%s]", \ num2str (cell2mat (m), "%d ")); endif if (! compare_strings (tmp.inname)) warning ("iddata: cat: input names don't match") endif if (! compare_strings (tmp.inunit)) warning ("iddata: cat: input units don't match") endif endfunction function check_samples (n) if (numel (n) > 1 && ! isequal (n{:})) error ("iddata: cat: number of samples don't match %s", \ mat2str (vertcat (n{:}), 10)); endif ## TODO: check sampling times endfunction ## kind of strcmp for more than two arguments ## return true if all cells of strings are equal ## and false otherwise function bool = compare_strings (str, varargin) if (nargin > 1) ## compare n-th string of first cell with n-th string of remaining cells tmp = cellfun (@(x) strcmp (str, x), varargin, "uniformoutput", false); ## check whether all strings of each pair are equal tmp = cellfun (@all, tmp); ## check whether all pairs are equal bool = all (tmp); else ## one or no cell at all is always equal to itself bool = true; endif endfunction %!error (cat (1, iddata (1, 1), iddata ({2, 3}, {2, 3})));