-
Notifications
You must be signed in to change notification settings - Fork 2
/
oppFoG.m
166 lines (140 loc) · 5.56 KB
/
oppFoG.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
classdef oppFoG < oppSpot
%OPPFOG Forms the product of to operators.
%
% oppFoG(OP1,OP2) creates an operator that successively applies each
% of the operators OP1, OP2 on a given input vector. In non-adjoint
% mode this is done in reverse order.
%
% The inputs must be either pSpot operators or explicit Matlab matrices
% (including scalars).
%
% See also opDictionary, opStack, opSum.
% 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
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Methods
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
methods
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Constructor
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function op = oppFoG(A,B)
if nargin ~= 2
error('Exactly two operators must be specified.')
end
% Input matrices are immediately cast as opMatrix's.
if isa(A,'numeric'), A = opMatrix(A); end
if isa(B,'numeric'), B = opMatrix(B); end
% Check that the input operators are valid.
if ~( isa(A,'opSpot') || isa(B,'opSpot') )
error('One of the operators is not a valid input.')
end
% Check operator consistency and complexity
[mA, nA] = size(A);
[mB, nB] = size(B);
compatible = isscalar(A) || isscalar(B) || nA == mB;
if ~compatible
error('Operators are not compatible in size.');
end
% Determine size
if isscalar(A) || isscalar(B)
m = max(mA,mB);
n = max(nA,nB);
else
m = mA;
n = nB;
end
% Construct operator
op = op@oppSpot('pFoG', m, n);
op.cflag = A.cflag | B.cflag;
op.linear = A.linear | B.linear;
op.sweepflag = A.sweepflag & B.sweepflag;
op.children = {A, B};
op.precedence = 3;
op.ms = A.ms;
op.ns = B.ns;
% Preprocess children
if isscalar(A), op.children{1} = opMatrix(double(A)); end
if isscalar(B), op.children{2} = opMatrix(double(B)); end
end % Constructor
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% double
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function A = double(op)
C1 = op.children{1};
C2 = op.children{2};
A = double(C1)*double(C2);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% drandn
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function A = drandn(op,varargin)
A = drandn(op.children{2},varargin{:});
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% rrandn
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function A = rrandn(op,varargin)
A = rrandn(op.children{1},varargin{:});
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Display
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function str = char(op)
% Get children
op1 = op.children{1};
op2 = op.children{2};
% Format first operator
str1 = char(op1);
if op1.precedence > op.precedence
str1 = ['(',str1,')'];
end
% Format second operator
str2 = char(op2);
if op2.precedence > op.precedence
str2 = ['(',str2,')'];
end
% Combine
str = [str1, ' * ', str2];
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% headerMod
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function h = headerMod(op,header,mode)
if mode == 1
g = headerMod(op.children{2},header,mode);
h = headerMod(op.children{1},g,mode);
else
g = headerMod(op.children{1},header,mode);
h = headerMod(op.children{2},g,mode);
end
end % headerMod
end % Methods
methods ( Access = protected )
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Multiply
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function z = multiply(op,x,mode)
if mode == 1
y = applyMultiply(op.children{2},x,mode);
z = applyMultiply(op.children{1},y,mode);
else % mode = 2
y = applyMultiply(op.children{1},x,mode);
z = applyMultiply(op.children{2},y,mode);
end
end % Multiply
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Divide
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function x = divide(op,b,mode)
% Needs sweepflag
if op.sweepflag
x = matldivide(op,b,mode);
else
x = lsqrdivide(op,b,mode);
end
end % divide
end % Methods
end % Classdef