0001 function b = padarray(varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061 [a, method, padSize, padVal, direction, msg] = ParseInputs(varargin{:});
0062 if (~isempty(msg))
0063 error(msg);
0064 end
0065
0066 if isempty(a),
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
0098
0099 function b = ConstantPad(a, padSize, padVal, direction)
0100
0101 numDims = prod(size(padSize));
0102
0103
0104
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
0125
0126 b = mkconstarray(class(a), padVal, sizeB);
0127 b(idx{:}) = a;
0128
0129
0130
0131
0132
0133 function b = CircularPad(a, padSize, direction)
0134
0135 numDims = prod(size(padSize));
0136
0137
0138
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
0161
0162 function b = SymmetricPad(a, padSize, direction)
0163
0164 numDims = prod(size(padSize));
0165
0166
0167
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
0189
0190 function b = ReplicatePad(a, padSize, direction)
0191
0192 numDims = prod(size(padSize));
0193
0194
0195
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
0217
0218 function [a, method, padSize, padVal, direction, msg] = ParseInputs(varargin)
0219
0220
0221 a = [];
0222 method = 'constant';
0223 padSize = [];
0224 padVal = 0;
0225 direction = 'both';
0226
0227
0228 msg = nargchk(2,4,nargin);
0229 if (~isempty(msg))
0230 return;
0231 end
0232
0233
0234 padSize = varargin{2};
0235 if ~isPositiveRealIntVector(padSize)
0236 msg = 'Invalid padding-size.';
0237 return;
0238 end
0239
0240
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
0261 switch nargin
0262 case 2
0263
0264
0265
0266
0267 case 3
0268
0269
0270
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
0296
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
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
0332 if (prod(size(padSize)) < ndims(a))
0333 padSize = padSize(:);
0334 padSize(ndims(a)) = 0;
0335 end
0336
0337
0338
0339
0340
0341 function t = isScalar(P)
0342
0343
0344
0345 t = prod(size(P)) == 1;
0346
0347
0348
0349
0350
0351 function t = isVector(P)
0352
0353
0354
0355 t = ((ndims(P) == 2) &...
0356 ((size(P,1) == 1) | (size(P,2) == 1)));
0357
0358
0359
0360
0361 function t = isPositiveRealIntVector(P)
0362
0363
0364
0365
0366 t = isreal(P) & all(isfinite(P(:))) & ~isempty(P) &...
0367 all(P(:)>=0) & all(P(:)==round(P(:))) &...
0368 isVector(P);
0369
0370