source: prextra/add_obj_cl.m @ 29

Last change on this file since 29 was 5, checked in by bduin, 14 years ago
File size: 9.5 KB
Line 
1%Auxiliary script for incsvc.
2%I especially did not make it a function to avoid a ton of arguments to
3%pass. Maybe it gives a small speedup...
4
5%fprintf('Add object number %d\n',c);
6% currently seen objects plus new object
7newsetD = (1:c)';
8
9% compute the kernel matrix entry for the new object:
10% (let us assume this is a row vector)
11K = feval(kernel,kpar,c,newsetD);
12Kc = (y(c)*y(newsetD)').*K;
13
14%  % first see if the object is accepted or not
15%  % (note that I could also have looked at the gradient, but then I
16%  % don't have a very honest 'distance to the boundary')
17%  this_label = K(c) - b;
18%  if ~isempty(setS)
19%    this_label = this_label - K(setS)*(y(setS).*alf(setS));
20%  end
21%  if ~isempty(setE)
22%    this_label = this_label - K(setE)*(y(setE).*alf(setE));
23%  end
24
25% Compute the gradient for the new object:
26grad(c,1) = y(c)*b - 1; %DXD here is a change for SVC
27if ~isempty(setS)
28        grad(c,1) = grad(c,1) + Kc(setS)*alf(setS);
29end
30if ~isempty(setE)
31        grad(c,1) = grad(c,1) + Kc(setE)*alf(setE);
32end
33
34% Right, here we go, can be add object c?:
35if grad(c)>0 % it is already classified ok,
36        if length(setR)>0
37                setR = [setR;c];   % put in the 'rest' set
38                Kr = [Kr; Kc(setS)];  % update Kr
39        else
40                setR = c;
41                Kr = Kc(setS);
42        end
43
44else         % we have to work
45
46        done = 0;  % to check if we are done
47        nrloops=0;
48        while ~done
49
50                % compute beta, not for the new object:
51                beta = zeros(length(setS)+1,1);
52                beta = -R*[y(c); Kc(setS)'];
53
54                if any(beta>1e100) & ~isempty(setS)
55                        disp('Beta is too large: do you have identical objects with different labels??'); keyboard;
56                end
57
58                % compute gamma, also for the new object:
59                if isempty(setS)
60                        % here something fishy is going on, when there is just a single
61                        % object added. Then we cannot freely move alf, and we can only
62                        % move b. In this case, b is moved until alf(c) enters setS
63                        % (that means, the gradient becomes 0).
64                        gamma = y(c)*y(newsetD);
65                        duptonow = y(c)*b;
66                else
67                        gamma = Kc';
68                        if ~isempty(setE)
69                                gamma(setE) = gamma(setE) + [y(setE) Ke]*beta;
70                        end
71                        if ~isempty(setR)
72                                gamma(setR) = gamma(setR) + [y(setR) Kr]*beta;
73                        end
74                        gamma(c) = gamma(c) + [y(c) Kc(setS)]*beta;
75                        gamma(setS) = 0;
76                        duptonow = alf(c);
77                end
78
79      % now we have to see how large deltaAc can become...
80      % (1) check the own upper bound:
81      if isempty(setS)
82        deltaAcisC = inf; %because we're moving b, and not alf!
83      else
84        deltaAcisC = C;
85      end
86      % (2) check if own gradient becomes zero:
87      warning off;
88      deltaGcis0 = duptonow-grad(c)./gamma(c);
89      warning on;
90      % object moves the wrong way:
91      deltaGcis0(deltaGcis0<duptonow) = inf;
92      % (3) check upper bounds of the SVs:
93      deltaupperC = inf;
94      if ~isempty(setS)
95        warning off;
96        deltaupperC = duptonow + (C-alf(setS))./beta(2:end);
97        warning on;
98        % negative changes do not count:
99        deltaupperC(deltaupperC<duptonow) = inf;
100        % object moves the wrong way (or not at all):
101        deltaupperC(beta(2:end)<=0) = inf;
102        [deltaupperC,nrS_up] = min(deltaupperC);
103      end
104      % (4) check lower bounds of the SVs:
105      deltalowerC = inf;
106      if ~isempty(setS)
107        warning off;
108        deltalowerC = duptonow + -alf(setS)./beta(2:end);
109        warning on;
110        % negative changes do not count:
111        deltalowerC(deltalowerC<=duptonow) = inf;
112        % object moves the wrong way (or not at all)
113        deltalowerC(beta(2:end)>=0) = inf;
114        [deltalowerC,nrS_low] = min(deltalowerC);
115      end
116      % (5) check E gradients to become 0:
117      deltaGeis0 = inf;
118      if ~isempty(setE)
119        warning off; % divide by 0 is taken care of later...
120        deltaGeis0 = duptonow -grad(setE)./gamma(setE);
121        warning on;
122        deltaGeis0(deltaGeis0<duptonow) = inf;
123        deltaGeis0(gamma(setE)<=0) = inf;
124        [deltaGeis0,nrE_0] = min(deltaGeis0);
125      end
126      % (6) check R gradients to become 0:
127      deltaGris0 = inf;
128      if ~isempty(setR)
129        warning off; % divide by 0 is taken care of later...
130        deltaGris0 = duptonow -grad(setR)./gamma(setR);
131        warning on;
132        %deltaGris0(deltaGris0<duptonow) = inf;
133        deltaGris0(deltaGris0<=duptonow) = inf;
134        deltaGris0(gamma(setR)>=0) = inf;
135        [deltaGris0,nrG_0] = min(deltaGris0);
136      end
137
138      % which one is the most urgent one?
139      deltas = [deltaAcisC; deltaGcis0; deltaupperC; deltalowerC;...
140                deltaGeis0; deltaGris0];
141      [maxdelta,situation] = min(deltas);
142% fprintf('Situation %d (max_delta=%f)\n',situation,maxdelta);
143%
144      % update the parameters
145      if isempty(setS) % then we only change b:
146        %disp('setS is empty!');
147        b = y(c)*maxdelta;
148      else
149        alf(c) = maxdelta;
150        alf(setS) = alf(setS) + (maxdelta-duptonow)*beta(2:end);
151        b = b + (maxdelta-duptonow)*beta(1);
152%fprintf(' b: %f -> %f\n',bold,b);
153%alf'
154%fprintf('after: sum alf = %f\n',sum(alf));
155      end
156      grad = grad + (maxdelta-duptonow)*gamma;
157     
158      % do consistency check:
159      I = find(alf<tol);
160      if ~isempty(I)
161        J = find(alf(I)<-tol);
162%        if ~isempty(J)
163%          disp('One of the alpha''s became < 0!');
164%                        alf(I(J))
165%          keyboard;
166%                 end
167        alf(I) = 0;
168      end
169
170      % update the sets:
171      %fprintf('%d: situation %d  \n',c,situation);
172      switch situation
173      case 1   % object c goes to setE
174        alf(c) = C; % just to be sure...
175        if size(Ke,1)==0, Ke = []; end % make it really empty
176        Ke = [Ke; Kc(setS)];
177        setE = [setE; c];
178        done = 1;
179      case 2   % object c goes to setS
180        Ks = [Ks [y(c); Kc(setS)']; y(c) Kc([setS; c])];
181        Ke = [Ke Kc(setE)'];
182        Kr = [Kr Kc(setR)'];
183        % update R
184        if isempty(setS) % compute it directly (to avoid the inf's)...
185          R = [-Kc(c) y(c); y(c) 0];
186        else
187          R = change_R(R,+c,beta,gamma(c));
188        end
189        setS = [setS;c];
190        done = 1;
191      case 3  % a support object hits upper bound
192        j = setS(nrS_up);             % number of the object
193        alf(j) = C;                   % just to be sure
194        if size(Ke,1)==0, Ke=[]; end  % make it really really empty
195        Ke = [Ke; Ks(nrS_up+1,2:end)];  % update Ke
196        setE = [setE;j];              % add to setE
197        Ks(nrS_up+1,:) = [];            % update all K's
198        Ks(:,nrS_up+1) = [];
199        Ke(:,nrS_up) = [];
200        if ~isempty(Kr), Kr(:,nrS_up) = []; end
201        setS(nrS_up) = [];            % remove from setS
202        R = change_R(R,-nrS_up,beta,gamma(j));
203      case 4  % a support object hits lower bound
204        j = setS(nrS_low);             % number of the object
205        alf(j) = 0;                    % just to be sure
206        if size(Kr,1)==0, Kr = []; end % make really empty
207        Kr = [Kr; Ks(nrS_low+1,2:end)];  % update Kr
208        setR = [setR;j];               % add to setE
209        Ks(nrS_low+1,:) = [];            % update all K's
210        Ks(:,nrS_low+1) = [];
211        if ~isempty(Ke), Ke(:,nrS_low) = []; end;
212        if ~isempty(Kr), Kr(:,nrS_low) = []; end;
213        setS(nrS_low) = [];            % remove from setS
214        R = change_R(R,-nrS_low,beta,gamma(j));
215      case 5  % an error becomes a support object
216        j = setE(nrE_0);              % number of the object
217        % adding to setS, means that all kernels have to be computed:
218        K = feval(kernel,kpar,j,newsetD);
219        Kj = (y(j)*y(newsetD)').*K;
220        % to update R, we have to have the beta of object j:
221        betaj = zeros(length(setS)+1,1);
222        betaj = -R*[y(j); Kj(setS)'];
223        Ks = [Ks; y(j) Kj(setS)];     % add row to Ks
224        Kr = [Kr Kj(setR)'];          % update Kr
225        Ke = [Ke Kj(setE)'];          % update Ke
226        Ke(nrE_0,:) = [];
227        setE(nrE_0) = [];             % update setE
228        setS = [setS;j];              % add to setS
229        Ks = [Ks [y(j); Kj(setS)']];   % and the extra column for Ks
230        if length(betaj)==1 % compute it directly (to avoid the inf's)...
231          R = [-Kj(j) y(j); y(j) 0];
232        else
233          % to update R, we also have to have the gamma of object j:
234          gammaj = Ks(end,:)*[betaj;1] ;
235          R = change_R(R,+j,betaj,gammaj);
236        end
237      case 6  % an other object becomes a support object
238        j = setR(nrG_0);              % number of the object
239        % adding to setS, means that all kernels have to be computed:
240        K = feval(kernel,kpar,j,newsetD);
241        Kj = (y(j)*y(newsetD)').*K;
242        % to update R, we have to have the beta of object j:
243        betaj = zeros(length(setS)+1,1);
244        betaj = -R*[y(j); Kj(setS)'];
245        Ks = [Ks; y(j) Kj(setS)];     % add row to Ks
246        Ks = [Ks [y(j); Kj([setS;j])']]; % and the extra column for Ks
247        Ke = [Ke Kj(setE)'];          % update Ke
248        Kr = [Kr Kj(setR)'];          % update Kr
249        Kr(nrG_0,:) = [];
250        setS = [setS;j];              % add to setS
251        setR(nrG_0) = [];             % update setR
252        if length(betaj)==1 % compute it directly (to avoid the inf's)...
253          R = [-Kj(j) y(j); y(j) 0];
254        else
255          % to update R, we also have to have the gamma of object j:
256          gammaj = Ks(end,:)*[betaj;1] ;
257          R = change_R(R,+j,betaj,gammaj);
258        end
259      end
260      %fprintf('end situation\n');
261      %alf,b
262                nrloops = nrloops+1;
263                %fprintf('nrloops = %d\n',nrloops);
264                if nrloops>50, done=1; end
265      %keyboard
266    end % changing alfa's till stable solution is found
267end % check for gradient<=0
268
269
270% now we can also compute the R, compute the output for the x(setS):
271% But fortunately, this value is
272%   R^2 = offset + b;
273% If we ignore the offset, we just have to use b!
274
275
Note: See TracBrowser for help on using the repository browser.