A.1.6.1 Отличия классов массивов и разреженных матриц ¶
Количество элементов в разреженной матрице считается как количество ненулевых элементов, а не как произведение размерностей. Поэтому,
SparseMatrix sm; ... int nnz = sm.nelem ();
возвращает количество ненулевых элементов (как функция интерпретатора nnz). Если пользователю действительно требуется количество элементов в матрице, включая ненулевые, он должен использовать numel, а не nelem. Обратите внимание, что для очень больших матриц, где произведение двух размерностей больше, чем представление беззнакового целого числа, numel может переполниться. Примером является speye (1e6), которая создаст матрицу с миллионом строк и столбцов, но только с миллионом ненулевых элементов. В этом случае число строк, умноженное на число столбцов, превышает в двести раз максимальное значение, которое может быть представлено 32-битным беззнаковым целым числом. Поэтому следует избегать использования numel, если нет уверенности, что переполнения не произойдёт.
Также необходимо проявлять особую осторожность при использовании метода elem или оператора (), которые выполняют в сущности одну и ту же функцию. Причина в том, что если объект разреженной матрицы не является константным, Octave предположит, что запрос на нулевой элемент в разреженной матрице фактически является запросом на создание этого элемента, чтобы он мог быть заполнен. Следовательно, фрагмент кода типа
SparseMatrix sm;
...
for (int j = 0; j < nc; j++)
for (int i = 0; i < nr; i++)
std::cerr << " (" << i << "," << j << "): " << sm(i,j) << "\n"; является отличным способом преобразования разреженной матрицы в плотную, и весьма медленным способом, так как он перераспределяет объект разреженной матрицы для каждого нулевого элемента в матрице.
Простым способом предотвращения вышеописанного является создание временной константной версии разреженной матрицы. Обратите внимание, что будет скопирована только контейнер разреженной матрицы, а фактическое представление данных будет совместно использоваться между двумя версиями разреженной матрицы; это не является дорогостоящей операцией. Пример выше, переписанный для предотвращения преобразования разреженной матрицы в плотную, выглядит так:
SparseMatrix sm;
...
const SparseMatrix tmp (sm);
for (int j = 0; j < nc; j++)
for (int i = 0; i < nr; i++)
std::cerr << " (" << i << "," << j << "): " << tmp(i,j) << "\n"; Наконец, поскольку типы разреженных матриц не представлены непрерывным блоком памяти, метод fortran_vec объекта Array<T> недоступен. Однако он заменён тремя отдельными методами ridx, cidx и data, которые обращаются к формату хранения разреженных матриц Octave в формате сжатых столбцов. Эти методы могут использоваться аналогично elem, чтобы разрешить доступ к матрице или заполнение её. Однако пользователь должен следовать формату сжатых столбцов разреженной матрицы, в противном случае матрица может быть повреждена.
© 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/Array-and-Sparse-Class-Differences.html