Spec-Zone.ru › Octave 9

4.2 Диапазоны

Диапазон — это удобный способ записать вектор-строку с равномерно расположенными элементами. Выражение диапазона задается значением первого элемента диапазона, необязательным значением шага между элементами и максимальным значением, которое элементы диапазона не превысят. Начальное значение, шаг и предел разделяются двоеточиями (символом «:») и могут содержать любые арифметические выражения и вызовы функций. Если шаг не указан, предполагается, что он равен 1. Например, диапазон

1 : 5

задает множество значений [ 1, 2, 3, 4, 5 ], а диапазон

1 : 3 : 5

задает множество значений [ 1, 4 ].

Хотя константа диапазона задает вектор-строку, Octave обычно не преобразует константы диапазона в векторы, если в этом нет необходимости. Это позволяет записать константу, например 1 : 10000, не расходуя 80 000 байт памяти на обычной рабочей станции.

Частый пример ситуации, когда диапазон необходимо преобразовать в вектор, — это его использование внутри вектора (то есть внутри квадратных скобок). Например, выражение

x = 0 : 0.1 : 1;

задает для x тип range и занимает 24 байта памяти, тогда как выражение

y = [ 0 : 0.1 : 1];

задает для y тип matrix и занимает 88 байт памяти.

Эту оптимизацию, экономящую память, можно отключить с помощью функции optimize_range.

: val = optimize_range ()
: old_val = optimize_range (new_val)
: old_val = optimize_range (new_val, "local")

Запрос или изменение настройки, определяющей, используется ли для хранения диапазонов специальный формат, экономящий память.

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

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

См. также: optimize_diagonal_matrix, optimize_permutation_matrix.

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

## x is some predefined range or vector or matrix or array
x(1:2:end) += 1;   # increment all  odd-numbered elements
x(2:2:end) -= 1;   # decrement all even-numbered elements

Приведенный выше код работает правильно независимо от того, содержит ли x нечетное число элементов, поэтому обрабатывать эти два случая по-разному не требуется.

Для вычисления значений диапазона Octave использует арифметику с плавающей точкой. Поэтому при определении диапазонов с вещественными значениями могут возникать такие проблемы:

a = -2
b = (0.3 - 0.2 - 0.1)
x = a : b

Из-за округления чисел с плавающей точкой b может быть равен нулю не точно; если это так, он может оказаться как больше, так и меньше нуля. Поэтому конечное значение диапазона x может включать ноль или не включать его. Аналогично:

x = 1.80 : 0.05 : 1.90
y = 1.85 : 0.05 : 1.90

работает не так предсказуемо, как может показаться. В Octave 8.3 результат таков: x содержит три элемента (1.80, 1.85 и 1.90), а y содержит только один элемент (1.85, но не 1.90). Таким образом, при использовании чисел с плавающей точкой в диапазонах изменение начального значения может легко повлиять на конец диапазона, хотя конечное значение в приведенном выше примере не менялось.

Чтобы избежать таких проблем с числами с плавающей точкой в диапазонах, используйте один из следующих шаблонов. Это изменение предыдущего кода:

x = (0:2) * 0.05 + 1.80
y = (0:1) * 0.05 + 1.85

делает его гораздо надежнее и обеспечивает более стабильные результаты на разных платформах, с разными компиляторами и настройками компилятора. Если известно число элементов, можно также использовать функцию linspace (см. раздел Специальные матрицы общего назначения), которая включает конечные точки диапазона. Также можно осмысленно использовать round, floor, ceil, fix и т. д., чтобы задавать пределы и шаг без влияния округления чисел с плавающей точкой. Например, предыдущий пример можно сделать надежнее и получить более стабильные результаты одним из следующих способов:

a = -2
b = round ((0.3 - 0.2 - 0.1) * 1e12) / 1e12   # rounds to 12 digits
c = floor (0.3 - 0.2 - 0.1)                   # floors as integer
d = floor ((0.3 - 0.2 - 0.1) * 1e12) / 1e12   # floors at 12 digits
x = a : b
y = a : c
z = a : d

При сложении скаляра с диапазоном, вычитании скаляра из диапазона (или вычитании диапазона из скаляра) и умножении на скаляр Octave попытается не преобразовывать диапазон в вектор и сохранить результат в виде диапазона, если сможет определить, что это безопасно. Например, выражение

a = 2*(1:1e7) - 1;

даст тот же результат, что и 1:2:2e7-1, но при этом вектор из десяти миллионов элементов ни разу не будет создан.

Использовать ноль в качестве шага в записи с двоеточиями, как в 1:0:1, нельзя, поскольку при определении числа элементов диапазона произошло бы деление на ноль. Однако диапазоны с нулевым шагом (то есть все элементы которых равны) полезны, особенно при индексировании, и Octave позволяет создавать их с помощью встроенной функции ones. Поскольку диапазон должен быть вектором-строкой, ones (1, 10) создает диапазон, а ones (10, 1) — нет.

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

© 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/Ranges.html

Spec-Zone.ru

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