Home > FMAToolbox > General > InIntervals.m

InIntervals

PURPOSE ^

InIntervals - Test which values fall in a list of intervals.

SYNOPSIS ^

function [status,interval,index] = InIntervals(values,intervals,varargin)

DESCRIPTION ^

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

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

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

Generated on Fri 16-Mar-2018 13:00:20 by m2html © 2005