forked from mpf/spot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
opExcise.m
127 lines (104 loc) · 3.96 KB
/
opExcise.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
classdef opExcise < opSpot
%OPEXCISE Excise rows or columns of an operator.
%
% opExcise(OP,IDX,TYPE) excises the entries in the rows or columns
% given by IDX, depending on whether TYPE = 'rows', or 'cols'.
%
% See also opRestrict.
% Copyright 2009, Ewout van den Berg and Michael P. Friedlander
% See the file COPYING.txt for full copyright information.
% Use the command 'spot.gpl' to locate this file.
% http://www.cs.ubc.ca/labs/scl/spot
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Properties
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
properties (SetAccess = private)
opIntrnl = []; % Internal operator
indices = []; % Indices
rowExcise = false;
end % Properties
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Methods
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
methods
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Constructor
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function op = opExcise(A,idx,type)
if nargin ~= 3
error('Exactly three operators must be specified.')
end
% Input matrices are immediately cast as opMatrix's.
if isa(A,'numeric'), A = opMatrix(A); end
% Check that the input operators are valid.
if ~isa(A,'opSpot')
error('Input operator is not valid.')
end
% Check type
switch lower(type)
case {'col','cols','column','columns'}
rowExcise = false;
dimIdx = 2;
case {'row','rows'}
rowExcise = true;
dimIdx = 1;
otherwise
error('Invalid parameter for operator type.');
end
% Check index type and range
if islogical(idx)
if (length(idx) > size(A,dimIdx))
error('Index exceeds operator dimensions.');
end
elseif spot.utils.isposintmat(idx)
if (max(idx) > size(A,dimIdx))
error('Index exceeds operator dimensions.');
end
else
error(['Subscript indices must either be real positive ' ...
'integers or logicals.']);
end
% Reverse input vector
if islogical(idx)
idxReverse = true(size(A,dimIdx),1);
idxReverse(idx) = false;
else
idxReverse = setdiff(1:size(A,dimIdx),idx);
end
% Construct new operator
if rowExcise
opIntrnl = opRestriction(size(A,1),idxReverse) * A;
else
opIntrnl = A * opRestriction(size(A,2),idxReverse)';
end
% Construct operator
[m,n] = size(opIntrnl);
op = op@opSpot('Excise', m, n);
op.cflag = A.cflag;
op.linear = A.linear;
op.children = {A};
op.opIntrnl = opIntrnl;
op.indices = idx;
op.rowExcise = rowExcise;
end % Constructor
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Display
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function str = char(op)
if op.rowExcise
type = 'Rows';
else
type = 'Cols';
end
str = ['Excise(', char(op.children{1}),', ', type, ')'];
end % Char
end % Methods
methods ( Access = protected )
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Multiply
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function y = multiply(op,x,mode)
y = applyMultiply(op.opIntrnl,x,mode);
end % Multiply
end % Methods
end % Classdef