Sets
****

Octave has a number of functions for managing sets of data.  A set is defined as a collection of unique elements and is typically represented by a vector of numbers sorted in ascending order.  Any vector or matrix can be converted to a set by removing duplicates through the use of the unique function. However, it isn't necessary to explicitly create a set as all of the functions which operate on sets will convert their input to a set before proceeding.

 -- Y =: unique (X)
 -- Y =: unique (X, "rows")
 -- Y =: unique (..., "sorted")
 -- Y =: unique (..., "stable")
 -- [Y, I, J] =: unique (...)
 -- [Y, I, J] =: unique (..., "first")
 -- [Y, I, J] =: unique (..., "last")
 -- [Y, I, J] =: unique (..., "legacy")
     Return the unique elements of X.

     If the input X is a column vector then return a column vector; Otherwise, return a row vector.  X may also be a cell array of strings.

     If the optional argument "rows" is given then return the unique rows of X.  The input must be a 2-D numeric matrix to use this option.

     The optional argument "sorted"/"stable" controls the order in which unique values appear in the output.  The default is "sorted" and values in the output are placed in ascending order. The alternative "stable" preserves the order found in the input X.

     If requested, return column index vectors I and J such that Y = X(I) and X = Y(J).

     Additionally, if I is a requested output then one of the flags "first" or "last" may be given.  If "last" is specified, return the highest possible indices in I, otherwise, if "first" is specified, return the lowest.  The default is "first".

     Example 1 : sort order

          unique ([3, 1, 1, 2])
          => [1, 2, 3]
          unique ([3, 1, 1, 2], "stable")
          => [3, 1, 2]

     Example 2 : index selection

          [~, I] = unique ([3, 1, 1, 2], "first")
          => I = [2; 4; 1]
          [~, I] = unique ([3, 1, 1, 2], "last")
          => I = [3; 4; 1]

     Programming Notes: The input flag "legacy" changes the algorithm to be compatible with MATLAB releases prior to R2012b.  Specifically, The index ordering flag is changed to "last", and the shape of the outputs I, J will follow the shape of the input X rather than always being column vectors.

     The third output, J, has not been implemented yet when the sort order is "stable".

     uniquetol, union, intersect, setdiff, setxor, ismember

 -- C =: uniquetol (A)
 -- C =: uniquetol (A, TOL)
 -- C =: uniquetol (..., PROPERTY, VALUE)
 -- [C, IA, IC] =: uniquetol (...)
     Return the unique elements of A within tolerance TOL.

     Two values, X and Y, are within relative tolerance if abs (X - Y) <= TOL * max (abs (A(:))).

     The input A must be a real (non-complex) floating point type (double or single).

     If TOL is unspecified, the default tolerance is 1e-12 for double precision input or 1e-6 for single precision input.

     The function may also be called with the following optional property/value pairs.  Property/value pairs must be passed after other input arguments:

     "ByRows" (default: false)
          When true, return the unique rows of A.  A must be a 2-D array to use this option.  For rows, the criteria for uniqueness is changed to all (abs (X - Y) <= TOL*max (abs (A),[],1)) which compares each column component of a row against a column-specific tolerance.

     "DataScale"
          The tolerance test is changed to abs (X - Y) <= TOL*DS where DS is a scalar unless the property "ByRows" is true.  In that case, DS can either be a scalar or a vector with a length equal to the number of columns in A.  Using a value of 1.0 for DS will change the tolerance from a relative one to an absolute tolerance.  Using a value of Inf will disable testing.

     "OutputAllIndices" (default: false)
          When true, IA is a cell array (not a vector) that contains the indices for all elements in A that are within tolerance of a value in C.  That is, each cell in IA corresponds to a single unique value in C, and the values in each cell correspond to locations in A.

     The output C is a row vector if the input A is a row vector. For all other cases, a column vector is returned.

     The optional output IA is a column index vector such that C = A(IA).  If the "ByRows" property is true, the condition is C = A(IA, :).  If the "OutputAllIndices" property is true, then the values A(IA{I}) are all within tolerance of the unique value C(I).

     The optional output IC is a column index vector such that A = C(IC) when A is a vector.  When A is a matrix, A(:) = C(IC).  If the "ByRows" property is true then A = C(IC,:).

     Example: small round-off errors require uniquetol, not unique

          x = [1:5];
          ## Inverse_Function (Function (x)) should return exactly x
          y = exp (log (x));
          D = unique ([x, y])
          => [1   2   3   3   4   5   5]
          C = uniquetol ([x, y])
          => [1   2   3   4   5]

     unique, union, intersect, setdiff, setxor, ismember

Set Operations
==============

Octave supports several basic set operations.  Octave can compute the union, intersection, and difference of two sets.  Octave also supports the Exclusive Or set operation.

The functions for set operations all work in the same way by accepting two input sets and returning a third set.  As an example, assume that a and b contains two sets, then

     union (a, b)

computes the union of the two sets.

Finally, determining whether elements belong to a set can be done with the ismember function.  Because sets are ordered this operation is very efficient and is of order O(log2(n)) which is preferable to the find function which is of order O(n).

 -- C =: intersect (A, B)
 -- C =: intersect (A, B, "rows")
 -- C =: intersect (..., "sorted")
 -- C =: intersect (..., "stable")
 -- C =: intersect (..., "legacy")
 -- [C, IA, IB] =: intersect (...)

     Return the unique elements common to both A and B.

     If A and B are both row vectors then return a row vector; Otherwise, return a column vector.  The inputs may also be cell arrays of strings.

     If the optional input "rows" is given then return the common rows of A and B.  The inputs must be 2-D numeric matrices to use this option.

     The optional argument "sorted"/"stable" controls the order in which unique values appear in the output.  The default is "sorted" and values in the output are placed in ascending order. The alternative "stable" preserves the order found in the input.

     If requested, return column index vectors IA and IB such that C = A(IA) and C = B(IB).

     Programming Note: The input flag "legacy" changes the algorithm to be compatible with MATLAB releases prior to R2012b.

     unique, union, setdiff, setxor, ismember

 -- C =: union (A, B)
 -- C =: union (A, B, "rows")
 -- C =: union (..., "sorted")
 -- C =: union (..., "stable")
 -- C =: union (..., "legacy")
 -- [C, IA, IB] =: union (...)

     Return the unique elements that are in either A or B.

     If A and B are both row vectors then return a row vector; Otherwise, return a column vector.  The inputs may also be cell arrays of strings.

     If the optional input "rows" is given then return rows that are in either A or B.  The inputs must be 2-D numeric matrices to use this option.

     The optional argument "sorted"/"stable" controls the order in which unique values appear in the output.  The default is "sorted" and values in the output are placed in ascending order. The alternative "stable" preserves the order found in the input.

     The optional outputs IA and IB are column index vectors such that A(IA) and B(IB) are disjoint sets whose union is C.

     Programming Note: The input flag "legacy" changes the algorithm to be compatible with MATLAB releases prior to R2012b.

     unique, intersect, setdiff, setxor, ismember

 -- C =: setdiff (A, B)
 -- C =: setdiff (A, B, "rows")
 -- C =: setdiff (..., "sorted")
 -- C =: setdiff (..., "stable")
 -- C =: setdiff (..., "legacy")
 -- [C, IA] =: setdiff (...)
     Return the unique elements in A that are not in B.

     If A is a row vector return a row vector; Otherwise, return a column vector.  The inputs may also be cell arrays of strings.

     If the optional input "rows" is given then return the rows in A that are not in B.  The inputs must be 2-D numeric matrices to use this option.

     The optional argument "sorted"/"stable" controls the order in which unique values appear in the output.  The default is "sorted" and values in the output are placed in ascending order. The alternative "stable" preserves the order found in the input.

     If requested, return the index vector IA such that C = A(IA).

     Programming Note: The input flag "legacy" changes the algorithm to be compatible with MATLAB releases prior to R2012b.

     unique, union, intersect, setxor, ismember

 -- C =: setxor (A, B)
 -- C =: setxor (A, B, "rows")
 -- C =: setxor (..., "sorted")
 -- C =: setxor (..., "stable")
 -- C =: setxor (..., "legacy")
 -- [C, IA, IB] =: setxor (...)

     Return the unique elements exclusive to sets A or B.

     If A and B are both row vectors then return a row vector; Otherwise, return a column vector.  The inputs may also be cell arrays of strings.

     If the optional input "rows" is given then return the rows exclusive to sets A and B.  The inputs must be 2-D numeric matrices to use this option.

     The optional argument "sorted"/"stable" controls the order in which unique values appear in the output.  The default is "sorted" and values in the output are placed in ascending order. The alternative "stable" preserves the order found in the input.

     The optional outputs IA and IB are column index vectors such that A(IA) and B(IB) are disjoint sets whose union is C.

     Programming Note: The input flag "legacy" changes the algorithm to be compatible with MATLAB releases prior to R2012b.

     unique, union, intersect, setdiff, ismember

 -- TF =: ismember (A, S)
 -- TF =: ismember (A, S, "rows")
 -- [TF, S_IDX] =: ismember (...)

     Return a logical matrix TF with the same shape as A which is true (1) if the element in A is found in S and false (0) if it is not.

     If a second output argument is requested then the index into S of each matching element is also returned.

          a = [3, 10, 1];
          s = [0:9];
          [tf, s_idx] = ismember (a, s)
               => tf = [1, 0, 1]
               => s_idx = [4, 0, 2]

     The inputs A and S may also be cell arrays.

          a = {"abc"};
          s = {"abc", "def"};
          [tf, s_idx] = ismember (a, s)
               => tf = 1
               => s_idx = 1

     If the optional third argument "rows" is given then compare rows in A with rows in S.  The inputs must be 2-D matrices with the same number of columns to use this option.

          a = [1:3; 5:7; 4:6];
          s = [0:2; 1:3; 2:4; 3:5; 4:6];
          [tf, s_idx] = ismember (a, s, "rows")
               => tf = logical ([1; 0; 1])
               => s_idx = [2; 0; 5];

     lookup, unique, union, intersect, setdiff, setxor, ismembertol

 -- TF =: ismembertol (A, S)
 -- TF =: ismembertol (A, S, TOL)
 -- TF =: ismembertol (A, S, NAME, VALUE)
 -- [TF, S_IDX] =: ismembertol (...)
     Check if values are members of a set within a tolerance.

     This functions returns a logical matrix TF with the same shape as A which is true (1) where the element in A is close to S within a tolerance TOL and false (0) if it is not.  If TOL is not specified, a default tolerance of 1e-6 is used.

     If a second output argument is requested then the index into S of each matching element is also returned.

     The inputs A and S must be numeric values.

          a = [3, 10, 1];
          s = [0:9];
          [tf, s_idx] = ismembertol (a, s)
               => tf = [1, 0, 1]
               => s_idx = [4, 0, 2]

     Optional property/value pairs may be given to change the function's behavior.  The property may be one of following strings:

     "ByRows"
          If set to false (default), all elements in A and S are treated separately.  If set to true, TF will be true for each row in A that matches a row in S within the given tolerance.  Two rows, U and V, are within tolerance if they fulfill the condition all (abs (u-v) <= tol*max (abs ([a;s]))).

     "OutputAllIndices"
          If set to false (default), S_IDX contains indices for one of the matches.  If set to true, S_IDX is a cell array containing the indices for all elements in S that are within tolerance of the corresponding value in A.

     "DataScale"
          The provided value DS is used to change the scale factor in the tolerance test to abs (u-v) <= tol*DS.  By default, the maximum absolute value in A and S is used as the scale factor.

     Example:

          s = [1:6].' * pi;
          a = 10.^log10 (x);
          [tf, s_idx] = ismembertol (a, s);

     ismember, lookup, unique, union, intersect, setdiff, setxor

 -- P =: powerset (A)
 -- P =: powerset (A, "rows")
     Compute the powerset (all subsets) of the set A.

     The set A must be a numerical matrix or a cell array of strings.  The output will always be a cell array of either vectors or strings.

     With the optional argument "rows", each row of the set A is considered one element of the set.  The input must be a 2-D numeric matrix to use this argument.

     unique, union, intersect, setdiff, setxor, ismember