changeset 811:547221feb08f

conndef: simplify code to generate N-dimensional minimal connectity array. * conndef.m: rewrite section to create N-dimensional minimal connectivity array; follow guidelines for documentation style, error messages, and whitespace; check connectivity type even for 1 dimensional arrays; add tests for input check and 4 dimensional minimal connectivity.
author Carnë Draug <carandraug@octave.org>
date Mon, 28 Oct 2013 17:07:35 +0000
parents b059579d8d41
children 94c119801c1c
files inst/conndef.m
diffstat 1 files changed, 76 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/inst/conndef.m
+++ b/inst/conndef.m
@@ -14,81 +14,113 @@
 ## this program; if not, see <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {@var{conn} = } conndef (@var{num_dims}, @var{type})
-## Creates a connectivity array.
+## @deftypefn {Function File} {} conndef (@var{num_dims}, @var{type})
+## Create connectivity array.
 ##
-## @code{conn=conndef(num_dims,type)} creates a connectivity array
-## (@var{CONN}) of @var{num_dims} dimensions and which type is defined
-## by @var{type} as follows:
-## @table @code
+## Creates a binary matrix of @var{num_dims} dimensions for morphological
+## operations, where elements with a value of 1 are considered connected
+## to the center element (a connectivity array).
+##
+## There are two possible @var{type}s of connectivity array, defined with
+## the strings:
+## @table @qcode
 ## @item minimal
 ## Neighbours touch the central element on a (@var{num_dims}-1)-dimensional
 ## surface.
 ## @item maximal
 ## Neighbours touch the central element in any way. Equivalent to
-## @code{ones(repmat(3,1,@var{num_dims}))}.
+## @code{ones (repmat (3, 1, @var{num_dims}))}.
 ## @end table
 ##
-## @seealso{iptcheckconn}
+## @seealso{iptcheckconn, strel}
 ## @end deftypefn
 
 function conn = conndef (num_dims, conntype)
 
-  if (nargin!=2)
-    print_usage;
-  elseif (!isnumeric (num_dims) || !isscalar (num_dims) || num_dims <= 0 || fix (num_dims) != num_dims)
-    error ("number of dimensions must be a positive integer.");
-  elseif (!ischar (conntype))
-    error ("second argument must be a string with type of connectivity.")
+  if (nargin != 2)
+    print_usage ();
+  elseif (! isnumeric (num_dims) || ! isscalar (num_dims) || num_dims <= 0 ||
+          fix (num_dims) != num_dims)
+    error ("conndef: NUM_DIMS must be a positive integer");
+  elseif (! ischar (conntype))
+    error ("conndef: CONNTYPE must be a string with type of connectivity")
   endif
 
-  ## support for 1 dimension does not exist in Matlab where num_dims must be >= 2
-  if (num_dims == 1)
-    conn = [1; 1; 1];
-  ## matlab is case insensitive when checking the type
-  elseif (strcmpi (conntype, "minimal"))
-    if (num_dims == 2)
+  if (strcmpi (conntype, "minimal"))
+    if (num_dims == 1)
+      ## This case does not exist in Matlab
+      conn = [1; 1; 1];
+    elseif (num_dims == 2)
+      ## The general case with the for loop below would also work for
+      ## 2D but it's such a simple case we have it like this, no need
+      ## to make it hard to read.
       conn = [0 1 0
               1 1 1
               0 1 0];
     else
       conn   = zeros (repmat (3, 1, num_dims));
-      idx    = {};
-      idx{1} = 1:3;
-      for i = 2:num_dims
-        idx{i} = 2;
-      endfor
-      conn(idx{:}) = 1;
-      for i = 2:num_dims
-        idx{i-1}     = 2;
-        idx{i}       = 1:3;
+      template_idx = repmat ({2}, [num_dims 1]);
+      for dim = 1:num_dims
+        idx = template_idx;
+        idx(dim) = ":";
         conn(idx{:}) = 1;
       endfor
     endif
 
   elseif (strcmpi (conntype, "maximal"))
-    conn = ones (repmat (3, 1, num_dims));
+    if (num_dims == 1)
+      ## This case does not exist in Matlab
+      conn = [1; 1; 1];
+    else
+      conn = ones (repmat (3, 1, num_dims));
+    endif
+
   else
-    error("invalid type of connectivity '%s'.", conntype);
+    error ("conndef: invalid type of connectivity '%s'.", conntype);
   endif
 
 endfunction
 
 %!demo
-%! conndef(2,'minimal')
-%! % Create a 2-D minimal connectivity array
+%! ## Create a 2-D minimal connectivity array
+%! conndef (2, "minimal")
+
+%!assert (conndef (1, "minimal"), [1; 1; 1]);
+%!assert (conndef (2, "minimal"), [0 1 0; 1 1 1; 0 1 0]);
 
-%!assert(conndef(1,'minimal'), [1;1;1]);
-%!assert(conndef(2,'minimal'), [0,1,0;1,1,1;0,1,0]);
+%!test
+%! C = zeros (3, 3, 3);
+%! C(:,2,2) = 1;
+%! C(2,:,2) = 1;
+%! C(2,2,:) = 1;
+%! assert (conndef (3, "minimal"), C);
 
 %!test
-%! C=zeros(3,3);
-%! C(2,2,1)=1;
-%! C(2,2,3)=1;
-%! C(:,:,2)=[0,1,0;1,1,1;0,1,0];
-%! assert(conndef(3,'minimal'), C);
+%! C = zeros (3, 3, 3, 3);
+%! C(:,:,2,1) = [0   0   0
+%!               0   1   0
+%!               0   0   0];
+%! C(:,:,1,2) = [0   0   0
+%!               0   1   0
+%!               0   0   0];
+%! C(:,:,2,2) = [0   1   0
+%!               1   1   1
+%!               0   1   0];
+%! C(:,:,3,2) = [0   0   0
+%!               0   1   0
+%!               0   0   0];
+%! C(:,:,2,3) = [0   0   0
+%!               0   1   0
+%!               0   0   0];
+%! assert (conndef (4, "minimal"), C);
 
-%!assert(conndef(1,'maximal'), ones(3,1));
-%!assert(conndef(2,'maximal'), ones(3,3));
-%!assert(conndef(3,'maximal'), ones(3,3,3));
-%!assert(conndef(4,'maximal'), ones(3,3,3,3));
+%!assert (conndef (1, "maximal"), ones (3, 1));
+%!assert (conndef (2, "maximal"), ones (3, 3));
+%!assert (conndef (3, "maximal"), ones (3, 3, 3));
+%!assert (conndef (4, "maximal"), ones (3, 3, 3, 3));
+
+%!error conndef (-2, "minimal")
+%!error conndef (char (2), "minimal")
+%!error <type of connectivity> conndef (3, "invalid")
+%!error conndef ("minimal", 3)
+