Home > matutils > padarray.m

padarray

PURPOSE ^

PADARRAY Pad an array.

SYNOPSIS ^

function b = padarray(varargin)

DESCRIPTION ^

PADARRAY Pad an array.
   B = PADARRAY(A,PADSIZE,METHOD,DIRECTION) pads array A with PADSIZE
   number of elements along each dimension of A using specified METHOD
   and DIRECTION. The N-th element of the PADSIZE vector specifies the
   padding size for the N-th dimension of the array, A.

   METHOD can be a numeric scalar, in which case it specifies the value
   for all padding elements, or one of the following strings which
   specify other methods used to determine pad values.  By default,
   PADARRAY assumes METHOD = 0.  

   String values for METHOD
       'circular'    Pads with circular repetion of elements.
       'replicate'   Repeats border elements of A.
       'symmetric'   Pads array with mirror reflections of itself. 
 
   DIRECTION specifies where to pad the array along each dimension.
   DIRECTION can be one of the following strings.  By default, DIRECTION
   is 'post'.

   String values for DIRECTION
       'pre'         Pads before the first array element along each
                     dimension .
       'post'        Pads after the last array element along each
                     dimension. 
       'both'        Pads before the first array element and after the
                     last array element along each dimension.

   Class Support
   -------------
   A can be of any class.  B is of the same class as A.

   Example
   -------
   Add three elements of padding to the beginning of a vector.  The
   padding elements contain mirror copies of the array.

       b = padarray([1 2 3 4],3,'symmetric','pre')

   Add three elements of padding to the end of the first dimension of
   the array and two elements of padding to the end of the second
   dimension.  Use the value of the last array element as the padding
   value.

       B = padarray([1 2; 3 4],[3 2],'replicate','post')

   Add three elements of padding to each dimension of a
   three-dimensional array.  Each pad element contains the value 0.

       A = [1 2; 3 4];
       B = [5 6; 7 8];
       C = cat(3,A,B)
       D = padarray(C,[3 3],0,'both')

   See also CIRCSHIFT, IMFILTER.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function b = padarray(varargin)
0002 %PADARRAY Pad an array.
0003 %   B = PADARRAY(A,PADSIZE,METHOD,DIRECTION) pads array A with PADSIZE
0004 %   number of elements along each dimension of A using specified METHOD
0005 %   and DIRECTION. The N-th element of the PADSIZE vector specifies the
0006 %   padding size for the N-th dimension of the array, A.
0007 %
0008 %   METHOD can be a numeric scalar, in which case it specifies the value
0009 %   for all padding elements, or one of the following strings which
0010 %   specify other methods used to determine pad values.  By default,
0011 %   PADARRAY assumes METHOD = 0.
0012 %
0013 %   String values for METHOD
0014 %       'circular'    Pads with circular repetion of elements.
0015 %       'replicate'   Repeats border elements of A.
0016 %       'symmetric'   Pads array with mirror reflections of itself.
0017 %
0018 %   DIRECTION specifies where to pad the array along each dimension.
0019 %   DIRECTION can be one of the following strings.  By default, DIRECTION
0020 %   is 'post'.
0021 %
0022 %   String values for DIRECTION
0023 %       'pre'         Pads before the first array element along each
0024 %                     dimension .
0025 %       'post'        Pads after the last array element along each
0026 %                     dimension.
0027 %       'both'        Pads before the first array element and after the
0028 %                     last array element along each dimension.
0029 %
0030 %   Class Support
0031 %   -------------
0032 %   A can be of any class.  B is of the same class as A.
0033 %
0034 %   Example
0035 %   -------
0036 %   Add three elements of padding to the beginning of a vector.  The
0037 %   padding elements contain mirror copies of the array.
0038 %
0039 %       b = padarray([1 2 3 4],3,'symmetric','pre')
0040 %
0041 %   Add three elements of padding to the end of the first dimension of
0042 %   the array and two elements of padding to the end of the second
0043 %   dimension.  Use the value of the last array element as the padding
0044 %   value.
0045 %
0046 %       B = padarray([1 2; 3 4],[3 2],'replicate','post')
0047 %
0048 %   Add three elements of padding to each dimension of a
0049 %   three-dimensional array.  Each pad element contains the value 0.
0050 %
0051 %       A = [1 2; 3 4];
0052 %       B = [5 6; 7 8];
0053 %       C = cat(3,A,B)
0054 %       D = padarray(C,[3 3],0,'both')
0055 %
0056 %   See also CIRCSHIFT, IMFILTER.
0057 
0058 %   Copyright 1993-2001 The MathWorks, Inc.
0059 %   $Revision: 1.1 $  $Date: 2010/02/08 23:22:00 $
0060 
0061 [a, method, padSize, padVal, direction, msg] = ParseInputs(varargin{:});
0062 if (~isempty(msg))
0063     error(msg);
0064 end
0065 
0066 if isempty(a),% treat empty matrix similar for any method
0067 
0068    if strcmp(direction,'both')
0069       sizeB = size(a) + 2*padSize;
0070    else
0071       sizeB = size(a) + padSize;
0072    end
0073 
0074    b = mkconstarray(class(a), padVal, sizeB);
0075    
0076 else
0077   switch method
0078     case 'constant'
0079         b = ConstantPad(a, padSize, padVal, direction);
0080         
0081     case 'circular'
0082         b = CircularPad(a, padSize, direction);
0083   
0084     case 'symmetric'
0085         b = SymmetricPad(a, padSize, direction);
0086         
0087     case 'replicate'
0088         b = ReplicatePad(a, padSize, direction);
0089   end      
0090 end
0091 
0092 if (islogical(a))
0093     b = logical(b);
0094 end
0095 
0096 %%%
0097 %%% ConstantPad
0098 %%%
0099 function b = ConstantPad(a, padSize, padVal, direction)
0100 
0101 numDims = prod(size(padSize));
0102 
0103 % Form index vectors to subsasgn input array into output array.
0104 % Also compute the size of the output array.
0105 idx   = cell(1,numDims);
0106 sizeB = zeros(1,numDims);
0107 for k = 1:numDims
0108     M = size(a,k);
0109     switch direction
0110         case 'pre'
0111             idx{k}   = (1:M) + padSize(k);
0112             sizeB(k) = M + padSize(k);
0113             
0114         case 'post'
0115             idx{k}   = 1:M;
0116             sizeB(k) = M + padSize(k);
0117             
0118         case 'both'
0119             idx{k}   = (1:M) + padSize(k);
0120             sizeB(k) = M + 2*padSize(k);
0121     end
0122 end
0123 
0124 % Initialize output array with the padding value.  Make sure the
0125 % output array is the same type as the input.
0126 b         = mkconstarray(class(a), padVal, sizeB);
0127 b(idx{:}) = a;
0128 
0129 
0130 %%%
0131 %%% CircularPad
0132 %%%
0133 function b = CircularPad(a, padSize, direction)
0134 
0135 numDims = prod(size(padSize));
0136 
0137 % Form index vectors to subsasgn input array into output array.
0138 % Also compute the size of the output array.
0139 idx   = cell(1,numDims);
0140 for k = 1:numDims
0141   M = size(a,k);
0142   dimNums = [1:M];
0143   p = padSize(k);
0144     
0145   switch direction
0146     case 'pre'
0147        idx{k}   = dimNums(mod([-p:M-1], M) + 1);
0148     
0149     case 'post'
0150       idx{k}   = dimNums(mod([0:M+p-1], M) + 1);
0151     
0152     case 'both'
0153       idx{k}   = dimNums(mod([-p:M+p-1], M) + 1);
0154   
0155   end
0156 end
0157 b = a(idx{:});
0158 
0159 %%%
0160 %%% SymmetricPad
0161 %%%
0162 function b = SymmetricPad(a, padSize, direction)
0163 
0164 numDims = prod(size(padSize));
0165 
0166 % Form index vectors to subsasgn input array into output array.
0167 % Also compute the size of the output array.
0168 idx   = cell(1,numDims);
0169 for k = 1:numDims
0170   M = size(a,k);
0171   dimNums = [1:M M:-1:1];
0172   p = padSize(k);
0173     
0174   switch direction
0175     case 'pre'
0176       idx{k}   = dimNums(mod([-p:M-1], 2*M) + 1);
0177             
0178     case 'post'
0179       idx{k}   = dimNums(mod([0:M+p-1], 2*M) + 1);
0180             
0181     case 'both'
0182       idx{k}   = dimNums(mod([-p:M+p-1], 2*M) + 1);
0183   end
0184 end
0185 b = a(idx{:});
0186 
0187 %%%
0188 %%% ReplicatePad
0189 %%%
0190 function b = ReplicatePad(a, padSize, direction)
0191 
0192 numDims = prod(size(padSize));
0193 
0194 % Form index vectors to subsasgn input array into output array.
0195 % Also compute the size of the output array.
0196 idx   = cell(1,numDims);
0197 for k = 1:numDims
0198   M = size(a,k);
0199   p = padSize(k);
0200   onesVector = ones(1,p);
0201     
0202   switch direction
0203     case 'pre'
0204       idx{k}   = [onesVector 1:M];
0205             
0206     case 'post'
0207       idx{k}   = [1:M M*onesVector];
0208             
0209     case 'both'
0210       idx{k}   = [onesVector 1:M M*onesVector];
0211   end
0212 end
0213  b = a(idx{:});
0214 
0215 %%%
0216 %%% ParseInputs
0217 %%%
0218 function [a, method, padSize, padVal, direction, msg] = ParseInputs(varargin)
0219 
0220 % default values
0221 a         = [];
0222 method    = 'constant';
0223 padSize   = [];
0224 padVal    = 0;
0225 direction = 'both';
0226 
0227 % Check the number of input arguments
0228 msg = nargchk(2,4,nargin);
0229 if (~isempty(msg))
0230    return;
0231 end
0232 
0233 % Check the padding size type
0234 padSize = varargin{2};
0235 if ~isPositiveRealIntVector(padSize)
0236    msg = 'Invalid padding-size.';
0237    return;
0238 end
0239 
0240 % Preprocess all option strings in varargin to detect abbreviations.
0241 allStrings = {'circular','replicate', 'symmetric', 'both', 'pre', 'post'};
0242 for k = 2:length(varargin)
0243     if (ischar(varargin{k}))
0244         idx = strmatch(lower(varargin{k}), allStrings);
0245         switch length(idx)
0246             case 0
0247                 msg = sprintf('Unknown string argument: "%s".', varargin{k});
0248                 return;
0249             
0250             case 1
0251                 varargin{k} = allStrings{idx};
0252                 
0253             otherwise
0254                 msg = sprintf('Ambiguous string argument: "%s".', varargin{k});
0255                 return;
0256         end
0257     end
0258 end
0259 
0260 % Assign the padding value, method and direction
0261 switch nargin
0262     case 2
0263         % PADARRAY(A,P)
0264         % Nothing to do here; A, padSize, padVal, method and
0265         % direction have already been assigned.
0266         
0267     case 3
0268        % PADARRAY(A,P,PADVAL)
0269        % PADARRAY(A,P,METHOD)
0270        % PADARRAY(A,P,DIRECTION)
0271        p3 = varargin{3};
0272        
0273        if isa(p3,'double')
0274           if isScalar(p3)
0275              padVal = p3;
0276           else
0277              msg = 'Wrong arguments for padding.';
0278              return;
0279           end
0280        elseif ischar(p3)
0281           if ismember(p3,{'circular','replicate','symmetric'}) 
0282              method = p3;
0283           else
0284              direction = p3;
0285           end
0286        else
0287           msg = sprintf(['Invalid syntax. It should be: \n'...
0288                          'PADARRAY(A,P,PADVAL), \n' ...
0289                          'PADARRAY(A,P,METHOD) or \n'...
0290                          'PADARRAY(A,P,DIRECTION).']);
0291           return;
0292        end
0293         
0294     case 4
0295        % PADARRAY(A,P,METHOD,DIRECTION)
0296        % PADARRAY(A,P,PADVAL,DIRECTION)
0297        p3 = varargin{3};
0298        p4 = varargin{4};
0299        
0300        if ischar(p3) & ischar(p4) 
0301           if ismember(p3,{'circular','replicate','symmetric'}) &...
0302                 ismember(p4,{'pre','post','both'})
0303              method    = p3;
0304              direction = p4;
0305           else
0306              msg = 'Wrong arguments for padding.';
0307              return;
0308           end
0309        elseif isa(p3,'double') & ischar(p4) 
0310           if isScalar(p3) & ismember(p4,{'pre','post','both'})
0311              padVal    = p3;
0312              direction = p4;
0313           else
0314              msg = 'Wrong arguments for padding.';
0315              return;
0316           end
0317        else
0318           msg = sprintf(['Invalid syntax. It should be: \n'...
0319                          'PADARRAY(A,P,PADVAL,DIRECTION).']);
0320           return;
0321        end
0322 end
0323 
0324 % Check the input array type
0325 a = varargin{1};
0326 if ~isnumeric(a) & strcmp(method,'constant')
0327     msg = 'Input array must be numeric if constant padding is used.';
0328     return;
0329 end
0330 
0331 % Preprocess the padding size
0332 if (prod(size(padSize)) < ndims(a))
0333   padSize           = padSize(:);
0334   padSize(ndims(a)) = 0;
0335 end
0336 
0337 
0338 %%%
0339 %%% isScalar
0340 %%%
0341 function t = isScalar(P)
0342 %   isScalar(P) returns 1 if P is a scalar
0343 %   number and returns 0 otherwise.
0344 %
0345 t = prod(size(P)) == 1;
0346 
0347 
0348 %%%
0349 %%% isVector
0350 %%%
0351 function t = isVector(P)
0352 %   isVector(P) returns 1 if P is a vector
0353 %   and returns 0 otherwise.
0354 %
0355 t = ((ndims(P) == 2) &...
0356     ((size(P,1) == 1) | (size(P,2) == 1)));
0357 
0358 %%%
0359 %%% isPositiveRealIntVector
0360 %%%
0361 function t = isPositiveRealIntVector(P)
0362 %   isPositiveRealIntVector(P) returns 1
0363 %   if P is a real, vector of integer numbers
0364 %   greater than 0 and returns 0 otherwise.
0365 %
0366 t = isreal(P) & all(isfinite(P(:))) & ~isempty(P) &...
0367     all(P(:)>=0) & all(P(:)==round(P(:))) &...
0368     isVector(P);
0369 
0370

Generated on Sun 14-Jun-2015 17:12:45 by m2html © 2005