# HG changeset patch
# User Steven <steven.waldrip@gmail.com>
# Date 1611415472 -39600
#      Sun Jan 24 02:24:32 2021 +1100
# Node ID acefc77c1e1af5c3334acd17fd652d7ba26083f7
# Parent  875d799ab0b349434497ae2b9573502df7e7177c
uniquetol.m: Implemented fast sorted method for when "byrows" is false (bug #59850).

diff -r 875d799ab0b3 -r acefc77c1e1a scripts/set/uniquetol.m
--- a/scripts/set/uniquetol.m	Sat Jan 23 11:27:46 2021 +0100
+++ b/scripts/set/uniquetol.m	Sun Jan 24 02:24:32 2021 +1100
@@ -166,58 +166,94 @@
     data_scale = max (abs (A(! isinf (A))(:)));
   endif
 
+  tol_data_scale = tol * data_scale;
+  
   if (by_rows)
-    isrowvec = false;
+    
+    points = rows (A);
+    d = columns (A);
+    Iall = zeros (points, 1);
+    I = NaN (d, 1);
+    ia = {};
+    J = NaN (d, 1);
+    j = 1;
+    ii = 0;
+    
+  
+    for i = 1:points
+      if (any (Iall == i))
+        continue;
+      else
+        equ = all (abs (A - A(i,:)) <= tol_data_scale, 2);
+        equ(i,1) = equ(i,1) || any (! isfinite (A(i,:)), 2);
+        sumeq = sum (equ);
+        ia_tmp = find (equ);
+        if (output_all_indices)
+          ia{end+1} = ia_tmp;
+        endif
+        Iall(ii+(1:sumeq)) = ia_tmp;
+        I(j) = ia_tmp(1);
+        J(equ) = j;
+        ii += sumeq;
+        j += 1;
+      endif
+    endfor
+  
+    I(isnan (I)) = [];
+    J(isnan (J)) = [];
+    c = A(I,:);
+
+    if (! output_all_indices)
+      ia = I(1:j-1);
+    endif
+    ic = J;
+    
   else
     isrowvec = isrow (A);
     A = A(:);
-  endif
-
-  points = rows (A);
-  d = columns (A);
-  Iall = zeros (points, 1);
-  I = NaN (d, 1);
-  ia = {};
-  J = NaN (d, 1);
-  j = 1;
-  ii = 0;
-  tol_data_scale = tol * data_scale;
-
-  for i = 1:points
-    if (any (Iall == i))
-      continue;
+    
+    [sortA, sAi] = sort (A);
+    diffsortA = diff (sortA);
+    ue = [true;diffsortA>tol_data_scale];
+    c = sortA(ue);
+    [~, sortsAi] = sort (sAi);
+    cumsumue = cumsum(ue);
+    ic = cumsumue(sortsAi);
+    isnanA = isnan (A);
+    anyisnanA = any (isnanA);
+    if anyisnanA
+      findisnanA = find (isnanA);
     else
-      equ = all (abs (A - A(i,:)) <= tol_data_scale, 2);
-      equ(i,1) = equ(i,1) || any (! isfinite (A(i,:)), 2);
-      sumeq = sum (equ);
-      ia_tmp = find (equ);
+      findisnanA = [];
+    endif
+    if (output_all_indices)
+      nu=cumsumue(end);
+      ia=cell (1,nu);
+      for k = 1:nu
+        ia{k} = setdiff (sAi(cumsumue==k),findisnanA);
+      endfor
+    else
+      ia = sAi(ue);
+    endif
+    
+    if anyisnanA
+      rowsc1=rows (c)+1;
+      c(rowsc1) = nan;
       if (output_all_indices)
-        ia{end+1} = ia_tmp;
+        ia(rowsc1)=findisnanA;
+      else
+        ia(rowsc1)=findisnanA(1);
       endif
-      Iall(ii+(1:sumeq)) = ia_tmp;
-      I(j) = ia_tmp(1);
-      J(equ) = j;
-      ii += sumeq;
-      j += 1;
+      ic(isnanA)=rowsc1;
     endif
-  endfor
-
-  I(isnan (I)) = [];
-  J(isnan (J)) = [];
-  c = A(I,:);
-
-  ## Matlab-compatible orientation of output
-  if (isrowvec)
-    c = c.';
-    I = I.';
-    J = J.';
+    
+    ## Matlab-compatible orientation of output
+    if (isrowvec)
+      c = c.';
+    endif
+    
   endif
 
-  if (! output_all_indices)
-    ia = I(1:j-1);
-  endif
-  ic = J;
-
 endfunction
 
 
@@ -232,7 +268,7 @@
 %!assert (uniquetol ([1; 2]), [1; 2])
 %!xtest <59850>
 %! ## FIXME: Matlab returns only one unique value for Inf.
-%! assert (uniquetol ([-Inf, 1, NaN, Inf, NaN, Inf]), [-Inf, 1, Inf, NaN, NaN]);
+%! assert (uniquetol ([-Inf, 1, NaN, Inf, NaN, Inf]), [-Inf, 1, Inf, NaN]);
 %!xtest <59850>
 %! ## FIXME: Matlab returns empty column vectors.
 %! ##        Do we want to bother with that?
@@ -241,7 +277,7 @@
 %!assert (uniquetol ([1,2,2,3,2,4], "byrows", true), [1,2,2,3,2,4])
 %!assert (uniquetol ([1,2,2,3,2,4]), [1,2,3,4])
 %!assert (uniquetol ([1,2,2,3,2,4].', "byrows", true), [1;2;3;4])
-%!assert (uniquetol (sparse ([2,0;2,0])), sparse ([2;0]))
+%!assert (uniquetol (sparse ([2,0;2,0])), sparse ([0;2]))
 %!assert (uniquetol (sparse ([1,2;2,3])), sparse ([1;2;3]))
 %!assert (uniquetol (single ([1,2,2,3,2,4]), "byrows", true),
 %!        single ([1,2,2,3,2,4]))
@@ -268,7 +304,7 @@
 %! x = (2:7)'*pi;
 %! y = exp (log (x));
 %! C = uniquetol ([x; y]);
-%! assert (C, x);
+%! assert (C, x,1e-12);
 
 ## Test "ByRows" Property
 %!test
