Spec-Zone.ru › Octave 7

34.3.1 Определение индексирования и индексированного присваивания

Объекты могут быть индексированы с помощью скобок или фигурных скобок, как obj(idx) или как obj{idx}, или даже как obj(idx).field. Однако программисту необходимо определить, что это индексирование фактически означает. В случае класса многочленов p(n) может означать либо коэффициент n-ой степени многочлена, либо вычисление многочлена в точке n. Значение этого индексированного обращения определяется методом subsref.

: subsref (val, idx) ¶

Выполняет операцию выбора индексированного элемента val в соответствии с индексом, указанным в idx.

Индекс idx должен быть структурой с полями «type» и «subs». Допустимые значения для поля «type» — "()", "{}", и ".". Поле «subs» может быть либо ":" , либо ячейкой индексов.

Следующий пример показывает, как извлечь две первые колонки матрицы

val = magic (3)
    ⇒ val = [ 8   1   6
               3   5   7
               4   9   2 ]
idx.type = "()";
idx.subs = {":", 1:2};
subsref (val, idx)
     ⇒ [ 8   1
          3   5
          4   9 ]

Обратите внимание, что это то же самое, что и val(:, 1:2).

Если idx является пустой структурой с полями «type» и «subs», вернуть val.

См. также: subsasgn, substruct.

Например, этот класс использует соглашение, что индексирование с помощью "()" вычисляет многочлен, а индексирование с помощью "{}" возвращает n-ый коэффициент (от n-ой степени). Код метода subsref выглядит так

function r = subsref (p, s)

  if (isempty (s))
    error ("@polynomial/subsref: missing index");
  endif

  switch (s(1).type)

    case "()"
      idx = s(1).subs;
      if (numel (idx) != 1)
        error ("@polynomial/subsref: need exactly one index");
      endif
      r = polyval (fliplr (p.poly), idx{1});

    case "{}"
      idx = s(1).subs;
      if (numel (idx) != 1)
        error ("@polynomial/subsref: need exactly one index");
      endif

      if (isnumeric (idx{1}))
        r = p.poly(idx{1}+1);
      else
        r = p.poly(idx{1});
      endif

    case "."
      fld = s.subs;
      if (! strcmp (fld, "poly"))
        error ('@polynomial/subsref: invalid property "%s"', fld);
      endif
      r = p.poly;

    otherwise
      error ("@polynomial/subsref: invalid subscript type");

  endswitch

  if (numel (s) > 1)
    r = subsref (r, s(2:end));
  endif

endfunction

Эквивалентная функциональность для индексированного присваивания использует метод subsasgn.

: subsasgn (val, idx, rhs) ¶

Выполняет операцию индексированного присваивания в соответствии с индексом, указанным в idx.

Индекс idx должен быть структурой с полями «type» и «subs». Допустимые значения для поля «type» — "()", "{}", и ".". Поле «subs» может быть либо ":" , либо ячейкой индексов.

Следующий пример показывает, как установить две первые колонки 3x3 матрицы в ноль.

val = magic (3);
idx.type = "()";
idx.subs = {":", 1:2};
val = subsasgn (val, idx, 0)
     ⇒  [ 0   0   6
           0   0   7
           0   0   2 ]

Обратите внимание, что это то же самое, что и val(:, 1:2) = 0.

Если idx является пустой структурой с полями «type» и «subs», вернуть rhs.

См. также: subsref, substruct, optimize_subsasgn_calls.

: val = optimize_subsasgn_calls () ¶
: old_val = optimize_subsasgn_calls (new_val) ¶
: optimize_subsasgn_calls (new_val, "local") ¶

Запрос или установка внутреннего флага для оптимизации вызовов метода subsasgn.

Если true, Octave попытается устранить избыточную копирование при вызове метода subsasgn пользовательского класса.

При вызове изнутри функции с опцией "local", переменная изменяется локально для функции и любых вызываемых подпрограмм. Исходное значение переменной восстанавливается при выходе из функции.

См. также: subsasgn.

Обратите внимание, что методы subsref и subsasgn всегда получают всю цепочку индексов, в то время как обычно обрабатывают только первый элемент. Эти методы несут ответственность за обработку остальной части цепочки (если необходимо), обычно перенаправляя её обратно в subsref или subsasgn.

Если вы хотите использовать ключевое слово end в индексированных выражениях объекта, должен быть определён метод end. Например, метод end для класса многочленов может выглядеть так

function r = end (obj, index_pos, num_indices)

  if (num_indices != 1)
    error ("polynomial object may only have one index");
  endif

  r = length (obj.poly) - 1;

endfunction

что является достаточно универсальным методом end, который имеет поведение, аналогичное ключевому слову end для классов массивов Octave. Пример с использованием класса многочленов тогда

p = polynomial ([1,2,3,4]);
p{end-1}
  ⇒ 3

Объекты также могут использоваться в качестве индекса в индексированном выражении, и это контролируется функцией subsindex.

: idx = subsindex (obj) ¶

Преобразует объект в вектор индексов.

Если obj — это объект класса, определённый с конструктором класса, то subsindex — это перегруженный метод, который позволяет преобразовать этот объект класса в допустимый вектор индексов. Важно отметить, что subsindex должен возвращать вектор целых чисел с плавающей запятой с нулевым началом класса "double". Например, если конструктор класса был

function obj = myclass (a)
  obj = class (struct ("a", a), "myclass");
endfunction

тогда функция subsindex

function idx = subsindex (obj)
  idx = double (obj.a) - 1.0;
endfunction

может быть использована следующим образом

a = myclass (1:4);
b = 1:10;
b(a)
⇒ 1  2  3  4

См. также: class, subsref, subsasgn.

Наконец, объекты могут использоваться как диапазоны, предоставив метод colon.

: r = colon (base, limit) ¶
: r = colon (base, increment, limit) ¶

Возвращает результат выражения двоеточия, соответствующего base, limit и необязательно increment.

Эта функция эквивалентна синтаксису оператора base : limit или base : increment : limit.

См. также: linspace.

© 1996–2022 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/v7.2.0/Defining-Indexing-And-Indexed-Assignment.html

Spec-Zone.ru

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