📄 matrix_sparse.cxx
字号:
// Copyright (C) 2001-2004 Vivien Mallet//// This file is part of Seldon library.// Seldon library provides matrices and vectors structures for// linear algebra.// // Seldon is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.// // Seldon is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License (file "license") for more details.//// For more information, please see the Seldon home page:// http://spacetown.free.fr/lib/seldon/#ifndef SELDON_FILE_MATRIX_SPARSE_CXX#include "Matrix_Sparse.hxx"namespace Seldon{ /**************** * CONSTRUCTORS * ****************/ //! Default constructor. /*! Builds an empty 0x0 matrix. */ template <class T, class Prop, class Storage, class Allocator> inline Matrix_Sparse<T, Prop, Storage, Allocator>::Matrix_Sparse(): Matrix_Base<T, Allocator>() { nz_ = 0; ptr_ = NULL; ind_ = NULL; } //! Constructor. /*! Builds an empty i by j sparse matrix. \param i number of rows. \param j number of columns. */ template <class T, class Prop, class Storage, class Allocator> inline Matrix_Sparse<T, Prop, Storage, Allocator>::Matrix_Sparse(int i, int j): Matrix_Base<T, Allocator>(i, j) { nz_ = 0; ptr_ = NULL; ind_ = NULL; } //! Constructor. /*! Builds a sparse matrix of size i by j , with nz non-zero elements. \param i number of rows. \param j number of columns. \param nz number of non-zero elements. \note Matrix values are not initialized. Indices of non-zero entries are not initialized either. */ template <class T, class Prop, class Storage, class Allocator> inline Matrix_Sparse<T, Prop, Storage, Allocator>:: Matrix_Sparse(int i, int j, int nz): Matrix_Base<T, Allocator>(i, j) { this->nz_ = nz;#ifdef SELDON_CHECK_DIMENSIONS if (static_cast<long int>(nz_-1) / static_cast<long int>(j) >= static_cast<long int>(i)) { this->m_ = 0; this->n_ = 0; nz_ = 0; ptr_ = NULL; ind_ = NULL; this->data_ = NULL; throw WrongDim("Matrix_Sparse::Matrix_Sparse(int, int, int)", string("There are more values (") + to_str(nz) + " values) than elements in the matrix (" + to_str(i) + " by " + to_str(j) + ")."); }#endif#ifdef SELDON_CHECK_MEMORY try {#endif ptr_ = reinterpret_cast<int*>( calloc(Storage::GetFirst(i, j)+1, sizeof(int)) );#ifdef SELDON_CHECK_MEMORY } catch (...) { this->m_ = 0; this->n_ = 0; nz_ = 0; ptr_ = NULL; ind_ = NULL; this->data_ = NULL; } if (ptr_ == NULL) { this->m_ = 0; this->n_ = 0; nz_ = 0; ind_ = NULL; this->data_ = NULL; } if (ptr_ == NULL && i != 0 && j != 0) throw NoMemory("Matrix_Sparse::Matrix_Sparse(int, int, int)", string("Unable to allocate ") + to_str(sizeof(int) * (Storage::GetFirst(i, j)+1) ) + " bytes to store " + to_str(Storage::GetFirst(i, j)+1) + " row or column start indices, for a " + to_str(i) + " by " + to_str(j) + " matrix.");#endif#ifdef SELDON_CHECK_MEMORY try {#endif ind_ = reinterpret_cast<int*>( calloc(nz_, sizeof(int)) ); #ifdef SELDON_CHECK_MEMORY } catch (...) { this->m_ = 0; this->n_ = 0; nz_ = 0; free(ptr_); ptr_ = NULL; ind_ = NULL; this->data_ = NULL; } if (ind_ == NULL) { this->m_ = 0; this->n_ = 0; nz_ = 0; free(ptr_); ptr_ = NULL; this->data_ = NULL; } if (ind_ == NULL && i != 0 && j != 0) throw NoMemory("Matrix_Sparse::Matrix_Sparse(int, int, int)", string("Unable to allocate ") + to_str(sizeof(int) * nz) + " bytes to store " + to_str(nz) + " row or column indices, for a " + to_str(i) + " by " + to_str(j) + " matrix.");#endif#ifdef SELDON_CHECK_MEMORY try {#endif this->data_ = this->allocator_.allocate(nz_, this);#ifdef SELDON_CHECK_MEMORY } catch (...) { this->m_ = 0; this->n_ = 0; free(ptr_); ptr_ = NULL; free(ind_); ind_ = NULL; this->data_ = NULL; } if (this->data_ == NULL) { this->m_ = 0; this->n_ = 0; free(ptr_); ptr_ = NULL; free(ind_); ind_ = NULL; } if (this->data_ == NULL && i != 0 && j != 0) throw NoMemory("Matrix_Sparse::Matrix_Sparse(int, int, int)", string("Unable to allocate ") + to_str(sizeof(int) * nz) + " bytes to store " + to_str(nz) + " values, for a " + to_str(i) + " by " + to_str(j) + " matrix.");#endif } //! Constructor. /*! Builds a i by j sparse matrix with non-zero values and indices provided by 'values' (values), 'ptr' (pointers) and 'ind' (indices). Input vectors are released and are empty on exit. \param i number of rows. \param j number of columns. \param values values of non-zero entries. \param ptr row or column start indices. \param ind row or column indices. \warning Input vectors 'values', 'ptr' and 'ind' are empty on exit. */ template <class T, class Prop, class Storage, class Allocator> template <class Storage0, class Allocator0, class Storage1, class Allocator1, class Storage2, class Allocator2> inline Matrix_Sparse<T, Prop, Storage, Allocator>:: Matrix_Sparse(int i, int j, Vector<T, Storage0, Allocator0>& values, Vector<int, Storage1, Allocator1>& ptr, Vector<int, Storage2, Allocator2>& ind): Matrix_Base<T, Allocator>(i, j) { nz_ = values.GetLength(); #ifdef SELDON_CHECK_DIMENSIONS // Checks whether vector sizes are acceptable. if (ind.GetLength() != nz_) { this->m_ = 0; this->n_ = 0; nz_ = 0; ptr_ = NULL; ind_ = NULL; this->data_ = NULL; throw WrongDim(string("Matrix_Sparse::Matrix_Sparse(int, int, ") + "const Vector&, const Vector&, const Vector&)", string("There are ") + to_str(nz_) + " values but " + to_str(ind.GetLength()) + " row or column indices."); } if (ptr.GetLength()-1 != Storage::GetFirst(i, j)) { this->m_ = 0; this->n_ = 0; nz_ = 0; ptr_ = NULL; ind_ = NULL; this->data_ = NULL; throw WrongDim(string("Matrix_Sparse::Matrix_Sparse(int, int, ") + "const Vector&, const Vector&, const Vector&)", string("The vector of start indices contains ") + to_str(ptr.GetLength()-1) + string(" row or column") + string(" start indices (plus the number") + " of non-zero entries) but there are " + to_str(Storage::GetFirst(i, j)) + " rows or columns (" + to_str(i) + " by " + to_str(j) + " matrix)."); } if (static_cast<long int>(nz_-1) / static_cast<long int>(j) >= static_cast<long int>(i)) { this->m_ = 0; this->n_ = 0; nz_ = 0; ptr_ = NULL; ind_ = NULL; this->data_ = NULL; throw WrongDim(string("Matrix_Sparse::Matrix_Sparse(int, int, ") + "const Vector&, const Vector&, const Vector&)", string("There are more values (") + to_str(values.GetLength()) + " values) than elements in the matrix (" + to_str(i) + " by " + to_str(j) + ")."); }#endif this->ptr_ = ptr.GetData(); this->ind_ = ind.GetData(); this->data_ = values.GetData(); ptr.Nullify(); ind.Nullify(); values.Nullify(); } /************** * DESTRUCTOR * **************/ //! Destructor. template <class T, class Prop, class Storage, class Allocator> inline Matrix_Sparse<T, Prop, Storage, Allocator>::~Matrix_Sparse() { this->m_ = 0; this->n_ = 0;#ifdef SELDON_CHECK_MEMORY try {#endif if (ptr_ != NULL) { free(ptr_); ptr_ = NULL; } #ifdef SELDON_CHECK_MEMORY } catch (...) { ptr_ = NULL; }#endif#ifdef SELDON_CHECK_MEMORY try {#endif if (ind_ != NULL) { free(ind_); ind_ = NULL; } #ifdef SELDON_CHECK_MEMORY } catch (...) { ind_ = NULL; }#endif#ifdef SELDON_CHECK_MEMORY try {#endif if (this->data_ != NULL) { this->allocator_.deallocate(this->data_, nz_); this->data_ = NULL; } #ifdef SELDON_CHECK_MEMORY } catch (...) { this->nz_ = 0; this->data_ = NULL; }#endif this->nz_ = 0; } //! Clears the matrix. /*! This methods is equivalent to the destructor. On exit, the matrix is empty (0x0). */ template <class T, class Prop, class Storage, class Allocator> inline void Matrix_Sparse<T, Prop, Storage, Allocator>::Clear() { this->~Matrix_Sparse(); } /********************* * MEMORY MANAGEMENT * *********************/ //! Redefines the matrix. /*! It clears the matrix and sets it to a new matrix defined by 'values' (values), 'ptr' (pointers) and 'ind' (indices). Input vectors are released and are empty on exit. \param i number of rows. \param j number of columns. \param values values of non-zero entries. \param ptr row or column start indices. \param ind row or column indices.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -