members count (and locate) in an array each element or row or column of another array

## Syntax

                [nb [,loc]] = members(N, H)
                [nb [,loc]] = members(N, H, "last")
                [nb [,loc]] = members(N, H, "rows"|"cols")
                [nb [,loc]] = members(N, H, "rows"|"cols", "last")
                [nb [,loc]] = members(N, H, "rows"|"cols", "shuffle")
                [nb [,loc]] = members(N, H, "rows"|"cols", "shuffle", "last")

## Arguments

N

  Needles: matrix or hypermatrix of booleans, integer-encoded numbers, real or complex decimal numbers, polynomials or texts. In "rows" or "cols" mode, no hypermatrix is accepted. A given value (or row or column) may appear several times in `N`.

H

  Haystack: matrix or hypermatrix of same data type as `N`. In "rows" or "cols" mode, no hypermatrix is accepted, and `N` and `H` must have respectively the same number of columns or rows.

Options:

  From one to three options may be specified in any order:

  "last"

    when the location in `H` of needles from `N` is querried through `loc`, by default the position of the first respective occurrences in `H` are returned. If `"last"` is specified, the position of the last occurrences in `H` are returned instead.

  "rows", "cols"

    By default, each element `N(i, j, ...)` of `N` is considered as a needle to search in `H`. If `"rows"` is specified, each row of `N` is considered as a needle -- as a whole --, and is searched among rows of `H`. The same applies between columns of `N` and `H` if `"cols"` is used.

  "shuffle"

    In `"rows"` or `"cols"` mode, by default the order of components of a row/column is considered: for instance, `[ 7 3 5 ]` in `N` does not match `[3 5 7]` in `H`. When `"shuffle"` is specified, any permutation of --say--`[3 5 7]` will be considered as matching a `[3 5 7]` row of `N`. This option is ignored for polynomials.

nb

  In normal mode: `nb(i, j, ...)` returns (as reals) the number of occurrences in `H` of `N(i, j, ...)`. `nb` and `N` have the same format. If `H` is empty, a matrix of zeros is returned. If `N` is empty, the empty matrix `[]` is returned.

  In `"rows"` or `"cols"` mode: `nb` is a row of reals with as many components as `N` has rows/columns. `nb(i)` returns the number of occurrences in `H(., :)` of `N(i, :)` (or of `N(:, i)` in `H(:, .)` ).

loc

  In normal mode: `loc` and `N` have the same format. `loc(i, j, ...)` returns the smallest linearized index in `H` where `N(i, j, ...)` occurs. If the `"last"` flag is used, the greatest linearized index is returned instead. If `N(i, j, ...)` in not found in `H`, `loc(i, j, ...)` is set to `0`.

  In `"rows"` or `"cols"` mode: `loc` is a row of reals with as many components as `N` has respectively rows or columns. `loc(i)` returns the index of the first line `H(loc(i), :)` matching `N(i, :)` (or the index of the first column `H(:, loc(i))` matching `N(:, i)`). If the `"shuffle"` flag is additionally specified, the order of components along the rows/columns is not considered.

## Description

`nb = members(N, H [,"rows"|"cols"])` returns the number of occurrences of each component or row or column of `N` found in `H`. If no match is found for an element, 0 is returned for it. The index in `H` of the first (default) or `"last"` occurrence of `N(i,j,...)` can be querried through a second optional output `loc`. If matching `"rows"` or `"cols"` are searched for, matches can ignore the order of their elements, by using the option `"shuffle"`.

`%inf` and `-%inf` values are supported in `N` as well as in `H`. In normal mode, `%nan` are supported in `N` but not in `H`. In `"rows"` or `"cols"` modes, `%nan` are supported everywhere.

In normal element-wise mode, members(..) uses dsearch(..) to proceed fast with booleans, integer-encoded numbers (any length 8-16-32 bits signed or not), and real numbers. For complex numbers, texts, and polynomials, a slower and more memory-consuming algorithm is used. For long calculations, a progression bar is displayed.

## Examples

    N = [1 8 4 5 2 1];
    H = [9 7 4 2 1 4];

    [nb, loc] = members(N, H, "last")
    // Returns nb  = [1 0 2 0 1 1]: for instance, 4 appears twice in H.
    // And     loc = [5 0 6 0 4 5]: the last occurrence of 4 is in sixth position in H

    [nb, loc] = members(N, H)
    // Returns loc = [5 0 3 0 4 5]: the 1st occurrence of 4 is in third position in H

    // With hypermatrices. From previous N and H:
    N = matrix(N, [3 1 2]);
    H = matrix(H, [3 1 2]);
    [nb, loc] = members(N, H, "last")

    // With integers:
    N = int8(grand(3, 2, "uin", -5, 5));
    H = int8(grand(4, 4, "uin", -5, 5));
    [nb, loc] = members(N, H)

    // With polynomials (complex coefficients are accepted):
    z = %z;
    N = [z (1-z)^2 ; -4 %i*z ];
    H = [2  %i*z -z  3-z  z  z^3 z];
    [nb, loc] = members(N, H)

    // With text:
    N = [ "Hi" "Hu" "Allo"];
    H = [ "Hello" "Bonjour" "Allo"
          "Holà"  "Allo"  "Hallo"
          "Hi"    "Hé"    "Salud" ];
    [nb, loc] = members(N, H, "last")

    // By rows:
     H = [
      3  3  0
      4  1  0
      2  0  3
      0  1  4
      3  4  3
      0  4  1
      3  1  0
      ];
     N = [
      1  2  3
      0  1  4
      3  0  3
      4  1  0
      2  0  2
      ];
     N, H
     [nb, loc] = members(N, H, "rows")
     [nb, loc] = members(N, H, "rows","last")
     [nb, loc] = members(N, H, "rows","shuffle") // [4 1 0], [0 1 4] and [0 4 1] are considered the same

    // By columns: From N and H defined above:
     N = N.', H = H.'
     [nb, loc] = members(N, H, "cols", "shuffle")

## See also

- dsearch
- intersect
- grep
- find
- vectorfind

## History

5.5.0 members() function introduced.