Mercurial > hg > octave-avbm
changeset 10122:9d1a14e12431
Update docs and add tests for container functions
author | Thorsten Meyer <thorsten.meyier@gmx.de> |
---|---|
date | Sun, 17 Jan 2010 13:31:42 +0100 |
parents | b5cc666da6ca |
children | 8590f3c51868 |
files | doc/ChangeLog doc/interpreter/container.txi scripts/ChangeLog scripts/general/celldisp.m scripts/general/structfun.m scripts/miscellaneous/getfield.m scripts/miscellaneous/orderfields.m scripts/miscellaneous/setfield.m scripts/miscellaneous/substruct.m src/ChangeLog src/DLD-FUNCTIONS/cellfun.cc src/ov-cell.cc src/ov-struct.cc |
diffstat | 13 files changed, 294 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,8 @@ +2010-01-17 Thorsten Meyer <thorsten.meyier@gmx.de> + + * interpreter/container.txi (Creating Cell Arrays): Add + docstring for cellslices function. + 2010-01-09 John W. Eaton <jwe@octave.org> * interpreter/munge-texi.cc: Avoid C-style casts.
--- a/doc/interpreter/container.txi +++ b/doc/interpreter/container.txi @@ -628,12 +628,14 @@ As an alternative to creating empty cell arrays, and then filling them, it is possible to convert numerical arrays into cell arrays using the -@code{num2cell} and @code{mat2cell} functions. +@code{num2cell}, @code{mat2cell} and @code{cellslices} functions. @DOCSTRING(num2cell) @DOCSTRING(mat2cell) +@DOCSTRING(cellslices) + @node Indexing Cell Arrays @subsection Indexing Cell Arrays
--- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,11 @@ +2010-01-17 Thorsten Meyer <thorsten.meyier@gmx.de> + + * general/celldisp.m: Add example, add demo. + + * general/structfun.m, miscellaneous/getfield.m, + miscellaneous/orderfields.m, miscellaneous/setfield.m, + miscellaneous/substruct.m: Update documentation string. + 2010-01-16 David Bateman <dbateman@free.fr> * plot/__go_draw_axes__.m (next_marker): New function to find a
--- a/scripts/general/celldisp.m +++ b/scripts/general/celldisp.m @@ -20,7 +20,24 @@ ## @deftypefn {Function File} {} celldisp (@var{c}, @var{name}) ## Recursively display the contents of a cell array. By default the values ## are displayed with the name of the variable @var{c}. However, this name -## can be replaced with the variable @var{name}. +## can be replaced with the variable @var{name}. For example: +## +## @example +## @group +## c = @{1, 2, @{31, 32@}@}; +## celldisp(c, "b") +## @result{} +## b@{1@} = +## 1 +## b@{2@} = +## 2 +## b@{3@}@{1@} = +## 31 +## b@{3@}@{2@} = +## 32 +## @end group +## @end example +## ## @seealso{disp} ## @end deftypefn @@ -60,3 +77,7 @@ s = sprintf("%i", i); endif endfunction + +%!demo +%! c = {1, 2, {31, 32}}; +%! celldisp(c, "b") \ No newline at end of file
--- a/scripts/general/structfun.m +++ b/scripts/general/structfun.m @@ -18,7 +18,7 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {} structfun (@var{func}, @var{s}) -## @deftypefnx {Function File} {[@var{a}, @var{b}] =} structfun (@dots{}) +## @deftypefnx {Function File} {[@var{a}, @dots{}] =} structfun (@dots{}) ## @deftypefnx {Function File} {} structfun (@dots{}, "ErrorHandler", @var{errfunc}) ## @deftypefnx {Function File} {} structfun (@dots{}, "UniformOutput", @var{val}) ## @@ -35,7 +35,7 @@ ## ## If the parameter "UniformOutput" is set to true (the default), then the function ## must return a single element which will be concatenated into the -## return value. If "UniformOutput" is false, the outputs placed in a structure +## return value. If "UniformOutput" is false, the outputs are placed into a structure ## with the same fieldnames as the input structure. ## ## @example @@ -44,10 +44,15 @@ ## s.name2 = "Jill Jones"; ## structfun (@@(x) regexp (x, '(\w+)$', "matches")@{1@}, s, ## "UniformOutput", false) +## @result{} +## @{ +## name1 = Smith +## name2 = Jones +## @} ## @end group ## @end example ## -## Given the parameter "ErrorHandler", then @var{errfunc} defines a function to +## Given the parameter "ErrorHandler", @var{errfunc} defines a function to ## call in case @var{func} generates an error. The form of the function is ## ## @example @@ -58,7 +63,9 @@ ## @var{func}, given by @var{se}. This is a structure with the elements ## "identifier", "message" and "index", giving respectively the error ## identifier, the error message, and the index into the input arguments -## of the element that caused the error. +## of the element that caused the error. For an example on how to use +## an error handler, @pxref{doc-cellfun, @code{cellfun}}. +## ## @seealso{cellfun, arrayfun} ## @end deftypefn
--- a/scripts/miscellaneous/getfield.m +++ b/scripts/miscellaneous/getfield.m @@ -19,13 +19,13 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{v1}, @dots{}] =} getfield (@var{s}, @var{key}, @dots{}) -## Extract fields from a structure. For example +## Extract a field from a structure (or a nested structure). For example ## ## @example ## @group ## ss(1,2).fd(3).b = 5; ## getfield (ss, @{1,2@}, "fd", @{3@}, "b") -## @result{} ans = 5 +## @result{} ans = 5 ## @end group ## @end example ## @@ -36,6 +36,8 @@ ## @group ## i1 = @{1,2@}; i2 = "fd"; i3 = @{3@}; i4= "b"; ## ss(i1@{:@}).(i2)(i3@{:@}).(i4) +## @result{} ans = 5 +## ## @end group ## @end example ## @seealso{setfield, rmfield, isfield, isstruct, fieldnames, struct}
--- a/scripts/miscellaneous/orderfields.m +++ b/scripts/miscellaneous/orderfields.m @@ -17,15 +17,70 @@ ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- -## @deftypefn {Function File} {[@var{t}, @var{p}] =} orderfields (@var{s1}, @var{s2}) -## Return a struct with fields arranged alphabetically or as specified -## by @var{s2} and a corresponding permutation vector. +## @deftypefn {Function File} {[@var{t}, @var{p}] =} orderfields (@var{s1}[, @var{s2}]) +## Return a copy of @var{s1} with fields arranged alphabetically or +## as specified by @var{s2}. ## ## Given one struct, arrange field names in @var{s1} alphabetically. ## -## Given two structs, arrange field names in @var{s1} as they appear -## in @var{s2}. The second argument may also specify the order in -## a permutation vector or a cell array of strings. +## If the second argument is a struct, arrange field names in @var{s1} +## as they appear in @var{s2}. The second argument may also specify the +## order in a permutation vector or a cell array of strings containing +## the fieldnames of @var{s1} in the desired order. +## +## The optional second output argument @var{p} is assigned the permutation vector +## which converts the original name order into the new name order. +## +## Examples: +## +## @example +## @group +## s = struct("d", 4, "b", 2, "a", 1, "c", 3); +## t1 = orderfields(s) +## @result{} t1 = +## @{ +## a = 1 +## b = 2 +## c = 3 +## d = 4 +## @} +## @end group +## @group +## t = struct("d", @{@}, "c", @{@}, "b", "a", @{@}); +## t2 = orderfields(s, t) +## @result{} t2 = +## @{ +## d = 4 +## c = 3 +## b = 2 +## a = 1 +## @} +## @end group +## @group +## t3 = orderfields(s, [3, 2, 4, 1]); +## @result{} t3 = +## @{ +## a = 1 +## b = 2 +## c = 3 +## d = 4 +## @} +## @end group +## @group +## [t4, p] = orderfields(s, @{"d", "c", "b", "a"@}) +## @result{} t4 = @{ +## d = 4 +## c = 3 +## b = 2 +## a = 1 +## @} +## p = +## 1 +## 4 +## 2 +## 3 +## @end group +## @end example ## ## @seealso{getfield, rmfield, isfield, isstruct, fieldnames, struct} ## @end deftypefn @@ -113,9 +168,10 @@ %! assert (a(2).foo, 5) %! assert (a(2).bar, 6) %!test -%! a(2) = orderfields (b, [2 1]); +%! [a(2), p] = orderfields (b, [2 1]); %! assert (a(2).foo, 5) %! assert (a(2).bar, 6) +%! assert (p, [2; 1]); %!test %! a(2) = orderfields (b, fieldnames (a)); %! assert (a(2).foo, 5)
--- a/scripts/miscellaneous/setfield.m +++ b/scripts/miscellaneous/setfield.m @@ -19,23 +19,24 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{k1}, @dots{}, @var{v1}] =} setfield (@var{s}, @var{k1}, @var{v1}, @dots{}) -## Set field members in a structure. +## Set a field member in a (nested) structure array. For example: ## ## @example ## @group ## oo(1,1).f0 = 1; ## oo = setfield (oo, @{1,2@}, "fd", @{3@}, "b", 6); ## oo(1,2).fd(3).b == 6 -## @result{} ans = 1 +## @result{} ans = 1 ## @end group ## @end example ## -## Note that this function could be written +## Note that the same result as in the above example could be achieved by: ## ## @example ## @group ## i1 = @{1,2@}; i2 = "fd"; i3 = @{3@}; i4 = "b"; -## oo(i1@{:@}).(i2)(i3@{:@}).(i4) == 6; +## oo(i1@{:@}).(i2)(i3@{:@}).(i4) == 6 +## @result{} ans = 1 ## @end group ## @end example ## @seealso{getfield, rmfield, isfield, isstruct, fieldnames, struct}
--- a/scripts/miscellaneous/substruct.m +++ b/scripts/miscellaneous/substruct.m @@ -19,7 +19,27 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {} substruct (@var{type}, @var{subs}, @dots{}) ## Create a subscript structure for use with @code{subsref} or -## @code{subsasgn}. +## @code{subsasgn}. For example: +## +## @example +## @group +## idx = substruct("()", @{3, ":"@}) +## @result{} +## idx = +## @{ +## type = () +## subs = +## @{ +## [1,1] = 3 +## [1,2] = : +## @} +## @} +## x = [1, 2, 3; 4, 5, 6; 7, 8, 9]; +## subsref(x, idx) +## @result{} ans = +## 7 8 9 +## @end group +## @end example ## @seealso{subsref, subsasgn} ## @end deftypefn
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2010-01-17 Thorsten Meyer <thorsten.meyier@gmx.de> + + * ov-cell.cc (Fstruct2cell): Add example, add test. + * DLD-FUNCTIONS/cellfun.cc (Fcellfun, Fnum2cell), ov-struct.cc + (Fisstruct): Fix docstring. + * DLD-FUNCTIONS/cellfun.cc (Fcellslices, Fisfield, Ffieldnames, + Frmfield): Add test. + * ov-struct.cc (Fcell2struct): Fix docstring, add test. + 2010-01-16 David Bateman <dbateman@free.fr> * graphics.h.in (line::properties, surface::properties,
--- a/src/DLD-FUNCTIONS/cellfun.cc +++ b/src/DLD-FUNCTIONS/cellfun.cc @@ -230,7 +230,7 @@ @deftypefnx {Loadable Function} {} cellfun (\"isclass\", @var{c}, @var{class})\n\ @deftypefnx {Loadable Function} {} cellfun (@var{func}, @var{c})\n\ @deftypefnx {Loadable Function} {} cellfun (@var{func}, @var{c}, @var{d})\n\ -@deftypefnx {Loadable Function} {[@var{a}, @var{b}] =} cellfun (@dots{})\n\ +@deftypefnx {Loadable Function} {[@var{a}, @dots{}] =} cellfun (@dots{})\n\ @deftypefnx {Loadable Function} {} cellfun (@dots{}, 'ErrorHandler', @var{errfunc})\n\ @deftypefnx {Loadable Function} {} cellfun (@dots{}, 'UniformOutput', @var{val})\n\ \n\ @@ -268,19 +268,37 @@ @example\n\ @group\n\ cellfun (@@atan2, @{1, 0@}, @{0, 1@})\n\ -@result{}ans = [1.57080 0.00000]\n\ + @result{}ans = [1.57080 0.00000]\n\ @end group\n\ @end example\n\ \n\ -Note that the default output argument is an array of the same size as the\n\ +The number of output arguments of @code{cellfun} matches the number of output\n\ +arguments of the function. The outputs of the function will be collected into the\n\ +output arguments of @code{cellfun} like this:\n\ +\n\ +@example\n\ +@group\n\ +function [a, b] = twoouts (x)\n\ + a = x;\n\ + b = x*x;\n\ +endfunction\n\ +[aa, bb] = cellfun(@@twoouts, @{1, 2, 3@})\n\ + @result{}\n\ + aa = \n\ + 1 2 3\n\ + bb =\n\ + 1 4 9\n\ +@end group\n\ +@end example\n\ +Note that per default the output argument(s) are arrays of the same size as the\n\ input arguments.\n\ Input arguments that are singleton (1x1) cells will be automatically expanded\n\ to the size of the other arguments.\n\ \n\ If the parameter 'UniformOutput' is set to true (the default), then the function\n\ -must return a single element which will be concatenated into the\n\ -return value. If 'UniformOutput' is false, the outputs are concatenated in\n\ -a cell array. For example\n\ +must return scalars which will be concatenated into the\n\ +return array(s). If 'UniformOutput' is false, the outputs are concatenated into\n\ +a cell array (or cell arrays). For example\n\ \n\ @example\n\ @group\n\ @@ -1084,7 +1102,31 @@ @deftypefnx {Loadable Function} {@var{c} =} num2cell (@var{m}, @var{dim})\n\ Convert the matrix @var{m} to a cell array. If @var{dim} is defined, the\n\ value @var{c} is of dimension 1 in this dimension and the elements of\n\ -@var{m} are placed in slices in @var{c}.\n\ +@var{m} are placed into @var{c} in slices. For example:\n\ +\n\ +@example\n\ +@group\n\ +num2cell([1,2;3,4])\n\ + @result{} ans =\n\ + @{\n\ + [1,1] = 1\n\ + [2,1] = 3\n\ + [1,2] = 2\n\ + [2,2] = 4\n\ + @}\n\ +num2cell([1,2;3,4],1)\n\ + @result{} ans =\n\ + @{\n\ + [1,1] =\n\ + 1\n\ + 3\n\ + [1,2] =\n\ + 2\n\ + 4\n\ + @}\n\ +@end group\n\ +@end example\n\ +\n\ @seealso{mat2cell}\n\ @end deftypefn") { @@ -1538,7 +1580,14 @@ return retval; } - + +/* +%!test +%! m = [1, 2, 3, 4; 5, 6, 7, 8; 9, 10, 11, 12]; +%! c = cellslices (m, [1, 2], [2, 3]); +%! assert (c, {[1, 2; 5, 6; 9, 10], [2, 3; 6, 7; 10, 11]}); +*/ + /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/ov-cell.cc +++ b/src/ov-cell.cc @@ -1339,7 +1339,30 @@ Create a new cell array from the objects stored in the struct object.\n\ If @var{f} is the number of fields in the structure, the resulting\n\ cell array will have a dimension vector corresponding to\n\ -@code{[@var{F} size(@var{S})]}.\n\ +@code{[@var{F} size(@var{S})]}. For example:\n\ +\n\ +@example\n\ +@group\n\ + s = struct('name', @{'Peter', 'Hannah', 'Robert'@}, 'age', @{23, 16, 3@});\n\ + c = struct2cell(s)\n\ + @result{} c = @{1x1x3 Cell Array@}\n\ + c(1,1,:)(:)\n\ + @result{} ans =\n\ + @{\n\ + [1,1] = Peter\n\ + [2,1] = Hannah\n\ + [3,1] = Robert\n\ + @}\n\ + c(2,1,:)(:)\n\ + @result{} ans =\n\ + @{\n\ + [1,1] = 23\n\ + [2,1] = 16\n\ + [3,1] = 3\n\ + @}\n\ +@end group\n\ +@end example\n\ +\n\ @seealso{cell2struct, fieldnames}\n\ @end deftypefn") { @@ -1402,6 +1425,18 @@ return retval; } +/* +%!test +%! keys = cellstr (char (floor (rand (11,10)*24+65)))'; +%! vals = cellfun(@(x) mat2cell(rand (19,1), ones (19,1), 1), ... +%! mat2cell([1:11]', ones(11,1), 1), "uniformoutput", false)'; +%! s = struct ([keys; vals]{:}); +%! t = cell2struct ([vals{:}], keys, 2); +%! assert (s, t); +%! assert (struct2cell (s), [vals{:}]'); +%! assert (fieldnames (s), keys'); +*/ + mxArray * octave_cell::as_mxArray (void) const {
--- a/src/ov-struct.cc +++ b/src/ov-struct.cc @@ -837,7 +837,8 @@ DEFUN (isstruct, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} isstruct (@var{expr})\n\ -Return 1 if the value of the expression @var{expr} is a structure.\n\ +Return 1 if the value of the expression @var{expr} is a structure\n\ +(or a structure array).\n\ @end deftypefn") { octave_value retval; @@ -886,6 +887,13 @@ return retval; } +/* +%!# test preservation of fieldname order +%!test +%! x(3).d=1; x(2).a=2; x(1).b=3; x(2).c=3; +%! assert(fieldnames(x), {"d"; "a"; "b"; "c"}); +*/ + DEFUN (isfield, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} isfield (@var{expr}, @var{name})\n\ @@ -940,6 +948,18 @@ return retval; } +/* +%!# test isfield +%!test +%! x(3).d=1; x(2).a=2; x(1).b=3; x(2).c=3; +%! assert (isfield (x, "b")); +%!assert( isfield( struct("a", "1"), "a")); +%!assert( isfield( {1}, "c"), logical (0)); +%!assert( isfield( struct("a", "1"), 10), logical (0)); +%!assert( isfield( struct("a", "b"), "a "), logical (0)); + +*/ + // Check that the dimensions of the input arguments are correct. static bool @@ -1014,11 +1034,11 @@ 185, 170, 168@},\n\ @{'Name','Height'@}, 1);\n\ A(1)\n\ -@result{} ans =\n\ - @{\n\ - Height = 185\n\ - Name = Peter\n\ - @}\n\ + @result{} ans =\n\ + @{\n\ + Name = Peter\n\ + Height = 185\n\ + @}\n\ \n\ @end group\n\ @end example\n\ @@ -1187,14 +1207,27 @@ return retval; } +/* +%!# test cell2struct versus struct2cell +%!test +%! keys = cellstr (char (floor (rand (100,10)*24+65)))'; +%! vals = mat2cell(rand (100,1), ones (100,1), 1)'; +%! s = struct ([keys; vals]{:}); +%! t = cell2struct (vals, keys, 2); +%! assert (s, t); +%! assert (struct2cell (s), vals'); +%! assert (fieldnames (s), keys'); +*/ + + // So we can call Fcellstr directly. extern octave_value_list Fcellstr (const octave_value_list& args, int); DEFUN (rmfield, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} rmfield (@var{s}, @var{f})\n\ -Remove field @var{f} from the structure @var{s}. If @var{f} is a\n\ -cell array of character strings or a character array, remove the\n\ +Return a copy of the structure (array) @var{s} with the field @var{f} removed.\n\ +If @var{f} is a cell array of strings or a character array, remove the\n\ named fields.\n\ @seealso{cellstr, iscellstr, setfield}\n\ @end deftypefn") @@ -1238,6 +1271,15 @@ return retval; } +/* +%!# test rmfield +%!test +%! x(3).d=1; x(2).a=2; x(1).b=3; x(2).c=3; x(6).f="abc123"; +%! y = rmfield (x, {"a", "f"}); +%! assert (fieldnames (y), {"d"; "b"; "c"}); +%! assert (size (y), [1, 6]); +*/ + bool octave_struct::save_ascii (std::ostream& os) {