Skip to content

Commit aa2e568

Browse files
committed
Correct, simplify and tidy
1 parent a8cd7e5 commit aa2e568

File tree

1 file changed

+40
-38
lines changed

1 file changed

+40
-38
lines changed

spConv.m

Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@
1111
%
1212
% shape == 'circ': circular convolution over the size of spA.
1313
%
14-
% Version 1.0 by Andrew J. Milne, The MARCS Institute, Western Sydney
15-
% University, 2018-01-09
14+
% By Andrew J. Milne, The MARCS Institute, Western Sydney University
1615
%
17-
% See also SPIND2SPSUB, SPSUB2SPIND, SPARSE, CONV, CCONV.
16+
% See also SPIND2SPSUB, SPSUB2SPIND, SPARSE, CONVN, CCONV.
1817

1918
if nargin < 3
2019
shape = 'full';
@@ -35,55 +34,58 @@
3534
error('The two arrays must have the same numbers of dimensions.')
3635
end
3736

38-
% Convert spB's linear index to subscripts
37+
%% Convert indices to those of an array of size spA.Size+spB.Size-1
38+
sizC = spA.Size+spB.Size-1;
39+
% Convert linear indices to subscripts
40+
subsA = spInd2spSub(spA);
3941
subsB = spInd2spSub(spB);
40-
41-
% Convert spB's subscripts back to a linear index, but taking the size of the
42-
% array to be the same as spA (in non-sparse terms, this is zero padding)
43-
indBSzA = spSub2spInd(spA.Size,subsB);
42+
% Convert subscripts back to a linear indices, but taking the size
43+
% of the array to be the same as spA + spB - 1 (in non-sparse terms,
44+
% this is zero padding)
45+
indASzC = spSub2spInd(sizC,subsA);
46+
indBSzC = spSub2spInd(sizC,subsB);
4447

4548
% Do the convolution
46-
indCSizA = spA.Ind + indBSzA' - 1;
47-
indCSizA = indCSizA(:);
48-
valC = spA.Val.*spB.Val';
49+
indC = indASzC + indBSzC' - 1; % Outer sum of indices, minus 1
50+
indC = indC(:);
51+
valC = spA.Val.*spB.Val'; % Outer product of values
4952
valC = valC(:);
50-
sparseC = sparse(indCSizA,1,valC); % Accumulate (sum) over repeated indices
53+
sparseC = sparse(indC,1,valC); % Accumulate (sum) over repeated indices
5154

52-
% Convert linear indices to subs for an array of size A
53-
[indCSizA,~,valC] = find(sparseC);
54-
spC = struct('Size',spA.Size,'Ind',indCSizA,'Val',valC);
55-
subsC = spInd2spSub(spC);
55+
% Make sparse array structure for full convolution
56+
[indC,~,valC] = find(sparseC);
57+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
58+
spC = struct('Size',sizC,'Ind',indC,'Val',valC);
59+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5660

57-
% If 'shape' is 'full', convert subsC to linear indices for array of
58-
% size A + size B - 1
59-
if isequal(shape,'full')
60-
% Convert subsC to linear indices for array of size A + size B - 1
61-
indCSizAB = spSub2spInd(spA.Size+spB.Size-1, subsC);
61+
if isequal(shape,'same') % Remove entries outside size A
62+
% Convert linear indices of spC to subs
63+
subsC = spInd2spSub(spC);
64+
% Remove subsC outside sizeA
65+
subsCTrunc = subsC;
66+
indCTrunc = all(subsCTrunc<=spA.Size,2);
67+
valC = valC(indCTrunc,:);
68+
subsCTrunc = subsCTrunc(indCTrunc,:);
69+
% convert subsCTrunc to linear index for array of size spA.Size
70+
indC = spSub2spInd(spA.Size,subsCTrunc);
6271
% Make into a sparse array structure
63-
spC = struct('Size',spA.Size+spB.Size-1,'Ind',indCSizAB,'Val',valC);
64-
65-
% If 'shape' is 'circ', all spC's subs outside spA's size are wrapped
66-
elseif isequal(shape,'circ')
67-
% Wrap subsC outside sizeA
72+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73+
spC = struct('Size',spA.Size,'Ind',indC,'Val',valC);
74+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75+
elseif isequal(shape,'circ') % Wrap entries around size A
76+
% Convert linear indices of spC to subs
77+
subsC = spInd2spSub(spC);
78+
% Wrap subsC over sizeA
6879
subsCWrap = mod(subsC-1,spA.Size) + 1;
6980
% Convert wrapped subsC to linear index for size A
70-
indC = spSub2spInd(spA.Size, subsCWrap);
81+
indC = spSub2spInd(spA.Size,subsCWrap);
7182
% Accumulate (sum) over repeated indices
7283
sparseC = sparse(indC,1,valC);
7384
% Make into a sparse array structure
7485
[indC,~,valC] = find(sparseC);
86+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7587
spC = struct('Size',spA.Size,'Ind',indC,'Val',valC);
76-
77-
% If 'shape' is 'same', all spC's subs outside spA's size are removed
78-
elseif isequal(shape,'same')
79-
% Remove subsC outside sizeA
80-
subsCTrunc = subsC;
81-
valC = valC(all(subsCTrunc<=spA.Size,2),:);
82-
subsCTrunc = subsCTrunc(all(subsCTrunc<=spA.Size,2),:);
83-
% convert subsCTrunc to linear index for SizA
84-
indC = spSub2spInd(spA.Size,subsCTrunc);
85-
% Make into a sparse array structure
86-
spC = struct('Size',spA.Size,'Ind',indC,'Val',valC);
88+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8789
end
8890

8991
end

0 commit comments

Comments
 (0)