-
Notifications
You must be signed in to change notification settings - Fork 29
/
opFoG.m
130 lines (109 loc) · 4.24 KB
/
opFoG.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
classdef opFoG < opSpot
%OPFOG Forms the product of two operators.
%
% opFoG(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 Spot 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
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Properties
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
properties (SetAccess = private)
operators = {}; % List of preprocessed operators
end % Properties
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Methods
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
methods
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Constructor
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function op = opFoG(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@opSpot('FoG', 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;
% 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
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 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
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
y = applyMultiply(op.children{1},x,mode);
z = applyMultiply(op.children{2},y,mode);
end
end % Multiply
end % Methods
end % Classdef