Daniel@0: function [dPsi, M, SO_time] = cuttingPlaneRandom(k, X, W, Ypos, Yneg, batchSize, SAMPLES, ClassScores) Daniel@0: % Daniel@0: % [dPsi, M, SO_time] = cuttingPlaneRandom(k, X, W, Yp, Yn, batchSize, SAMPLES, ClassScores) Daniel@0: % Daniel@0: % k = k parameter for the SO Daniel@0: % X = d*n data matrix Daniel@0: % W = d*d PSD metric Daniel@0: % Yp = cell-array of relevant results for each point Daniel@0: % Yn = cell-array of irrelevant results for each point Daniel@0: % batchSize = number of points to use in the constraint batch Daniel@0: % SAMPLES = indices of valid points to include in the batch Daniel@0: % ClassScores = structure for synthetic constraints Daniel@0: % Daniel@0: % dPsi = dPsi vector for this batch Daniel@0: % M = mean loss on this batch Daniel@0: % SO_time = time spent in separation oracle Daniel@0: Daniel@0: global SO PSI DISTANCE SETDISTANCE CPGRADIENT; Daniel@0: Daniel@0: [d,n] = size(X); Daniel@0: Daniel@0: Daniel@0: if length(SAMPLES) == n Daniel@0: % All samples are fair game (full data) Daniel@0: Batch = randperm(n); Daniel@0: Batch = Batch(1:batchSize); Daniel@0: D = SETDISTANCE(X, W, Batch); Daniel@0: Daniel@0: else Daniel@0: Batch = randperm(length(SAMPLES)); Daniel@0: Batch = SAMPLES(Batch(1:batchSize)); Daniel@0: Daniel@0: Ito = sparse(n,1); Daniel@0: Daniel@0: if isempty(ClassScores) Daniel@0: for i = Batch Daniel@0: Ito(Ypos{i}) = 1; Daniel@0: Ito(Yneg{i}) = 1; Daniel@0: end Daniel@0: D = SETDISTANCE(X, W, Batch, find(Ito)); Daniel@0: else Daniel@0: D = SETDISTANCE(X, W, Batch, 1:n); Daniel@0: end Daniel@0: end Daniel@0: Daniel@0: Daniel@0: M = 0; Daniel@0: S = zeros(n); Daniel@0: dIndex = sub2ind([n n], 1:n, 1:n); Daniel@0: Daniel@0: SO_time = 0; Daniel@0: Daniel@0: if isempty(ClassScores) Daniel@0: for i = Batch Daniel@0: SO_start = tic(); Daniel@0: [yi, li] = SO(i, D, Ypos{i}, Yneg{i}, k); Daniel@0: SO_time = SO_time + toc(SO_start); Daniel@0: Daniel@0: M = M + li /batchSize; Daniel@0: snew = PSI(i, yi', n, Ypos{i}, Yneg{i}); Daniel@0: S(i,:) = S(i,:) + snew'; Daniel@0: S(:,i) = S(:,i) + snew; Daniel@0: S(dIndex) = S(dIndex) - snew'; Daniel@0: end Daniel@0: else Daniel@0: for j = 1:length(ClassScores.classes) Daniel@0: c = ClassScores.classes(j); Daniel@0: points = find(ClassScores.Y(Batch) == c); Daniel@0: if ~any(points) Daniel@0: continue; Daniel@0: end Daniel@0: Daniel@0: Yneg = find(ClassScores.Yneg{j}); Daniel@0: yp = ClassScores.Ypos{j}; Daniel@0: Daniel@0: for x = 1:length(points) Daniel@0: i = Batch(points(x)); Daniel@0: yp(i) = 0; Daniel@0: Ypos = find(yp); Daniel@0: SO_start = tic(); Daniel@0: [yi, li] = SO(i, D, Ypos, Yneg, k); Daniel@0: SO_time = SO_time + toc(SO_start); Daniel@0: Daniel@0: M = M + li /batchSize; Daniel@0: snew = PSI(i, yi', n, Ypos, Yneg); Daniel@0: S(i,:) = S(i,:) + snew'; Daniel@0: S(:,i) = S(:,i) + snew; Daniel@0: S(dIndex) = S(dIndex) - snew'; Daniel@0: Daniel@0: yp(i) = 1; Daniel@0: end Daniel@0: end Daniel@0: end Daniel@0: Daniel@0: dPsi = CPGRADIENT(X, S) / batchSize; Daniel@0: Daniel@0: end