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} {} padarray (@var{A}, @var{padsize}) 18## @deftypefnx {Function File} {} padarray (@dots{}, @var{padval}) 19## @deftypefnx {Function File} {} padarray (@dots{}, @var{pattern}) 20## @deftypefnx {Function File} {} padarray (@dots{}, @var{direction}) 21## Pad array or matrix. 22## 23## Adds padding of length @var{padsize}, to a numeric matrix @var{A}. 24## @var{padsize} must be a vector of non-negative values, each of them 25## defining the length of padding to its corresponding dimension. For 26## example, if @var{padsize} is [4 5], it adds 4 rows (1st dimension) 27## and 5 columns (2nd dimension), to both the start and end of @var{A}. 28## 29## If there's less values in @var{padsize} than number of dimensions in @var{A}, 30## they're assumed to be zero. Singleton dimensions of @var{A} are also 31## padded accordingly (except when @var{pattern} is @qcode{"reflect"}). 32## 33## The values used in the padding can either be a scalar value @var{padval}, or 34## the name of a specific @var{pattern}. Available patterns are: 35## 36## @table @asis 37## @item @qcode{"zeros"} (default) 38## Pads with the value 0 (same as passing a @var{padval} of 0). This is the 39## default. 40## 41## @item @qcode{"circular"} 42## Pads with a circular repetition of elements in @var{A} (similar to 43## tiling @var{A}). 44## 45## @item @qcode{"replicate"} 46## Pads replicating the values at the border of @var{A}. 47## 48## @item @qcode{"symmetric"} 49## Pads with a mirror reflection of @var{A}. 50## 51## @item @qcode{"reflect"} 52## Same as "symmetric", but the borders are not used in the padding. Because 53## of this, it is not possible to pad singleton dimensions. 54## 55## @end table 56## 57## By default, padding is done in both directions. To change this, 58## @var{direction} can be one of the following values: 59## 60## @table @asis 61## @item @qcode{"both"} (default) 62## Pad each dimension before the first element of @var{A} the number 63## of elements defined by @var{padsize}, and the same number again after 64## the last element. This is the default. 65## 66## @item @qcode{"pre"} 67## Pad each dimension before the first element of @var{A} the number of 68## elements defined by @var{padsize}. 69## 70## @item @qcode{"post"} 71## Pad each dimension after the last element of @var{A} the number of 72## elements defined by @var{padsize}. 73## 74## @end table 75## 76## @seealso{cat, flip, resize, prepad, postpad} 77## @end deftypefn 78 79function B = padarray(A, padsize, varargin) 80 81 if (nargin < 2 || nargin > 4) 82 print_usage (); 83 elseif (! isvector (padsize) || ! isnumeric (padsize) || any (padsize < 0) || 84 any (padsize != fix (padsize))) 85 error ("padarray: PADSIZE must be a vector of non-negative integers"); 86 endif 87 88 ## Assure padsize is a row vector 89 padsize = padsize(:).'; 90 91 if (! any (padsize)) 92 ## Nothing to do here 93 B = A; 94 return 95 endif 96 97 ## Default values 98 padval = 0; 99 pattern = ""; 100 direction = "both"; 101 102 ## There won't be more than 2 elements in varargin 103 ## We have to support setting the padval (shape) and direction in any 104 ## order. Both examples must work: 105 ## padarray (A, padsize, "circular", "pre") 106 ## padarray (A, padsize, "pre", "circular") 107 for opt = 1:numel(varargin) 108 val = varargin{opt}; 109 if (ischar (val)) 110 if (any (strcmpi (val, {"pre", "post", "both"}))) 111 direction = val; 112 elseif (any (strcmpi (val, {"circular", "replicate", "reflect", "symmetric"}))) 113 pattern = val; 114 elseif (strcmpi (val, "zeros")) 115 padval = 0; 116 else 117 error ("padarray: unrecognized string option `%s'", val); 118 endif 119 elseif (isscalar (val)) 120 padval = val; 121 else 122 error ("padarray: PADVAL and DIRECTION must be a string or a scalar"); 123 endif 124 endfor 125 126 fancy_pad = false; 127 if (! isempty (pattern)) 128 fancy_pad = true; 129 endif 130 131 ## Check direction 132 pre = any (strcmpi (direction, {"pre", "both"})); 133 post = any (strcmpi (direction, {"post", "both"})); 134 135 ## Create output matrix 136 B_ndims = max ([numel(padsize) ndims(A)]); 137 A_size = size (A); 138 P_size = padsize; 139 A_size(end+1:B_ndims) = 1; # add singleton dimensions 140 P_size(end+1:B_ndims) = 0; # assume zero for missing dimensions 141 142 pre_pad_size = P_size * pre; 143 B_size = A_size + pre_pad_size + (P_size * post); 144 145 ## insert input matrix into output matrix 146 A_idx = cell (B_ndims, 1); 147 for dim = 1:B_ndims 148 A_idx{dim} = (pre_pad_size(dim) +1):(pre_pad_size(dim) + A_size(dim)); 149 endfor 150 if (post && ! pre && (padval == 0 || fancy_pad)) 151 ## optimization for post padding only with zeros 152 B = resize (A, B_size); 153 else 154 B = repmat (cast (padval, class (A)), B_size); 155 B(A_idx{:}) = A; 156 endif 157 158 if (fancy_pad) 159 ## Init a template "index all" cell array 160 template_idx = repmat ({":"}, [B_ndims 1]); 161 162 circular = replicate = symmetric = reflect = false; 163 switch (tolower (pattern)) 164 case "circular", circular = true; 165 case "replicate", replicate = true; 166 case "symmetric", symmetric = true; 167 case "reflect", reflect = true; 168 otherwise 169 error ("padarray: unknown PADVAL `%s'.", pattern); 170 endswitch 171 172 ## For a dimension of the input matrix of size 1, since reflect does 173 ## not includes the borders, it is not possible to pad singleton dimensions. 174 if (reflect && any ((! (A_size -1)) & P_size)) 175 error ("padarray: can't add %s padding to singleton dimensions", pattern); 176 endif 177 178 ## For symmetric and reflect: 179 ## 180 ## The idea is to split the padding into 3 different cases: 181 ## bits 182 ## Parts of the input matrix that are used for the padding. 183 ## In most user cases, there will be only this padding, 184 ## complete will be zero, and so bits will be equal to padsize. 185 ## complete 186 ## Number of full copies of the input matrix are used for 187 ## the padding (for reflect, "full" size is actually minus 1). 188 ## This is divided into pair and unpaired complete. In most 189 ## cases, this will be zero. 190 ## pair complete 191 ## Number of pairs of complete copies. 192 ## unpaired complete 193 ## This is either 1 or 0. If 1, then the complete copy closer 194 ## to the output borders has already been flipped so that if 195 ## there's bits used to pad as well, they don't need to be flipped. 196 ## 197 ## Reasoning pair and unpaired complete: when the pad is much larger 198 ## than the input matrix, we must pay we must pay special attention to 199 ## symmetric and reflect. In a normal case (the padding is smaller than 200 ## the input), we just use the flipped matrix to pad and we're done. 201 ## In other cases, if the input matrix is used multiple times on the 202 ## pad, every other copy of it must NOT be flipped (the padding must be 203 ## symmetric itself) or the padding will be circular. 204 205 if (reflect) 206 A_cut_size = A_size -1; 207 complete = floor (P_size ./ A_cut_size); 208 bits = rem (P_size, A_cut_size); 209 pair_size = A_cut_size * 2; 210 pair_complete = floor (complete / 2); 211 unpaired_complete = mod (complete, 2); 212 else 213 complete = floor (P_size ./ A_size); 214 bits = rem (P_size, A_size); 215 if (circular) 216 complete_size = complete .* A_size; 217 elseif (symmetric) 218 pair_complete = floor (complete / 2); 219 pair_size = A_size * 2; 220 unpaired_complete = mod (complete, 2); 221 endif 222 endif 223 224 dim = 0; 225 for s = padsize 226 dim++; 227 if (s == 0) 228 ## skip this dimension if no padding requested 229 continue 230 endif 231 232 if (circular) 233 dim_idx = template_idx; 234 source_idx = template_idx; 235 A_idx_end = A_idx{dim}(end); 236 A_idx_ini = A_idx{dim}(1); 237 238 if (complete(dim)) 239 dim_pad_size(1:B_ndims) = 1; 240 dim_pad_size(dim) = complete(dim)*pre + complete(dim)*post; 241 dim_idx{dim} = []; 242 if (pre) 243 dim_idx{dim} = [(bits(dim) +1):(complete_size(dim) + bits(dim))]; 244 endif 245 if (post) 246 dim_idx{dim} = [dim_idx{dim} (A_idx_end +1):(A_idx_end + complete_size(dim))]; 247 endif 248 source_idx{dim} = A_idx{dim}; 249 B(dim_idx{:}) = repmat (B(source_idx{:}), dim_pad_size); 250 endif 251 252 if (pre) 253 if (bits(dim)) 254 dim_idx{dim} = 1:bits(dim); 255 source_idx{dim} = (A_idx_end - bits(dim) +1):A_idx_end; 256 B(dim_idx{:}) = B(source_idx{:}); 257 endif 258 endif 259 if (post) 260 if (bits(dim)) 261 dim_idx{dim} = (B_size(dim) -bits(dim) +1):B_size(dim); 262 source_idx{dim} = A_idx_ini:(A_idx_ini + bits(dim) -1); 263 B(dim_idx{:}) = B(source_idx{:}); 264 endif 265 endif 266 267 elseif (replicate) 268 dim_pad_size(1:B_ndims) = 1; 269 dim_pad_size(dim) = P_size(dim); 270 dim_idx = template_idx; 271 source_idx = template_idx; 272 if (pre) 273 dim_idx{dim} = 1:P_size(dim); 274 source_idx{dim} = P_size(dim) +1; 275 B(dim_idx{:}) = repmat (B(source_idx{:}), dim_pad_size); 276 endif 277 if (post) 278 dim_idx{dim} = (A_idx{dim}(end) +1):B_size(dim); 279 source_idx{dim} = A_idx{dim}(end); 280 B(dim_idx{:}) = repmat (B(source_idx{:}), dim_pad_size); 281 endif 282 283 ## The idea behind symmetric and reflect passing is the same so the 284 ## following cases have similar looking code. However, there's small 285 ## adjustements everywhere that makes it really hard to merge as a 286 ## common case. 287 elseif (symmetric) 288 dim_idx = template_idx; 289 source_idx = template_idx; 290 A_idx_ini = A_idx{dim}(1); 291 A_idx_end = A_idx{dim}(end); 292 293 if (pre) 294 if (bits(dim)) 295 dim_idx{dim} = 1:bits(dim); 296 if (unpaired_complete(dim)) 297 source_idx{dim} = (A_idx_end - bits(dim) +1):A_idx_end; 298 B(dim_idx{:}) = B(source_idx{:}); 299 else 300 source_idx{dim} = A_idx_ini:(A_idx_ini + bits(dim) -1); 301 B(dim_idx{:}) = flip (B(source_idx{:}), dim); 302 endif 303 endif 304 endif 305 if (post) 306 if (bits(dim)) 307 dim_idx{dim} = (B_size(dim) - bits(dim) +1):B_size(dim); 308 if (unpaired_complete(dim)) 309 source_idx{dim} = A_idx_ini:(A_idx_ini + bits(dim) -1); 310 B(dim_idx{:}) = B(source_idx{:}); 311 else 312 source_idx{dim} = (A_idx_end - bits(dim) +1):A_idx_end; 313 B(dim_idx{:}) = flip (B(source_idx{:}), dim); 314 endif 315 endif 316 endif 317 318 if (complete(dim)) 319 dim_pad_size(1:B_ndims) = 1; 320 source_idx{dim} = A_idx{dim}; 321 flipped_source = flip (B(source_idx{:}), dim); 322 endif 323 324 if (pair_complete(dim)) 325 dim_pad_size(dim) = pair_complete(dim); 326 dim_idx{dim} = []; 327 if (pre) 328 dim_idx{dim} = [(1 + bits(dim) + (A_size(dim)*unpaired_complete(dim))):(A_idx_ini -1)]; 329 B(dim_idx{:}) = repmat (cat (dim, B(source_idx{:}), flipped_source), dim_pad_size); 330 endif 331 if (post) 332 dim_idx{dim} = [(A_idx_end +1):(A_idx_end + (pair_size(dim) * pair_complete(dim)))]; 333 B(dim_idx{:}) = repmat (cat (dim, flipped_source, B(source_idx{:})), dim_pad_size); 334 endif 335 endif 336 337 if (unpaired_complete(dim)) 338 source_idx = template_idx; 339 if (pre) 340 dim_idx{dim} = (1 + bits(dim)):(bits(dim) + A_size(dim)); 341 B(dim_idx{:}) = flipped_source(source_idx{:}); 342 endif 343 if (post) 344 dim_idx{dim} = (B_size(dim) - bits(dim) - A_size(dim) +1):(B_size(dim) - bits(dim)); 345 B(dim_idx{:}) = flipped_source(source_idx{:}); 346 endif 347 endif 348 349 elseif (reflect) 350 dim_idx = template_idx; 351 source_idx = template_idx; 352 A_idx_ini = A_idx{dim}(1); 353 A_idx_end = A_idx{dim}(end); 354 355 if (pre) 356 if (bits(dim)) 357 dim_idx{dim} = 1:bits(dim); 358 if (unpaired_complete(dim)) 359 source_idx{dim} = (A_idx_end - bits(dim)):(A_idx_end -1); 360 B(dim_idx{:}) = B(source_idx{:}); 361 else 362 source_idx{dim} = (A_idx_ini +1):(A_idx_ini + bits(dim)); 363 B(dim_idx{:}) = flip (B(source_idx{:}), dim); 364 endif 365 endif 366 endif 367 if (post) 368 if (bits(dim)) 369 dim_idx{dim} = (B_size(dim) - bits(dim) +1):B_size(dim); 370 if (unpaired_complete(dim)) 371 source_idx{dim} = (A_idx_ini +1):(A_idx_ini + bits(dim)); 372 B(dim_idx{:}) = B(source_idx{:}); 373 else 374 source_idx{dim} = (A_idx_end - bits(dim)):(A_idx_end -1); 375 B(dim_idx{:}) = flip (B(source_idx{:}), dim); 376 endif 377 endif 378 endif 379 380 if (complete(dim)) 381 dim_pad_size(1:B_ndims) = 1; 382 source_idx{dim} = A_idx{dim}; 383 flipped_source = flip (B(source_idx{:}), dim); 384 endif 385 386 if (pair_complete(dim)) 387 dim_pad_size(dim) = pair_complete(dim); 388 dim_idx{dim} = []; 389 if (pre) 390 flipped_source_idx = source_idx; 391 flipped_source_idx{dim} = 1:A_cut_size(dim); 392 source_idx{dim} = A_idx_ini:(A_idx_end -1); 393 dim_idx{dim} = [(1 + bits(dim) + (A_cut_size(dim)*unpaired_complete(dim))):(A_idx_ini -1)]; 394 B(dim_idx{:}) = repmat (cat (dim, B(source_idx{:}), flipped_source(flipped_source_idx{:})), dim_pad_size); 395 endif 396 if (post) 397 flipped_source_idx = source_idx; 398 flipped_source_idx{dim} = 2:A_size(dim); 399 source_idx{dim} = (A_idx_ini +1):A_idx_end; 400 dim_idx{dim} = [(A_idx_end +1):(A_idx_end + (pair_size(dim) * pair_complete(dim)))]; 401 B(dim_idx{:}) = repmat (cat (dim, flipped_source(flipped_source_idx{:}), B(source_idx{:})), dim_pad_size); 402 endif 403 endif 404 405 if (unpaired_complete(dim)) 406 source_idx = template_idx; 407 if (pre) 408 source_idx{dim} = 1:(A_size(dim)-1); 409 dim_idx{dim} = (1 + bits(dim)):(bits(dim) + A_size(dim) -1); 410 B(dim_idx{:}) = flipped_source(source_idx{:}); 411 endif 412 if (post) 413 source_idx{dim} = 2:A_size(dim); 414 dim_idx{dim} = (B_size(dim) - bits(dim) - A_size(dim) +2):(B_size(dim) - bits(dim)); 415 B(dim_idx{:}) = flipped_source(source_idx{:}); 416 endif 417 endif 418 419 endif 420 endfor 421 endif 422endfunction 423 424%!demo 425%! padarray([1,2,3;4,5,6],[2,1]) 426%! % pads [1,2,3;4,5,6] with a whole border of 2 rows and 1 columns of 0 427 428%!demo 429%! padarray([1,2,3;4,5,6],[2,1],5) 430%! % pads [1,2,3;4,5,6] with a whole border of 2 rows and 1 columns of 5 431 432%!demo 433%! padarray([1,2,3;4,5,6],[2,1],0,'pre') 434%! % pads [1,2,3;4,5,6] with a left and top border of 2 rows and 1 columns of 0 435 436%!demo 437%! padarray([1,2,3;4,5,6],[2,1],'circular') 438%! % pads [1,2,3;4,5,6] with a whole 'circular' border of 2 rows and 1 columns 439%! % border 'repeats' data as if we tiled blocks of data 440 441%!demo 442%! padarray([1,2,3;4,5,6],[2,1],'replicate') 443%! % pads [1,2,3;4,5,6] with a whole border of 2 rows and 1 columns which 444%! % 'replicates' edge data 445 446%!demo 447%! padarray([1,2,3;4,5,6],[2,1],'symmetric') 448%! % pads [1,2,3;4,5,6] with a whole border of 2 rows and 1 columns which 449%! % is symmetric to the data on the edge 450 451## Test default padval and direction 452%!assert (padarray ([1;2], [1]), [0;1;2;0]); 453%!assert (padarray ([3 4], [0 2]), [0 0 3 4 0 0]); 454%!assert (padarray ([1 2 3; 4 5 6], [1 2]), 455%! [zeros(1, 7); 0 0 1 2 3 0 0; 0 0 4 5 6 0 0; zeros(1, 7)]); 456 457## Test padding on 3D array 458%!test 459%! assert (padarray ([1 2 3; 4 5 6], [3 2 1]), 460%! cat(3, zeros(8, 7), 461%! [ [ zeros(3, 7) ] 462%! [zeros(2, 2) [1 2 3; 4 5 6] zeros(2, 2) ] 463%! [ zeros(3,7)] ], 464%! zeros (8, 7))); 465 466## Test if default param are ok 467%!assert (padarray ([1 2], [4 5]), padarray ([1 2], [4 5], 0)); 468%!assert (padarray ([1 2], [4 5]), padarray ([1 2], [4 5], "both")); 469 470## Test literal padval 471%!assert (padarray ([1;2], [1], i), [i; 1; 2; i]); 472 473## Test directions (horizontal) 474%!assert (padarray ([1;2], [1], i, "pre"), [i; 1; 2]); 475%!assert (padarray ([1;2], [1], i, "post"), [1; 2; i]); 476%!assert (padarray ([1;2], [1], i, "both"), [i; 1; 2; i]); 477 478## Test directions (vertical) 479%!assert (padarray ([1 2], [0 1], i, "pre"), [i 1 2]); 480%!assert (padarray ([1 2], [0 1], i, "post"), [1 2 i]); 481%!assert (padarray ([1 2], [0 1], i, "both"), [i 1 2 i]); 482 483## Test vertical padsize 484%!assert (padarray ([1 2], [0;1], i, "both"), [i 1 2 i]); 485 486## Test circular padding 487%!test 488%! A = [1 2 3; 4 5 6]; 489%! B = repmat (A, 7, 9); 490%! assert (padarray (A, [1 2], "circular", "pre"), B(2:4,2:6)); 491%! assert (padarray (A, [1 2], "circular", "post"), B(3:5,4:8)); 492%! assert (padarray (A, [1 2], "circular", "both"), B(2:5,2:8)); 493%! ## This tests when padding is bigger than data 494%! assert (padarray (A, [5 10], "circular", "both"), B(2:13,3:25)); 495 496% Test circular padding with int* uint* class types 497%!test 498%! A = int8 ([1 2 3; 4 5 6]); 499%! B = repmat (A, 7, 9); 500%! assert (padarray (A, [1 2], "circular", "pre"), B(2:4,2:6)); 501%! assert (padarray (A, [1 2], "circular", "post"), B(3:5,4:8)); 502%! assert (padarray (A, [1 2], "circular", "both"), B(2:5,2:8)); 503%! ## This tests when padding is bigger than data 504%! assert (padarray (A, [5 10], "circular", "both"), B(2:13,3:25)); 505 506## Test replicate padding 507%!test 508%! A = [1 2; 3 4]; 509%! B = kron (A, ones (10, 5)); 510%! assert (padarray (A, [9 4], "replicate", "pre"), B(1:11,1:6)); 511%! assert (padarray (A, [9 4], "replicate", "post"), B(10:20,5:10)); 512%! assert (padarray (A, [9 4], "replicate", "both"), B); 513%! ## same with uint class 514%! assert (padarray (uint8 (A), [9 4], "replicate", "pre"), uint8 (B(1:11,1:6))); 515%! assert (padarray (uint8 (A), [9 4], "replicate", "post"), uint8 (B(10:20,5:10))); 516%! assert (padarray (uint8 (A), [9 4], "replicate", "both"), uint8 (B)); 517 518## Test symmetric padding 519%!test 520%! A = [1:3 521%! 4:6]; 522%! HA = [3:-1:1 523%! 6:-1:4]; 524%! VA = [4:6 525%! 1:3]; 526%! VHA = [6:-1:4 527%! 3:-1:1]; 528%! B = [VHA VA VHA 529%! HA A HA 530%! VHA VA VHA]; 531%! assert (padarray (A, [1 2], "symmetric", "pre"), B(2:4,2:6)); 532%! assert (padarray (A, [1 2], "symmetric", "post"), B(3:5,4:8)); 533%! assert (padarray (A, [1 2], "symmetric", "both"), B(2:5,2:8)); 534%! ## same with int class 535%! assert (padarray (int16 (A), [1 2], "symmetric", "pre"), int16 (B(2:4,2:6))); 536%! assert (padarray (int16 (A), [1 2], "symmetric", "post"), int16 (B(3:5,4:8))); 537%! assert (padarray (int16 (A), [1 2], "symmetric", "both"), int16 (B(2:5,2:8))); 538 539## Repeat some tests with int* uint* class types 540%!assert (padarray (int8 ([1; 2]), [1]), int8 ([0; 1; 2; 0])); 541%!assert (padarray (uint8 ([3 4]), [0 2]), uint8 ([0 0 3 4 0 0])); 542%!assert (padarray (int16 ([1; 2]), [1], 4), int16 ([4; 1; 2; 4])); 543%!assert (padarray (uint16 ([1; 2]), [1], 0), uint16 ([0; 1; 2; 0])); 544%!assert (padarray (uint32 ([1; 2]), [1], 6, "post"), uint32 ([1; 2; 6])); 545%!assert (padarray (int32 ([1; 2]), [1], int32 (4), "pre"), int32 ([4; 1; 2])); 546 547## Test symmetric and reflect for multiple lengths of padding (since the way 548## it's done changes based on this). By iterating from 10 on a matrix of size 549## 10, we catch the cases where there's only part of the matrix on the pad, a 550## single copy of the matrix, a single copy with bits of non-flipped matrix, two 551##copies of the matrix (flipped and non-flipped), the two copies with bits. 552%!test 553%! in = [ 7 5 1 3 554%! 5 3 3 4 555%! 7 5 2 3 556%! 6 1 3 8]; 557%! padded = [ 558%! 3 5 5 3 3 4 4 3 3 5 5 3 3 4 4 3 3 5 5 3 3 4 4 3 559%! 5 7 7 5 1 3 3 1 5 7 7 5 1 3 3 1 5 7 7 5 1 3 3 1 560%! 5 7 7 5 1 3 3 1 5 7 7 5 1 3 3 1 5 7 7 5 1 3 3 1 561%! 3 5 5 3 3 4 4 3 3 5 5 3 3 4 4 3 3 5 5 3 3 4 4 3 562%! 5 7 7 5 2 3 3 2 5 7 7 5 2 3 3 2 5 7 7 5 2 3 3 2 563%! 1 6 6 1 3 8 8 3 1 6 6 1 3 8 8 3 1 6 6 1 3 8 8 3 564%! 1 6 6 1 3 8 8 3 1 6 6 1 3 8 8 3 1 6 6 1 3 8 8 3 565%! 5 7 7 5 2 3 3 2 5 7 7 5 2 3 3 2 5 7 7 5 2 3 3 2 566%! 3 5 5 3 3 4 4 3 3 5 5 3 3 4 4 3 3 5 5 3 3 4 4 3 567%! 5 7 7 5 1 3 3 1 5 7 7 5 1 3 3 1 5 7 7 5 1 3 3 1 568%! 5 7 7 5 1 3 3 1 5 7 7 5 1 3 3 1 5 7 7 5 1 3 3 1 569%! 3 5 5 3 3 4 4 3 3 5 5 3 3 4 4 3 3 5 5 3 3 4 4 3 570%! 5 7 7 5 2 3 3 2 5 7 7 5 2 3 3 2 5 7 7 5 2 3 3 2 571%! 1 6 6 1 3 8 8 3 1 6 6 1 3 8 8 3 1 6 6 1 3 8 8 3 572%! 1 6 6 1 3 8 8 3 1 6 6 1 3 8 8 3 1 6 6 1 3 8 8 3 573%! 5 7 7 5 2 3 3 2 5 7 7 5 2 3 3 2 5 7 7 5 2 3 3 2 574%! 3 5 5 3 3 4 4 3 3 5 5 3 3 4 4 3 3 5 5 3 3 4 4 3 575%! 5 7 7 5 1 3 3 1 5 7 7 5 1 3 3 1 5 7 7 5 1 3 3 1 576%! 5 7 7 5 1 3 3 1 5 7 7 5 1 3 3 1 5 7 7 5 1 3 3 1 577%! 3 5 5 3 3 4 4 3 3 5 5 3 3 4 4 3 3 5 5 3 3 4 4 3 578%! 5 7 7 5 2 3 3 2 5 7 7 5 2 3 3 2 5 7 7 5 2 3 3 2 579%! 1 6 6 1 3 8 8 3 1 6 6 1 3 8 8 3 1 6 6 1 3 8 8 3 580%! 1 6 6 1 3 8 8 3 1 6 6 1 3 8 8 3 1 6 6 1 3 8 8 3 581%! 5 7 7 5 2 3 3 2 5 7 7 5 2 3 3 2 5 7 7 5 2 3 3 2]; 582%! for ite = 1:10 583%! assert (padarray (in, [ite ite], "symmetric"), padded((11-ite):(14+ite),(11-ite):(14+ite))); 584%! assert (padarray (in, [ite ite], "symmetric", "pre"), padded((11-ite):14,(11-ite):14)); 585%! assert (padarray (in, [ite ite], "symmetric", "post"), padded(11:(14+ite),11:(14+ite))); 586%! endfor 587 588%!test 589%! in = [ 7 5 4 9 590%! 6 4 5 1 591%! 5 3 3 3 592%! 2 6 7 3]; 593%! padded = [ 594%! 3 3 3 3 5 3 3 3 3 3 5 3 3 3 3 3 5 3 3 3 3 3 5 3 595%! 7 3 7 6 2 6 7 3 7 6 2 6 7 3 7 6 2 6 7 3 7 6 2 6 596%! 3 3 3 3 5 3 3 3 3 3 5 3 3 3 3 3 5 3 3 3 3 3 5 3 597%! 5 1 5 4 6 4 5 1 5 4 6 4 5 1 5 4 6 4 5 1 5 4 6 4 598%! 4 9 4 5 7 5 4 9 4 5 7 5 4 9 4 5 7 5 4 9 4 5 7 5 599%! 5 1 5 4 6 4 5 1 5 4 6 4 5 1 5 4 6 4 5 1 5 4 6 4 600%! 3 3 3 3 5 3 3 3 3 3 5 3 3 3 3 3 5 3 3 3 3 3 5 3 601%! 7 3 7 6 2 6 7 3 7 6 2 6 7 3 7 6 2 6 7 3 7 6 2 6 602%! 3 3 3 3 5 3 3 3 3 3 5 3 3 3 3 3 5 3 3 3 3 3 5 3 603%! 5 1 5 4 6 4 5 1 5 4 6 4 5 1 5 4 6 4 5 1 5 4 6 4 604%! 4 9 4 5 7 5 4 9 4 5 7 5 4 9 4 5 7 5 4 9 4 5 7 5 605%! 5 1 5 4 6 4 5 1 5 4 6 4 5 1 5 4 6 4 5 1 5 4 6 4 606%! 3 3 3 3 5 3 3 3 3 3 5 3 3 3 3 3 5 3 3 3 3 3 5 3 607%! 7 3 7 6 2 6 7 3 7 6 2 6 7 3 7 6 2 6 7 3 7 6 2 6 608%! 3 3 3 3 5 3 3 3 3 3 5 3 3 3 3 3 5 3 3 3 3 3 5 3 609%! 5 1 5 4 6 4 5 1 5 4 6 4 5 1 5 4 6 4 5 1 5 4 6 4 610%! 4 9 4 5 7 5 4 9 4 5 7 5 4 9 4 5 7 5 4 9 4 5 7 5 611%! 5 1 5 4 6 4 5 1 5 4 6 4 5 1 5 4 6 4 5 1 5 4 6 4 612%! 3 3 3 3 5 3 3 3 3 3 5 3 3 3 3 3 5 3 3 3 3 3 5 3 613%! 7 3 7 6 2 6 7 3 7 6 2 6 7 3 7 6 2 6 7 3 7 6 2 6 614%! 3 3 3 3 5 3 3 3 3 3 5 3 3 3 3 3 5 3 3 3 3 3 5 3 615%! 5 1 5 4 6 4 5 1 5 4 6 4 5 1 5 4 6 4 5 1 5 4 6 4 616%! 4 9 4 5 7 5 4 9 4 5 7 5 4 9 4 5 7 5 4 9 4 5 7 5 617%! 5 1 5 4 6 4 5 1 5 4 6 4 5 1 5 4 6 4 5 1 5 4 6 4]; 618%! for ite = 1:10 619%! assert (padarray (in, [ite ite], "reflect"), padded((11-ite):(14+ite),(11-ite):(14+ite))); 620%! assert (padarray (in, [ite ite], "reflect", "pre"), padded((11-ite):14,(11-ite):14)); 621%! assert (padarray (in, [ite ite], "reflect", "post"), padded(11:(14+ite),11:(14+ite))); 622%! endfor 623