Spec-Zone.ru › Octave 9

Далее: Накопление, Предыдущее: Распространение, Вверх: Векторизация и ускорение выполнения кода [Оглавление][Индекс]

19.3 Применение функции ¶

Как общее правило, функции должны быть написаны с учетом матричных аргументов и должны рассматривать операции над всей матрицей векторным способом. Иногда написание функций таким образом кажется сложным или невозможным по разным причинам. В таких ситуациях Octave предоставляет средства для применения функции к каждому элементу массива, ячейки или структуры.

: B = arrayfun (fcn, A) ¶
: B = arrayfun (fcn, A1, A2, …) ¶
: [B1, B2, …] = arrayfun (fcn, A, …) ¶
: B = arrayfun (…, "UniformOutput", val) ¶
: B = arrayfun (…, "ErrorHandler", errfcn) ¶

Выполняет функцию над каждым элементом массива.

Это полезно для функций, которые не принимают аргументы массива. Если функция принимает аргументы массива, лучше вызвать её напрямую.

Первый входной аргумент fcn может быть строкой, функцией-обработчиком, встроенной функцией или анонимной функцией. Входной аргумент A может быть логическим массивом, числовым массивом, строковым массивом, массивом структур или массивом ячеек. arrayfun передает все элементы A по отдельности функции fcn и собирает результаты. Эквивалентный псевдокод:

cls = class (fcn (A(1));
B = zeros (size (A), cls);
for i = 1:numel (A)
  B(i) = fcn (A(i))
endfor

Названная функция также может принимать более двух входных аргументов, которые передаются как третий входной аргумент A2, четвертый входной аргумент A2 и т. д. Если задано более одного аргумента массива, все входные аргументы должны иметь одинаковые размеры. Например:

arrayfun (@atan2, [1, 0], [0, 1])
     ⇒ [ 1.57080   0.00000 ]

Если параметр val после дополнительного строкового входного аргумента "UniformOutput" установлен true (по умолчанию), то названная функция fcn должна возвращать один элемент, который затем будет добавлен в возвращаемое значение и будет иметь тип матрицы. В противном случае, если этот параметр установлен на false, то выходные данные конкатенируются в массив ячеек. Например:

arrayfun (@(x,y) x:y, "abc", "def", "UniformOutput", false)
⇒
   {
     [1,1] = abcd
     [1,2] = bcde
     [1,3] = cdef
   }

Если задано более одного выходных аргументов, то названная функция должна вернуть количество возвращаемых значений, которые также ожидаются, например:

[A, B, C] = arrayfun (@find, [10; 0], "UniformOutput", false)
⇒
A =
{
   [1,1] =  1
   [2,1] = [](0x0)
}
B =
{
   [1,1] =  1
   [2,1] = [](0x0)
}
C =
{
   [1,1] =  10
   [2,1] = [](0x0)
}

Если параметр errfcn после дополнительного строкового входного аргумента "ErrorHandler" является другой строкой, функцией-обработчиком, встроенной функцией или анонимной функцией, то errfcn определяет функцию для вызова в случае возникновения ошибки в fcn. Определение функции должно быть такого вида:

function [...] = errfcn (s, ...)

где есть дополнительный входной аргумент для errfcn по сравнению с fcn, заданный s. Это структура с элементами "identifier", "message", и "index", которые соответственно представляют идентификатор ошибки, сообщение об ошибке и индекс элементов массива, вызвавших ошибку. Размер выходного аргумента errfcn должен иметь тот же размер, что и выходной аргумент fcn; в противном случае генерируется реальная ошибка. Например:

function y = ferr (s, x), y = "MyString"; endfunction
arrayfun (@str2num, [1234],
          "UniformOutput", false, "ErrorHandler", @ferr)
⇒
   {
     [1,1] = MyString
   }

См. также: spfun, cellfun, structfun.

: y = spfun (f, S) ¶

Вычисляет f (S) для ненулевых элементов S.

Входящая функция f применяется только к ненулевым элементам входной матрицы S, которая обычно разреженная. Функция f может быть передана как строка, функция-обработчик или встроенная функция.

Выход y — разреженная матрица с той же структурой разреженности, что и вход S. spfun сохраняет структуру разреженности, что отличается от простого применения функции f к разреженной матрице S, когда f (0) != 0.

Пример

Сохранение разреженности spfun по сравнению с обычным применением функции

S = pi * speye (2,2)
S =

Compressed Column Sparse (rows = 2, cols = 2, nnz = 2 [50%])

  (1, 1) -> 3.1416
  (2, 2) -> 3.1416

y = spfun (@cos, S)
y =

Compressed Column Sparse (rows = 2, cols = 2, nnz = 2 [50%])

  (1, 1) -> -1
  (2, 2) -> -1


y = cos (S)
y =

Compressed Column Sparse (rows = 2, cols = 2, nnz = 4 [100%])

  (1, 1) -> -1
  (2, 1) -> 1
  (1, 2) -> 1
  (2, 2) -> -1

См. также: arrayfun, cellfun, structfun.

: A = cellfun ("fcn", C) ¶
: A = cellfun ("size", C, k) ¶
: A = cellfun ("isclass", C, class) ¶
: A = cellfun (@fcn, C) ¶
: A = cellfun (fcn, C) ¶
: A = cellfun (fcn, C1, C2, …) ¶
: [A1, A2, …] = cellfun (…) ¶
: A = cellfun (…, "ErrorHandler", errfcn) ¶
: A = cellfun (…, "UniformOutput", val) ¶

Вычисляет функцию с именем "fcn" для элементов массива ячеек C.

Элементы массива ячеек C передаются в заданную функцию индивидуально. Функция fcn может быть одной из функций

isempty

Возвращает 1 для пустых элементов.

islogical

Возвращает 1 для логических элементов.

isnumeric

Возвращает 1 для числовых элементов.

isreal

Возвращает 1 для вещественных элементов.

length

Возвращает вектор длин элементов ячеек.

ndims

Возвращает количество измерений каждого элемента.

numel
prodofsize

Возвращает количество элементов, содержащихся в каждом элементе ячейки. Число является произведением измерений объекта в каждом элементе ячейки.

size

Возвращает размер по k-му измерению.

isclass

Возвращает 1 для элементов класса class.

Кроме того, cellfun принимает произвольную функцию fcn в виде встроенной функции, дескриптора функции или имени функции (в виде символьной строки). Функция может принимать один или несколько аргументов, с входными аргументами, заданными C1, C2 и т. д. Например:

cellfun ("atan2", {1, 0}, {0, 1})
     ⇒ [ 1.57080   0.00000 ]

Количество выходных аргументов cellfun соответствует количеству выходных аргументов функции и может быть больше единицы. Когда существует несколько выходных значений функции, они собираются в выходные аргументы cellfun следующим образом:

function [a, b] = twoouts (x)
  a = x;
  b = x*x;
endfunction
[aa, bb] = cellfun (@twoouts, {1, 2, 3})
     ⇒
        aa =
           1 2 3
        bb =
           1 4 9

Обратите внимание, что по умолчанию выходной(ые) аргумент(ы) являются массивами того же размера, что и входные аргументы. Входные аргументы, которые являются одиночными (1x1) ячейками, будут автоматически расширены до размера других аргументов.

Если параметр "UniformOutput" установлен в true (по умолчанию), то функция должна возвращать скаляры, которые будут конкатенированы в возвращаемый массив(ы). Если "UniformOutput" ложно, выходные данные конкатенируются в массив ячеек (или массивы ячеек). Например:

cellfun ("lower", {"Foo", "Bar", "FooBar"},
         "UniformOutput", false)
⇒ {"foo", "bar", "foobar"}

Учитывая параметр "ErrorHandler", errfcn определяет функцию, которую следует вызвать в случае возникновения ошибки в fcn. Формат функции

function [...] = errfcn (s, ...)

где существует дополнительный входной аргумент для errfcn относительно fcn, заданный s. Это структура с элементами "identifier", "message", и "index", соответственно идентификатор ошибки, сообщение об ошибке и индекс во входные аргументы элемента, вызвавшего ошибку. Например:

function y = foo (s, x), y = NaN; endfunction
cellfun ("factorial", {-1,2}, "ErrorHandler", @foo)
⇒ [NaN 2]

Используйте cellfun разумно. Функция cellfun - это полезный инструмент для избегания циклов. Она часто используется с анонимными дескрипторами функций; однако, вызов анонимной функции связан с накладными расходами, сопоставимыми с накладными расходами функции m-файла. Передача дескриптора встроенной функции быстрее, поскольку интерпретатор не участвует во внутреннем цикле. Например:

C = {...}
v = cellfun (@(x) det (x), C); # compute determinants
v = cellfun (@det, C);         # 40% faster

См. также: arrayfun, structfun, spfun.

: A = structfun (fcn, S) ¶
: A = structfun (…, "ErrorHandler", errfcn) ¶
: A = structfun (…, "UniformOutput", val) ¶
: [A, B, …] = structfun (…) ¶

Вычисляет функцию с именем name для полей структуры S. Поля структуры S передаются функции fcn индивидуально.

structfun принимает произвольную функцию fcn в виде встроенной функции, дескриптора функции или имени функции (в виде символьной строки). В случае символьной строки аргумент функция должна принимать один аргумент с именем x и должна возвращать строковое значение. Если функция возвращает более одного аргумента, они возвращаются как отдельные выходные переменные.

Если параметр "UniformOutput" установлен в true (по умолчанию), то функция должна возвращать один элемент, который будет конкатенирован в возвращаемое значение. Если "UniformOutput" ложно, выходные данные помещаются в структуру с теми же именами полей, что и входная структура.

s.name1 = "John Smith";
s.name2 = "Jill Jones";
structfun (@(x) regexp (x, '(\w+)$', "matches"){1}, s,
           "UniformOutput", false)
  ⇒ scalar structure containing the fields:
       name1 = Smith
       name2 = Jones

Учитывая параметр "ErrorHandler", errfcn определяет функцию, которую следует вызвать в случае возникновения ошибки в fcn. Формат функции

function [...] = errfcn (se, ...)

где существует дополнительный входной аргумент для errfcn относительно fcn, заданный se. Это структура с элементами "identifier", "message" и "index", соответственно идентификатор ошибки, сообщение об ошибке и индекс во входные аргументы элемента, вызвавшего ошибку. Пример использования обработчика ошибок см. в cellfun.

См. также: cellfun, arrayfun, spfun.

В соответствии с предыдущими рекомендациями, старайтесь использовать встроенные функции Octave, когда это возможно, для достижения наилучшей производительности. Это особенно относится к четырём функциям выше. Например, при сложении двух массивов поэлементно можно использовать дескриптор встроенной функции сложения @plus или определить анонимную функцию @(x,y) x + y. Но анонимная функция на 60% медленнее первого метода. См. Перегрузка операторов для списка основных функций, которые могут быть использованы вместо анонимных.

Далее: Накопление, Предыдущее: Распространение, Вверх: Векторизация и ускорение кода [Содержание][Индекс]

© 1996–2023 The Octave Project Developers
Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.
Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions.
https://docs.octave.org/v9.2.0/Function-Application.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API