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