source: proiecte/pmake3d/make3d_original/Make3dSingleImageStanford_version0.1/third_party/opt/yalmip/@sdpvar/minus.m @ 37

Last change on this file since 37 was 37, checked in by (none), 14 years ago

Added original make3d

File size: 6.6 KB
Line 
1function y = minus(X,Y)
2%MINUS (overloaded)
3
4% Author Johan Löfberg
5% $Id: minus.m,v 1.21 2006/07/26 20:17:58 joloef Exp $
6
7X_is_spdvar = isa(X,'sdpvar');
8Y_is_spdvar = isa(Y,'sdpvar');
9
10% Convert block objects
11if ~X_is_spdvar
12    if isa(X,'blkvar')
13        X = sdpvar(X);
14        X_is_spdvar = isa(X,'sdpvar');
15    end
16end
17
18if ~Y_is_spdvar
19    if isa(Y,'blkvar')
20        Y = sdpvar(Y);
21        Y_is_spdvar = isa(Y,'sdpvar');;
22    end
23end
24
25switch 2*X_is_spdvar+Y_is_spdvar
26    case 1
27        if isempty(X)
28            try
29                y = full(X - reshape(Y.basis(:,1),Y.dim(1),Y.dim(2)));
30            catch
31                error(lasterr);
32            end
33            return
34        end
35
36        y = Y;
37        n_Y = Y.dim(1);
38        m_Y = Y.dim(2);
39        [n_X,m_X] = size(X);
40        x_isscalar = (n_X*m_X==1);
41        y_isscalar = (n_Y*m_Y==1);
42        any_scalar = x_isscalar | y_isscalar;
43
44        % Speeeeeeed
45        if x_isscalar & y_isscalar
46             y.basis = -y.basis;
47             y.basis(1) = y.basis(1)+X;
48             % Reset info about conic terms
49             y.conicinfo = [0 0];
50             return
51        end
52         
53        if any_scalar | ([n_Y m_Y]==[n_X m_X])
54            if y_isscalar
55                y.basis = repmat(y.basis,n_X*m_X,1);
56                y.dim(1) = n_X;
57                y.dim(2) = m_X;
58            end
59            y.basis = -y.basis;
60            if nnz(X)~=0
61                y.basis(:,1) = y.basis(:,1)+X(:);
62            end
63        else
64            error('Matrix dimensions must agree.');
65        end
66        % Reset info about conic terms
67        y.conicinfo = [0 0];
68
69    case 2
70
71        if isempty(Y)
72            try
73                y = full(reshape(X.basis(:,1),X.dim(1),X.dim(2))-Y);
74            catch
75                error(lasterr);
76            end
77            return
78        end
79        y = X;
80        n_X = X.dim(1);
81        m_X = X.dim(2);
82        [n_Y,m_Y] = size(Y);
83        x_isscalar = (n_X*m_X==1);
84        y_isscalar = (n_Y*m_Y==1);
85        any_scalar = x_isscalar | y_isscalar;
86
87        % Silly hack
88        % Taking X-scalar(0) takes unnecessary time
89        % and is used in most definitions of LMIs
90        if (y_isscalar & (Y==0))
91            return
92        end
93               
94        % Speeeeeeed
95        if x_isscalar & y_isscalar
96             y.basis(1) = y.basis(1)-Y;
97             % Reset info about conic terms
98             y.conicinfo = [0 0];
99             return
100         end
101
102        if any_scalar | ([n_Y m_Y]==[n_X m_X])
103            if x_isscalar
104                y.basis = repmat(y.basis,n_Y*m_Y,1);
105                y.dim(1) = n_Y;
106                y.dim(2) = m_Y;
107            end
108            y.basis(:,1) = y.basis(:,1)-Y(:);
109        else
110            error('Matrix dimensions must agree.');
111        end
112
113        % Update information about conic terms
114        % This information is used in DUALIZE to
115        % speed up some checks, and to facilitate some
116        % advanced dualization features. It also
117        % speeds up checking for symmetry in some other code
118        % Ugly, but the best way at the moment
119        % For a description of this field, check SDPVAR code
120       % if (y.conicinfo(1)~=0) & isequal(Y,Y') & (y.conicinfo(2) ~= 2)
121       %     y.conicinfo(2) = max(1,y.conicinfo(2));
122       % else
123            y.conicinfo = [0 0];
124       % end
125       
126
127    case 3
128
129        %       if (X.typeflag~=0) | (Y.typeflag~=0)
130        %               error('Relational objects cannot be manipulated')
131        %       end
132
133        n_X = X.dim(1);
134        m_X = X.dim(2);
135        n_Y = Y.dim(1);
136        m_Y = Y.dim(2);
137        x_isscalar = (n_X*m_X==1);
138        y_isscalar = (n_Y*m_Y==1);
139        any_scalar = x_isscalar | y_isscalar;
140
141        if ~any_scalar
142            if (~((n_X==n_Y) & (m_X==m_Y)))
143                error('Matrix dimensions must agree.')
144            end
145        end
146
147        all_lmi_variables = uniquestripped([X.lmi_variables Y.lmi_variables]);
148        y = X;
149        X.basis = []; % Returns memory?
150        y.lmi_variables = all_lmi_variables;
151
152        in_X_logical = ismembc(all_lmi_variables,X.lmi_variables);
153        in_Y_logical = ismembc(all_lmi_variables,Y.lmi_variables);
154        in_X = find(in_X_logical);
155        in_Y = find(in_Y_logical);
156
157        if isequal(X.lmi_variables,Y.lmi_variables) & n_Y==n_X & m_Y==m_X
158            y.basis = y.basis - Y.basis;
159            % Super special case f(scalar)-f(scalar)
160            if length(X.lmi_variables)==1
161                if all(y.basis(:,2)==0)
162                    y = full(y.basis(1));
163                else
164                    y.conicinfo = [0 0];
165                end
166                return
167            end
168        else
169            if 1
170                [ix,jx,sx] = find(y.basis);y.basis = [];
171                [iy,jy,sy] = find(Y.basis);Y.basis = [];
172                mapX = [1 1+in_X];
173                mapY = [1 1+in_Y];
174                basis_X = sparse(ix,mapX(jx),sx,n_X*m_X,1+length(all_lmi_variables));ix=[];jx=[];sx=[];
175                basis_Y = sparse(iy,mapY(jy),sy,n_Y*m_Y,1+length(all_lmi_variables));iy=[];jy=[];sy=[];
176            else
177                % MATLAB sparse fails on this for huge problems at a certain size
178                basis_X = spalloc(n_X*m_X,1+length(all_lmi_variables),nnz(X.basis));
179                basis_Y = spalloc(n_Y*m_Y,1+length(all_lmi_variables),nnz(Y.basis));
180                basis_X(:,[1 1+in_X])=y.basis;y.basis = [];
181                basis_Y(:,[1 1+in_Y])=Y.basis;Y.basis = [];
182            end
183
184            % Fix addition of matrix+scalar
185            if n_X*m_X<n_Y*m_Y
186                y.dim(1) = n_Y;
187                y.dim(2) = m_Y;
188                basis_X = repmat(basis_X,n_Y*m_Y,1);
189            end
190            if n_Y*m_Y<n_X*m_X
191                y.dim(1) = n_X;
192                y.dim(2) = m_X;
193                basis_Y = repmat(basis_Y,n_X*m_X,1);
194            end
195
196            % OK, solution is...
197            y.basis = basis_X - basis_Y;
198        end
199       
200        % Only clean if there are variables used in both
201        %if ~all(xor(in_X_logical,in_Y_logical))
202        % Reset info about conic terms
203                 
204     %    if (y.conicinfo(1)~=0) & ishermitian(Y) & isempty(intersect(X.lmi_variables,Y.lmi_variables))
205     %       y.conicinfo = [y.conicinfo(2);
206     %   else
207            y.conicinfo = [0 0];
208     %   end
209         
210         
211         y = clean(y);
212        %else
213        %end
214
215    otherwise
216end
217
218% Update info on KYP objects
219if X_is_spdvar & Y_is_spdvar & X.typeflag==9  & Y.typeflag==9
220    error('Substraction of KYP objects currently not supported')
221end
222if Y_is_spdvar & Y.typeflag==9
223    y.extra.M = -Y.extra.M+X;
224    y.extra.negated = ~Y.extra.negated;
225    return
226end
227if X_is_spdvar & X.typeflag==9
228    y.extra.M = y.extra.M-Y;
229    return
230end
231
232
233
Note: See TracBrowser for help on using the repository browser.