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–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/Array-and-Sparse-Class-Differences.html