1## Copyright (C) 2013 Carnë Draug <carandraug@octave.org> 2## 3## This program is free software; you can redistribute it and/or modify it under 4## the terms of the GNU General Public License as published by the Free Software 5## Foundation; either version 3 of the License, or (at your option) any later 6## version. 7## 8## This program is distributed in the hope that it will be useful, but WITHOUT 9## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 11## details. 12## 13## You should have received a copy of the GNU General Public License along with 14## this program; if not, see <http://www.gnu.org/licenses/>. 15 16## -*- texinfo -*- 17## @deftypefn {Function File} {@var{blk_size} =} bestblk (@var{IMS}) 18## @deftypefnx {Function File} {@var{blk_size} =} bestblk (@var{IMS}, @var{max}) 19## @deftypefnx {Function File} {[@var{Mb}, @var{Nb}, @dots{}] =} bestblk (@dots{}) 20## Calculate block best size for block processing. 21## 22## Given a matrix of size @var{IMS}, calculates the largest size for distinct 23## blocks @var{blk_size}, that minimize padding and is smaller than or equal to 24## @var{k} (defaults to 100) 25## 26## The output @var{blk_size} is a row vector for the block size. If there are 27## multiple output arguments, the number of rows is assigned to the first 28## (@var{Mb}), and the number of columns to the second (@var{Nb}), etc. 29## 30## To determine @var{blk_size}, the following is performed for each 31## dimension: 32## 33## @enumerate 34## @item 35## If dimension @var{IMS} is less or equal than @var{k}, it returns the 36## dimension value. 37## 38## @item 39## If not, find the highest value between @code{min (dimension/10, k/2)} 40## which minimizes padding. 41## 42## @end enumerate 43## 44## @seealso{blockproc, col2im, im2col} 45## @end deftypefn 46 47function [varargout] = bestblk (ims, k = 100) 48 49 if (nargin < 1 || nargin > 2) 50 print_usage (); 51 elseif (! isnumeric (ims) || ! isvector (ims) || any (ims(:) < 1)) 52 error("bestblk: IMS must be a numeric vector of positive integers."); 53 elseif (numel (ims) < 2) 54 error ("bestblk: IMS must have at least 2 elements"); 55 elseif (! isnumeric (k) || ! isscalar (k) || k < 1) 56 error ("bestblk: K must be a positive scalar"); 57 endif 58 59 ims = floor (ims(:).'); 60 k = floor (k); 61 62 out = zeros (size (ims)); 63 for dim = 1:numel (ims) 64 if (ims(dim) <= k) 65 out(dim) = ims(dim); 66 else 67 possible = k:-1:min (ims(dim) /10, k /2); 68 [~, ind] = min (mod (-ims(dim), possible)); 69 out(dim) = possible(ind); 70 endif 71 endfor 72 73 if (nargout <= 1) 74 varargout{1} = out; 75 else 76 varargout = mat2cell (out', ones (1, numel (out))); 77 endif 78 79endfunction 80 81%!demo 82%! siz = bestblk ([200; 10], 50); 83%! disp (siz) 84 85%!error <numeric vector> bestblk ("string") 86%!error <positive scalar> bestblk ([100 200], "string") 87%!error <2 elements> bestblk ([100], 5) 88 89%!assert (bestblk ([ 10 12], 2), [ 2 2]); 90%!assert (bestblk ([ 10 12], 3), [ 2 3]); 91%!assert (bestblk ([300 100], 150), [150 100]); 92%!assert (bestblk ([256 128], 17), [ 16 16]); 93 94## make sure we really pick the highest one 95%!assert (bestblk ([ 17 17], 3), [ 3 3]); 96 97## Test default 98%!assert (bestblk ([230 470]), bestblk ([230 470], 100)) 99 100## Test N-dimensional 101%!assert (bestblk ([10 12 10], 3), [2 3 2]); 102%!assert (bestblk ([ 9 12 9], 3), [3 3 3]); 103%!assert (bestblk ([10 12 10 11], 5), [5 4 5 4]); 104