function [clean,cleanIndices,discarded] = RemoveRepetitions(vector, varargin); % Removes repetitions (e.g. bursting neuron) from a vector or a matrix. % % ========================================================================= % Properties Values % ------------------------------------------------------------------------- % 'mode' 'all' (default) - removes all repetitions, keeping only % the first instance of the value (lie 'unique' but without % changing the order) % 'immediate' - removes a value only if it is an % immediate repetition of the value preceding it. % 'matrix' - removes repetitions within each row - these % will be substituted by NaNs. % % EXAMPLES: % [clean,cleanIndices,discarded] = RemoveRepetitions([1 1 3 4 5 5 5 2 1]), % clean = [1 3 4 5 2]; % cleanIndices = [1 3 4 5 8]; % discarded = [0 1 0 0 0 1 1 0 1]; % % [clean,cleanIndices,discarded] = RemoveRepetitions([1 1 3; 4 5 5; 5 2 1], 'mode', 'matrix'), % clean = [1 NaN 3; 4 5 NaN; 5 2 1]; % cleanIndices = [1 1; 1 3; 2 1; 2 2; 3 1; 3 2; 3 3]; % discarded = [0 1 0; 0 0 1; 0 0 0]; % % [clean,cleanIndices,discarded] = RemoveRepetitions([1 1 3 4 5 5 5 2 1], 'mode', 'immediate'), % clean = [1 3 4 5 2 1]; % cleanIndices = [1 3 4 5 8 9]; % discarded = [0 1 0 0 0 1 1 0 0]; % % Copyright (C) 2015 by Ralitsa Todorova % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 3 of the License, or % (at your option) any later version. mode = 'all'; % Options for i = 1:2:length(varargin), if ~ischar(varargin{i}), error(['Parameter ' num2str(i+1) ' is not a property (type ''help RemoveRepetitions'' for details).']); end switch(lower(varargin{i})), case 'mode', mode = lower(varargin{i+1}); if ~isastring(mode,'immediate','all','matrix') error('Incorrect value for property ''mode'' (type ''help RemoveRepetitions'' for details).'); end otherwise, error(['Unknown property ''' num2str(varargin{i}) ''' (type ''help RemoveRepetitions'' for details).']); end end if size(vector,2)>size(vector,1) && ~strcmp(mode, 'matrix'), turn = true; vector = vector(:); else turn = false; end if strcmp(mode, 'immediate'), discarded = [false; diff(vector)==0]; clean = vector(~discarded); cleanIndices = find(~discarded); elseif strcmp(mode, 'matrix'), % Each nan is unique, causing problems. Make them zeros to avoid such problems: discarded = false(size(vector)); nans = isnan(vector); vector(isnan(vector)) = 0; % should be a safe value [count, value] = hist(vector', unique(vector)); [elementIndex, sequenceIndex] = find(count>1); for i=unique(sequenceIndex)', repeatedValues = value(elementIndex(sequenceIndex==i)); repeatedValues(repeatedValues==0) = []; %remove repeats due to NaNs for j=1:length(repeatedValues), thismany = sum(vector(i,:)==repeatedValues(j)); discarded(i, find(vector(i,:)==repeatedValues(j),round(thismany-1),'last')) = 1; % letting the first one stay, the last n-1 will be discarded end end [x y] = find(~discarded); cleanIndices = sortrows([x y]); clean = vector; clean(discarded) = NaN; % Put the NaNs back in: clean(nans) = NaN; else [count, value] = hist(vector, unique(vector)); repeatedValues = value(count > 1); cleanIndices = find(~ismember(vector,repeatedValues)); for i=1:length(repeatedValues), cleanIndices = [cleanIndices; find(vector==repeatedValues(i),1,'first')]; end cleanIndices = sort(cleanIndices); discarded = ~Unfind(cleanIndices,length(vector)); clean = vector(cleanIndices); end if turn, clean = clean'; discarded = discarded'; end