]> Creatis software - CreaPhase.git/blobdiff - octave_packages/nan-2.5.5/quantile.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / nan-2.5.5 / quantile.m
diff --git a/octave_packages/nan-2.5.5/quantile.m b/octave_packages/nan-2.5.5/quantile.m
new file mode 100644 (file)
index 0000000..007d608
--- /dev/null
@@ -0,0 +1,151 @@
+function Q=quantile(Y,q,DIM,method)
+% QUANTILE calculates the quantiles of histograms and sample arrays.  
+%
+%  Q = quantile(Y,q)
+%  Q = quantile(Y,q,DIM)
+%     returns the q-th quantile along dimension DIM of sample array Y.
+%     size(Q) is equal size(Y) except for dimension DIM which is size(Q,DIM)=length(Q)
+%
+%  Q = quantile(HIS,q)
+%     returns the q-th quantile from the histogram HIS. 
+%     HIS must be a HISTOGRAM struct as defined in HISTO2 or HISTO3.
+%     If q is a vector, the each row of Q returns the q(i)-th quantile 
+%
+% see also: HISTO2, HISTO3, PERCENTILE
+
+
+%      $Id: quantile.m 9601 2012-02-09 14:14:36Z schloegl $
+%      Copyright (C) 1996-2003,2005,2006,2007,2009,2011 by Alois Schloegl <alois.schloegl@gmail.com>   
+%       This function is part of the NaN-toolbox
+%       http://pub.ist.ac.at/~schloegl/matlab/NaN/
+
+%    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.
+%
+%    This program is distributed in the hope that it will be useful,
+%    but WITHOUT ANY WARRANTY; without even the implied warranty of
+%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+%    GNU General Public License for more details.
+%
+%    You should have received a copy of the GNU General Public License
+%    along with this program; If not, see <http://www.gnu.org/licenses/>.
+
+if nargin<3,
+        DIM = [];
+end;
+if isempty(DIM),
+        DIM = find(size(Y)>1,1);
+        if isempty(DIM), DIM = 1; end;
+end;
+
+
+if nargin<2,
+       help quantile
+        
+else
+       [q, rix]  = sort(q(:)');        % sort quantile values 
+       [tmp,rix] = sort(rix);  % generate reverse index 
+
+        SW = isstruct(Y);
+        if SW, SW = isfield(Y,'datatype'); end;
+        if SW, SW = strcmp(Y.datatype,'HISTOGRAM'); end;
+        if SW,                 
+                [yr, yc] = size(Y.H);
+                Q = repmat(nan,length(q),yc);
+                if ~isfield(Y,'N');
+                        Y.N = sum(Y.H,1);
+                end;
+                
+                for k1 = 1:yc,
+                        tmp = Y.H(:,k1)>0;
+                        h = full(Y.H(tmp,k1));
+                        t = Y.X(tmp,min(size(Y.X,2),k1));
+
+                       N = Y.N(k1);  
+                       t2(1:2:2*length(t)) = t;
+                       t2(2:2:2*length(t)) = t;
+                       x2 = cumsum(h); 
+                       x(1)=0; 
+                       x(2:2:2*length(t)) = x2;
+                       x(3:2:2*length(t)) = x2(1:end-1);
+
+                       % Q(q < 0 | 1 < q,:) = NaN;  % already done at initialization
+                       Q(q==0,k1) = t2(1);
+                       Q(q==1,k1) = t2(end);
+                       n = 1; 
+                       for k2 = find( (0 < q) & (q < 1) )
+                               while (q(k2)*N > x(n)),
+                                       n=n+1; 
+                               end;
+
+                               if q(k2)*N==x(n)
+                                       % mean of upper and lower bound 
+                                       Q(k2,k1) = (t2(n)+t2(n+1))/2;
+                               else
+                                       Q(k2,k1) = t2(n);
+                               end;
+                        end;
+                       Q = Q(rix,:);   % order resulting quantiles according to original input q 
+                end;
+
+
+        elseif isnumeric(Y),
+               sz = size(Y);
+               if DIM>length(sz),
+                       sz = [sz,ones(1,DIM-length(sz))];
+               end;
+
+               f  = zeros(1,length(q));        
+               f( (q < 0) | (1 < q) ) = NaN;
+               D1 = prod(sz(1:DIM-1));
+               D3 = prod(sz(DIM+1:length(sz)));
+               Q  = repmat(nan,[sz(1:DIM-1),length(q),sz(DIM+1:length(sz))]);
+               for k = 0:D1-1,
+               for l = 0:D3-1,
+                       xi = k + l * D1*sz(DIM) + 1 ;
+                       xo = k + l * D1*length(q) + 1;
+                       t  = Y(xi:D1:xi+D1*sz(DIM)-1);
+                       t  = t(~isnan(t));
+                       N  = length(t); 
+                       
+                       if (N==0)
+                               f(:) = NaN;        
+                       else
+                               t  = sort(t);
+                               t2(1:2:2*length(t)) = t; 
+                               t2(2:2:2*length(t)) = t;
+                               x = floor((1:2*length(t))/2);
+                               %f(q < 0 | 1 < q) = NaN;  % for efficiency its defined outside loop 
+                               f(q==0) = t2(1);
+                               f(q==1) = t2(end);
+
+                               n = 1; 
+                               for k2 = find( (0 < q) & (q < 1) )
+                                       while (q(k2)*N > x(n)),
+                                               n = n+1;
+                                       end;
+
+                                       if q(k2)*N==x(n)
+                                               % mean of upper and lower bound 
+                                               f(k2) = (t2(n) + t2(n+1))/2;   
+                                       else
+                                               f(k2) = t2(n);
+                                       end; 
+                               end;            
+                       end; 
+                       Q(xo:D1:xo + D1*length(q) - 1) = f(rix);
+               end;
+               end;
+
+        else
+                fprintf(2,'Error QUANTILES: invalid input argument\n');
+                return;
+        end;
+        
+end;
+
+%!assert(quantile(1:10,[.2,.5]),[2.5, 5.5])
+
+