InIntervals - Test which values fall in a list of intervals. USAGE [status,interval,index] = InIntervals(values,intervals,<options>) values values to test (see NOTE below) intervals list of (start,stop) pairs <options> optional list of property-value pairs (see table below) ========================================================================= Properties Values ------------------------------------------------------------------------- 'mode' 'fast' if values are sorted in ascending order (see NOTE below), 'safe' otherwise (default = 'safe') 'verbose' display information about ongoing processing (default = 'off') ========================================================================= OUTPUT status logical indices (1 = belongs to one of the intervals, 0 = belongs to none) interval for each value, the index of the interval to which it belongs (0 = none) index for each value, its index in the interval to which it belongs (0 = none) NOTES Depending on the number of values to test, the 'fast' mode can be orders of magnitude faster, but will return inaccurate results if the values are not sorted in ascending order. If the intervals overlap, the outputs 'interval' and 'index' refer to the last overlapping interval (i.e. if one value belongs to intervals #7 and #8, it will be listed as belonging to interval #8). SEE See also ConsolidateIntervals, SubtractIntervals, ExcludeIntervals, Restrict, FindInInterval, CountInIntervals, ToIntervals, PlotIntervals
0001 function [status,interval,index] = InIntervals(values,intervals,varargin) 0002 0003 %InIntervals - Test which values fall in a list of intervals. 0004 % 0005 % USAGE 0006 % 0007 % [status,interval,index] = InIntervals(values,intervals,<options>) 0008 % 0009 % values values to test (see NOTE below) 0010 % intervals list of (start,stop) pairs 0011 % <options> optional list of property-value pairs (see table below) 0012 % 0013 % ========================================================================= 0014 % Properties Values 0015 % ------------------------------------------------------------------------- 0016 % 'mode' 'fast' if values are sorted in ascending order (see 0017 % NOTE below), 'safe' otherwise (default = 'safe') 0018 % 'verbose' display information about ongoing processing 0019 % (default = 'off') 0020 % ========================================================================= 0021 % 0022 % OUTPUT 0023 % 0024 % status logical indices (1 = belongs to one of the intervals, 0025 % 0 = belongs to none) 0026 % interval for each value, the index of the interval to which 0027 % it belongs (0 = none) 0028 % index for each value, its index in the interval to which 0029 % it belongs (0 = none) 0030 % 0031 % NOTES 0032 % 0033 % Depending on the number of values to test, the 'fast' mode can be orders 0034 % of magnitude faster, but will return inaccurate results if the values are 0035 % not sorted in ascending order. 0036 % 0037 % If the intervals overlap, the outputs 'interval' and 'index' refer to the 0038 % last overlapping interval (i.e. if one value belongs to intervals #7 and #8, 0039 % it will be listed as belonging to interval #8). 0040 % 0041 % SEE 0042 % 0043 % See also ConsolidateIntervals, SubtractIntervals, ExcludeIntervals, 0044 % Restrict, FindInInterval, CountInIntervals, ToIntervals, PlotIntervals 0045 0046 % Copyright (C) 2004-2015 by Michaƫl Zugaro 0047 % 0048 % This program is free software; you can redistribute it and/or modify 0049 % it under the terms of the GNU General Public License as published by 0050 % the Free Software Foundation; either version 3 of the License, or 0051 % (at your option) any later version. 0052 0053 % Default values 0054 verbose = false; 0055 safe = true; 0056 0057 % Check number of parameters 0058 if nargin < 2 || mod(length(varargin),2) ~= 0, 0059 error('Incorrect number of parameters (type ''help <a href="matlab:help InIntervals">InIntervals</a>'' for details).'); 0060 end 0061 0062 % Check parameters 0063 if ~isdmatrix(intervals) || size(intervals,2) ~= 2, 0064 error('Incorrect intervals (type ''help <a href="matlab:help InIntervals">InIntervals</a>'' for details).'); 0065 end 0066 0067 if size(values,1) == 1, 0068 values = values(:); 0069 end 0070 0071 % Parse parameter list 0072 for i = 1:2:length(varargin), 0073 if ~ischar(varargin{i}), 0074 error(['Parameter ' num2str(i+2) ' is not a property (type ''help <a href="matlab:help InIntervals">InIntervals</a>'' for details).']); 0075 end 0076 switch(lower(varargin{i})), 0077 case 'verbose', 0078 verbose = varargin{i+1}; 0079 if ~isastring(verbose,'on','off'), 0080 error('Incorrect value for property ''verbose'' (type ''help <a href="matlab:help InIntervals">InIntervals</a>'' for details).'); 0081 end 0082 verbose = strcmp(verbose,'on'); 0083 case 'mode', 0084 mode = varargin{i+1}; 0085 if ~isastring(mode,'safe','fast'), 0086 error('Incorrect value for property ''mode'' (type ''help <a href="matlab:help InIntervals">InIntervals</a>'' for details).'); 0087 end 0088 safe = strcmp(mode,'safe'); 0089 otherwise, 0090 error(['Unknown property ''' num2str(varargin{i}) ''' (type ''help <a href="matlab:help InIntervals">InIntervals</a>'' for details).']); 0091 end 0092 end 0093 0094 % Sort if necessary 0095 if safe, 0096 [values,order] = sortrows(values(:,1)); 0097 end 0098 0099 % Max nb of digits for display 0100 if verbose, l = int2str(floor(log10(max(max(intervals*100))))+2); end 0101 0102 % Determine if intervals overlap (in which case we must use a 'slow' algorithm) 0103 i = sortrows(intervals,1); 0104 di = i(2:end,1)-i(1:end-1,2); 0105 overlap = any(di<0); 0106 if ~overlap, 0107 % Fast algorithm: for the next interval, start from the end of the previous interval 0108 k = 2; 0109 else 0110 % Slow algorithm: for the next interval, start from the beginning of the previous interval 0111 k = 1; 0112 end 0113 0114 % Retrieve values in intervals 0115 previous = 1; 0116 n = size(intervals,1); 0117 status = false(size(values)); 0118 interval = zeros(size(values)); 0119 index = zeros(size(values)); 0120 for i = 1:n, 0121 from = intervals(i,1); 0122 to = intervals(i,2); 0123 0124 % Get values 0125 more = FindInInterval(values,[from to],previous); 0126 if ~isempty(more), 0127 previous = more(k); % See note above about algorithm 0128 nMore = more(2)-more(1)+1; 0129 interval(more(1):more(2)) = i; 0130 status(more(1):more(2)) = 1; 0131 index(more(1):more(2)) = (1:nMore); 0132 end 0133 if verbose, timeString = sprintf(['%' l '.2f %' l '.2f (%' l '.2f)'],from,to,to-from); disp([timeString ' - ' int2str(nMore) ' values']); end 0134 end 0135 0136 if safe, 0137 status(order) = status; 0138 interval(order) = interval; 0139 index(order) = index; 0140 end