]> Creatis software - CreaPhase.git/blob - octave_packages/m/general/structfun.m
update packages
[CreaPhase.git] / octave_packages / m / general / structfun.m
1 ## Copyright (C) 2007-2012 David Bateman
2 ## Copyright (C) 2010 VZLU Prague
3 ##
4 ## This file is part of Octave.
5 ##
6 ## Octave is free software; you can redistribute it and/or modify it
7 ## under the terms of the GNU General Public License as published by
8 ## the Free Software Foundation; either version 3 of the License, or (at
9 ## your option) any later version.
10 ##
11 ## Octave is distributed in the hope that it will be useful, but
12 ## WITHOUT ANY WARRANTY; without even the implied warranty of
13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ## General Public License for more details.
15 ##
16 ## You should have received a copy of the GNU General Public License
17 ## along with Octave; see the file COPYING.  If not, see
18 ## <http://www.gnu.org/licenses/>.
19
20 ## -*- texinfo -*-
21 ## @deftypefn  {Function File} {} structfun (@var{func}, @var{S})
22 ## @deftypefnx {Function File} {[@var{A}, @dots{}] =} structfun (@dots{})
23 ## @deftypefnx {Function File} {} structfun (@dots{}, "ErrorHandler", @var{errfunc})
24 ## @deftypefnx {Function File} {} structfun (@dots{}, "UniformOutput", @var{val})
25 ##
26 ## Evaluate the function named @var{name} on the fields of the structure
27 ## @var{S}.  The fields of @var{S} are passed to the function @var{func}
28 ## individually.
29 ##
30 ## @code{structfun} accepts an arbitrary function @var{func} in the form of
31 ## an inline function, function handle, or the name of a function (in a
32 ## character string).  In the case of a character string argument, the
33 ## function must accept a single argument named @var{x}, and it must return
34 ## a string value.  If the function returns more than one argument, they are
35 ## returned as separate output variables.
36 ##
37 ## If the parameter "UniformOutput" is set to true (the default), then the
38 ## function
39 ## must return a single element which will be concatenated into the
40 ## return value.  If "UniformOutput" is false, the outputs are placed into a
41 ## structure
42 ## with the same fieldnames as the input structure.
43 ##
44 ## @example
45 ## @group
46 ## s.name1 = "John Smith";
47 ## s.name2 = "Jill Jones";
48 ## structfun (@@(x) regexp (x, '(\w+)$', "matches")@{1@}, s,
49 ##            "UniformOutput", false)
50 ## @result{}
51 ##    @{
52 ##      name1 = Smith
53 ##      name2 = Jones
54 ##    @}
55 ## @end group
56 ## @end example
57 ##
58 ## Given the parameter "ErrorHandler", @var{errfunc} defines a function to
59 ## call in case @var{func} generates an error.  The form of the function is
60 ##
61 ## @example
62 ## function [@dots{}] = errfunc (@var{se}, @dots{})
63 ## @end example
64 ##
65 ## @noindent
66 ## where there is an additional input argument to @var{errfunc} relative to
67 ## @var{func}, given by @var{se}.  This is a structure with the elements
68 ## "identifier", "message" and "index", giving respectively the error
69 ## identifier, the error message, and the index into the input arguments
70 ## of the element that caused the error.  For an example on how to use
71 ## an error handler, @pxref{doc-cellfun, @code{cellfun}}.
72 ##
73 ## @seealso{cellfun, arrayfun, spfun}
74 ## @end deftypefn
75
76 function varargout = structfun (func, S, varargin);
77
78   if (nargin < 2)
79     print_usage ();
80   endif
81
82   nargs = length (varargin);
83
84   recognized_opts = {"UniformOutput", "ErrorHandler"};
85   uo_str = recognized_opts{1};
86
87   uniform_output = true;
88
89   while (nargs >= 2)
90     opt_match = strcmpi (varargin{nargs-1}, recognized_opts);
91     if (opt_match(1))
92       uniform_output = varargin{nargs};
93     endif
94     if (any (opt_match))
95       nargs -= 2;
96     else
97       break;
98     endif
99   endwhile
100
101   if (nargs > 0)
102     error ("structfun: invalid options");
103   endif
104
105   varargout = cell (max ([nargout, 1]), 1);
106   [varargout{:}] = cellfun (func, struct2cell (S), varargin{:});
107
108   if (! uniform_output)
109     varargout = cellfun ("cell2struct", varargout, {fieldnames(S)}, {1}, uo_str, false);
110   endif
111 endfunction
112
113
114 %!test
115 %! s.name1 = "John Smith";
116 %! s.name2 = "Jill Jones";
117 %! l.name1 = "Smith";
118 %! l.name2 = "Jones";
119 %! o = structfun (@(x) regexp (x, '(\w+)$', "matches"){1}, s,
120 %!                "UniformOutput", false);
121 %! assert (o, l);
122
123 %!function [a, b] = __twoouts (x)
124 %! a = x + x;
125 %! b = x * x;
126 %!endfunction
127
128 %!test
129 %! s = struct ("a", {1, 2, 3}, "b", {4, 5, 6});
130 %! c(1:2, 1, 1) = [2; 8];
131 %! c(1:2, 1, 2) = [4; 10];
132 %! c(1:2, 1, 3) = [6; 12];
133 %! d(1:2, 1, 1) = [1; 16];
134 %! d(1:2, 1, 2) = [4; 25];
135 %! d(1:2, 1, 3) = [9; 36];
136 %! [aa, bb] = structfun(@__twoouts, s);
137 %! assert(aa, c);
138 %! assert(bb, d);
139
140 %!test
141 %! s = struct ("a", {1, 2, 3}, "b", {4, 5, 6});
142 %! c = struct ("a", {2, 4, 6}, "b", {8, 10, 12});
143 %! d = struct ("a", {1, 4, 9}, "b", {16, 25, 36});
144 %! [aa, bb] = structfun(@__twoouts, s, "UniformOutput", false);
145 %! assert(aa, c);
146 %! assert(bb, d);