vectorfind ищет расположение вектора (отмеченный символом групповой подстановки) в матрице или гиперматрице

## Синтаксис

                ind             = vectorfind(haystack, needle)
                ind             = vectorfind(haystack, needle, dimAlong)
                ind             = vectorfind(haystack, needle, dimAlong, ,indType)
                [ind, matching] = vectorfind(haystack, needle, dimAlong, joker)
                [ind, matching] = vectorfind(haystack, needle, dimAlong, joker, indType)

## Аргументы

haystack

  Матрица или гиперматрица любого типа, возможно разрежённая: массив в котором будет идти поиск вектора.

needle

  Вектор, который надо искать в `haystack`, того же самого типа. Если `haystack` является разрежённой, то `needle` может быть неразрежённой. К тому же, если `haystack` является логической и используется `joker`, то `needle` должна быть числовой, а не логической. В этом случае любой её ненулевой элемент считается равным `%T`.

  - Десятичные числа, комплексные числа и кодированные целые числа считаются одним типом: числовым.
  - Значения `%nan` принимаются в `needle`. Они обрабатываются обычным способом, как и другие значения. Они совпадают только с `%nan` в `haystack`.
dimAlong

  Направление внутри массива `haystack` вдоль которого идёт поиск вектора `needle`. Возможными значениями являются `"r"` или `1` (вдоль строк), `"c"` или `2` (вдоль столбцов) или для гиперматрицы любое целое значение, такое, что `2 < dimAlong <= ndims(haystack)`, представляющее индекс сканируемого измерения. По умолчанию используется `"r"`.

  `dimAlong` обязателен, когда определён `joker` или `indType`.
joker

  Одиночный элемент типа данных `needle`. Элементы `needle`, равные значению `joker` игнорируются (сопоставляются/принимаются любые значения из `haystack`).

  Когда `haystack` является логическим, то `joker` должно быть ненулевым числом.

  Чтобы пропустить `joker`, укажите `..dimAlong, ,indType` без значения `joker`.

indType

  Одиночное нечувствительное к регистру слово внутри кавычек `""` (по умолчанию без текста), `"headIJK"` и `"headN"`: Определяет формат или индексы. Смотрите ниже описание переменной `ind`.

ind

  - Если `needle` по размеру больше, чем `haystack`, в выбранной размерности `dimAlong`, и возвращается `ind=[]`.

  - Если длина `needle` соответствует по размеру `haystack` по выбранной размерности:

    - По умолчанию (`indType==""`): `ind` является вектором-строкой, содержащей индексы совпавших строк и столбцов `haystack`. В случае гиперматрицы возвращаемые индексы совпавших диапазонов линеаризованы через все размерности кроме одной `dimAlong` (см. примеры).

    - indType="headN": `ind` является вектором-строкой линейных индексов в `haystack` первых элементов совпавших строк, столбцов и более высоких диапазонов.

    - indType="headIJK": `ind` является матрицей: каждая строка возвращает индексы `[i j ..]` в `haystack` первых элементов совпавших диапазонов (строки, столбцы или более высокие диапазоны). `ind` имеет столько строк, сколько совпавших диапазонов в `haystack`.

  - В противном случае (короткая `needle`): По умолчанию, `ind` является вектором-строкой линейных индексов элементов `haystack`, где начинаются совпавшие диапазоны. Используя опцию `indType="headN"` ни к чему не приводит. Использование `indType="headIJK"` возвращает `ind` в виде матрицы индексов `[i j k ..]`, как было описано выше.

  Возвращаемые индексы сортированы в порядке возрастания.
matching

  Когда используется `matching` выходная необязательная переменная `matching` является матрицей с типом данных, как у `haystack`, возвращающей фактические диапазоны совпадения: диапазон совпадения №i возвращается в строке `matching(i,:)`.

  Когда `haystack` является разрежённой, то матрица `matching` тоже является разрежённой.

## Описание

`vectorfind()` ищет указанную последовательность значений `needle` (иголка) в массиве `haystack` (стог сена) по указанному прямому направлению/измерению: ширина (строки), высота (столбцы), толщина (подобно пикселям RGB) и т.д. Иголка `needle` может быть длиннее или короче, чем размер исследуемой стороны стога сена `haystack`.

Может быть определено специальное значение, так называемый джокер. Тогда это значение работает, как символ универсальной подстановки там, где он встречается в векторе иглы `needle`. Поскольку это значение более нельзя выбирать, то -- ЛЮБОЕ значение после совпадений в стогу сена `haystack` на своей позиции --, оно не может одновременно использоваться в игле `needle` в качестве выбираемого. На практике любое значение, не представленное в стоге сена `haystack`, обязательно требует хорошего джокера. Однако, это условие не является обязательным.

Следовательно: когда стог сена `haystack` является логическим, то джокер -- а также вектор иглы `needle` -- должен быть числовым. Действительно, в противном случае было бы невозможно выбрать значение джокера из ограниченного множества значений `{%T, %F}`.

Когда такой символ универсальной подстановки используется, то фактические значения в совпавших диапазонах не фиксируются. Тогда можно получить их благодаря необязательной выходной переменной `matching`. В противном случае `matching` будет пустой (это тривиальный повтор вектора иглы `needle`).

### Поиск в гиперматрицах

Использование `vectorfind()` с гиперматрицей в качестве `haystack` заслуживает несколько особого внимания:

- О значении направления `dimAlong`:

  Например, мы можем затем исследовать массив `haystack` по "толщине", то есть сквозь её следующие друг за другом слои `haystack(:,:,#,..)`. Чтобы так сделать, мы определим здесь `dimAlong = 3`.

  Как и для матриц, этот вид многомерного массива может быть просканирован вдоль его строк или столбцов. Подходящие значения `dimAlong` имеют некоторые исключения:

  - Поиск иглы как строки сканирует массив сквозь его столбцы. Следовательно, значение `dimAlong = "r"` должно быть эквивалентно значению `dimAlong = 2` вместо 1!
  - Аналогично поиск иглы как столбцы сканирует массив сквозь его строки: Обычное значение `dimAlong = "c"` должно быть эквивалентно значению `dimAlong = 1` вместо 2!

  Для того, чтобы не нарушать общую договорённость, о том что `"r"<=>1` и `"c"<=>2` используется везде в Scilab, `vectorfind()` придерживается и справляется с ним. Но нужно иметь в виду лежащий в основе переключатель, чтобы иметь чёткое понимание возвращаемых по умолчанию индексов, когда используются `"r",1` или `"c",2`.

- О возвращаемых индексах совпадающих строк, столбцов, "пикселей"... когда игла `needle` такой же длины, как размер стороны стога сена `haystack` и опция `indType` не используется:

  Индексы совпадающих диапазонов являются линейными индексами компонентов следующих подпространств:

  - С `dimAlong = "r" = 1`: в `haystack(:,1,:,:..)`
  - С `dimAlong = "c" = 2`: в `haystack(1,:,:,:..)`
  - С `dimAlong = 3`: в `haystack(:,:,1,:..)`
  - С `dimAlong = 4`: в `haystack(:,:,:,1,:..)`.
  - и др...
  Случай трёх- и четырёхмерных массивов рассмотрен в разделе примеров. Несмотря на то, что легко понять и использовать для простых матриц, несколько трудно работать с этими линейными индексами в подпространстве `haystack`, чтобы фактически обращаться к совпадающим диапазонам в ND-мерном массиве с N>2. Необязательный параметр `indType = "headN" | "headIJK` затем вернёт более удобные в работе индексы, обращающиеся ко всему массиву `haystack`.

## Примеры

В матрице чисел:

    m = [ 1  0   1   2  2  1
          2  2   0   1  0  2
          0  2  %nan 2  1  2
          2 %nan 1   0  1  2
        ];
    vectorfind(m,[2 0 1 1], "c")            // => 5
    vectorfind(m,[2 0 1 1], "c",,"headN")   // => 17
    vectorfind(m,[2 0 1 1], "c",,"headIJK") // [1 5]
    // С короткой иглой:
    vectorfind(m,[2 2])                     // => [2 13]
    vectorfind(m,[2 2], "r",,"headN")       // тот же выходной параметр
    vectorfind(m,[2 2], "r",,"headIJK")     // => [2 1 ; 1 4]
    vectorfind(m,[2 %nan])                  // => [4 7]
    // С символом универсальной подстановки в игле:
    // пример №1: все столбцы начинаются с 1 и заканчиваются 2:
    [n, ma] = vectorfind(m,[1 .3 .3 2], "c", .3) // => n = [1 6], ma = [1 2 0 2; 1 2 2 2]
    // пример №2: все строки, имеющие диапазон [2 * 2] (короткая игла с символом универсальной подстановки):
    [n, ma] = vectorfind(m,[2 .3  2], "r", .3)   // => n = [7 15], ma = [2 %nan 2; 2 1 2]
    vectorfind(m,[2 .3  2], "r", .3, "headIJK")  // => [3 2 ; 3 4]
                                                 // Примечание: значение %nan соответствует *

Логическая матрица:

    m = [0  0  0  1  1  0
         0  1  1  1  0  1
         1  1  0  1  1  1
         1  0  1  0  0  1]==1
    // m  =
    //  F F F T T F
    //  F T T T F T
    //  T T F T T T
    //  T F T F F T
    vectorfind(m, [%F %T %T %F], "c")   // => 2
    vectorfind(m, [%T %T], "c")         // => [3 6 13 14 22 23]
    vectorfind(m, [1 1], "c")           // => ошибка: ожидался тот же тип
    // джокер => игла является числовой:
    [n, ma] = vectorfind(m, [0 %nan 0 %nan 1], "r", %nan) // => n=[1 8], ma=[F F F T T ; F T F F T]

В маленьком 8-цветном RGB-изображении (трёхмерная гиперматрица целых чисел типа uint8):

    // Формирование массива яркости цвета:
    m = [1  1  1  1  1  0  1  0  0  0  1  0  1  0  0
         1  1  0  0  0  0  1  0  1  0  1  1  1  1  1
         1  1  0  1  0  1  1  0  0  1  1  0  0  1  0];
    m = uint8(matrix(m,3,5,3)*255)
    // m  =
    //(:,:,1)                   // Красный слой
    //  255  255  255  255  255
    //  255  255    0    0    0
    //  255  255    0  255    0
    //(:,:,2)                   // Зелёный слой
    //    0  255    0    0    0
    //    0  255    0  255    0
    //  255  255    0    0  255
    //(:,:,3)                   // Синий слой
    //  255    0  255    0    0
    //  255  255  255  255  255
    //  255    0    0  255    0
    // Определяет позицию красных пикселей:
    vectorfind(m, [255 0 0], 3)             // => [10 13]
    vectorfind(m, [255 0 0], 3,,"headIJK")  // => [1 4 1 ; 1 5 1]
    // Пиксели с включённым зелёным и синим цветом, каким бы ни был их красный канал:
    //   Мы можем использовать десятично-кодированную иглу (не uint8).
    //   Тогда, %nan можно использовать в качестве джокера, который не может быт в изображении с типом uint8:
    vectorfind(m, [%nan 255 255], 3, %nan,"headIJK") // => [3 1 1; 2 2 1; 2 4 1]
    // Столбцы из 255:
    vectorfind(m, [255 255 255], "c")      // => [1 2 7 11]

В четырёхмерной текстовой гиперматрице:

    m  = [
      "U"  "C"  "G"  "A"  "A"  "A"  "U"  "U"  "A"  "G"  "A"  "G"
      "A"  "A"  "A"  "A"  "C"  "C"  "U"  "U"  "C"  "G"  "G"  "G"
      "A"  "G"  "A"  "C"  "G"  "C"  "C"  "C"  "G"  "C"  "A"  "G"
      "C"  "U"  "G"  "G"  "G"  "A"  "A"  "G"  "C"  "C"  "C"  "C"
      "C"  "G"  "G"  "A"  "A"  "G"  "U"  "C"  "A"  "U"  "G"  "C"
      ];
    m = matrix(m, 3, 5, 2, 2);
    // (:,:,1,1)
    // !U  C  A  G  A  !
    // !A  C  G  G  G  !
    // !A  C  U  A  G  !
    //(:,:,2,1)
    // !A  G  C  A  C  !
    // !A  A  G  A  A  !
    // !C  A  G  C  G  !
    //(:,:,1,2)
    // !U  A  U  C  G  !
    // !U  U  C  A  C  !
    // !C  U  G  C  A  !
    //(:,:,2,2)
    // !G  C  G  G  G  !
    // !G  U  A  G  C  !
    // !C  A  C  G  C  !
    vectorfind(m, ["A" "A" "C"], "c")       // => [6 9]
    vectorfind(m, [""  "G" "G"], "c", "")   // => [5 8 19]
    // Джокер
    [n, ma] = vectorfind(m, ["" "G" "G"], "c", "", "headN") // => n=[13 22 55], ma=[A G G; C G G; G G G]
    vectorfind(m, ["" "C" "C"], "c", "", "headIJK") // => [1 2 1 1 ; 1 5 2 2]
    // Короткая игла
    vectorfind(m, ["C" "C"], "c",,"headIJK")        // => [1 2 1 1; 2 2 1 1; 2 5 2 2]
    // Короткая игла с джокером
    vectorfind(m, ["A" "" "A"],"r","","headIJK")    // => [1 3 1 1 ; 2 2 2 1]

## Смотрите также

- find
- members
- grep

## История

6.1

- `vectorfind(H,[])` теперь возвращает `[]` вместо ошибки.
- Когда игла слишком длинная, теперь вместо ошибки возвращается `[]`.
- Теперь может быть использована игла, короче, чем размер стога сена.
- Значение символа универсальной подстановки, совпавшее с любым значением стога сена теперь может быть определён и использован в качестве иглы. Затем могут быть возвращены фактически совпадающие диапазоны: добавлены необязательные параметры `joker` и `matching`.
- Любое значение `%nan`, встреченное в игле, теперь обрабатывается как любое иное регулярное значение: оно соответствует значению `%nan` в стоге сена. Оно ранее никогда не соответствовало.
- Гиперматрицы могут теперь обрабатываться в качестве стога сена.
- Исследуемое направление `dimAlong` теперь может быть числовым: 1, 2, ..
- Добавлен необязательный параметр `indType`.