Spec-Zone.ru › Octave 9

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

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

: newval = 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.

Ключевое слово end нельзя использовать внутри subsref для индексированных присваиваний.

См. также: 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.

: newval = subsasgn (val, idx, rhs)

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

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

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

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.

Ключевое слово end нельзя использовать внутри subsasgn для индексированных присваиваний.

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

: val = optimize_subsasgn_calls ()
: old_val = optimize_subsasgn_calls (new_val)
: old_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–2026 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.4.0/Defining-Indexing-And-Indexed-Assignment.html

Spec-Zone.ru

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