%Auxiliary script for incsvc. %I especially did not make it a function to avoid a ton of arguments to %pass. Maybe it gives a small speedup... %fprintf('Add object number %d\n',c); % currently seen objects plus new object newsetD = (1:c)'; % compute the kernel matrix entry for the new object: % (let us assume this is a row vector) K = feval(kernel,kpar,c,newsetD); Kc = (y(c)*y(newsetD)').*K; % % first see if the object is accepted or not % % (note that I could also have looked at the gradient, but then I % % don't have a very honest 'distance to the boundary') % this_label = K(c) - b; % if ~isempty(setS) % this_label = this_label - K(setS)*(y(setS).*alf(setS)); % end % if ~isempty(setE) % this_label = this_label - K(setE)*(y(setE).*alf(setE)); % end % Compute the gradient for the new object: grad(c,1) = y(c)*b - 1; %DXD here is a change for SVC if ~isempty(setS) grad(c,1) = grad(c,1) + Kc(setS)*alf(setS); end if ~isempty(setE) grad(c,1) = grad(c,1) + Kc(setE)*alf(setE); end % Right, here we go, can be add object c?: if grad(c)>0 % it is already classified ok, if length(setR)>0 setR = [setR;c]; % put in the 'rest' set Kr = [Kr; Kc(setS)]; % update Kr else setR = c; Kr = Kc(setS); end else % we have to work done = 0; % to check if we are done nrloops=0; while ~done % compute beta, not for the new object: beta = zeros(length(setS)+1,1); beta = -R*[y(c); Kc(setS)']; if any(beta>1e100) & ~isempty(setS) disp('Beta is too large: do you have identical objects with different labels??'); keyboard; end % compute gamma, also for the new object: if isempty(setS) % here something fishy is going on, when there is just a single % object added. Then we cannot freely move alf, and we can only % move b. In this case, b is moved until alf(c) enters setS % (that means, the gradient becomes 0). gamma = y(c)*y(newsetD); duptonow = y(c)*b; else gamma = Kc'; if ~isempty(setE) gamma(setE) = gamma(setE) + [y(setE) Ke]*beta; end if ~isempty(setR) gamma(setR) = gamma(setR) + [y(setR) Kr]*beta; end gamma(c) = gamma(c) + [y(c) Kc(setS)]*beta; gamma(setS) = 0; duptonow = alf(c); end % now we have to see how large deltaAc can become... % (1) check the own upper bound: if isempty(setS) deltaAcisC = inf; %because we're moving b, and not alf! else deltaAcisC = C; end % (2) check if own gradient becomes zero: warning off; deltaGcis0 = duptonow-grad(c)./gamma(c); warning on; % object moves the wrong way: deltaGcis0(deltaGcis0=0) = inf; [deltalowerC,nrS_low] = min(deltalowerC); end % (5) check E gradients to become 0: deltaGeis0 = inf; if ~isempty(setE) warning off; % divide by 0 is taken care of later... deltaGeis0 = duptonow -grad(setE)./gamma(setE); warning on; deltaGeis0(deltaGeis0=0) = inf; [deltaGris0,nrG_0] = min(deltaGris0); end % which one is the most urgent one? deltas = [deltaAcisC; deltaGcis0; deltaupperC; deltalowerC;... deltaGeis0; deltaGris0]; [maxdelta,situation] = min(deltas); % fprintf('Situation %d (max_delta=%f)\n',situation,maxdelta); % % update the parameters if isempty(setS) % then we only change b: %disp('setS is empty!'); b = y(c)*maxdelta; else alf(c) = maxdelta; alf(setS) = alf(setS) + (maxdelta-duptonow)*beta(2:end); b = b + (maxdelta-duptonow)*beta(1); %fprintf(' b: %f -> %f\n',bold,b); %alf' %fprintf('after: sum alf = %f\n',sum(alf)); end grad = grad + (maxdelta-duptonow)*gamma; % do consistency check: I = find(alf50, done=1; end %keyboard end % changing alfa's till stable solution is found end % check for gradient<=0 % now we can also compute the R, compute the output for the x(setS): % But fortunately, this value is % R^2 = offset + b; % If we ignore the offset, we just have to use b!