| // This file is part of Eigen, a lightweight C++ template library |
| // for linear algebra. Eigen itself is part of the KDE project. |
| // |
| // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> |
| // |
| // Eigen is free software; you can redistribute it and/or |
| // modify it under the terms of the GNU Lesser General Public |
| // License as published by the Free Software Foundation; either |
| // version 3 of the License, or (at your option) any later version. |
| // |
| // Alternatively, 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. |
| // |
| // Eigen 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 Lesser General Public License or the |
| // GNU General Public License for more details. |
| // |
| // You should have received a copy of the GNU Lesser General Public |
| // License and a copy of the GNU General Public License along with |
| // Eigen. If not, see <http://www.gnu.org/licenses/>. |
| |
| #ifndef EIGEN_SPARSE_ARRAY_H |
| #define EIGEN_SPARSE_ARRAY_H |
| |
| /** Stores a sparse set of values as a list of values and a list of indices. |
| * |
| */ |
| template<typename Scalar> class SparseArray |
| { |
| public: |
| SparseArray() |
| : m_values(0), m_indices(0), m_size(0), m_allocatedSize(0) |
| {} |
| |
| SparseArray(int size) |
| : m_values(0), m_indices(0), m_size(0), m_allocatedSize(0) |
| { |
| resize(size); |
| } |
| |
| SparseArray(const SparseArray& other) |
| { |
| *this = other; |
| } |
| |
| SparseArray& operator=(const SparseArray& other) |
| { |
| resize(other.size()); |
| memcpy(m_values, other.m_values, m_size * sizeof(Scalar)); |
| memcpy(m_indices, other.m_indices, m_size * sizeof(int)); |
| } |
| |
| void swap(SparseArray& other) |
| { |
| std::swap(m_values, other.m_values); |
| std::swap(m_indices, other.m_indices); |
| std::swap(m_size, other.m_size); |
| std::swap(m_allocatedSize, other.m_allocatedSize); |
| } |
| |
| ~SparseArray() |
| { |
| delete[] m_values; |
| delete[] m_indices; |
| } |
| |
| void reserve(int size) |
| { |
| int newAllocatedSize = m_size + size; |
| if (newAllocatedSize > m_allocatedSize) |
| reallocate(newAllocatedSize); |
| } |
| |
| void squeeze() |
| { |
| if (m_allocatedSize>m_size) |
| reallocate(m_size); |
| } |
| |
| void resize(int size, int reserveSizeFactor = 0) |
| { |
| if (m_allocatedSize<size) |
| reallocate(size + reserveSizeFactor*size); |
| m_size = size; |
| } |
| |
| void append(const Scalar& v, int i) |
| { |
| int id = m_size; |
| resize(m_size+1, 1); |
| m_values[id] = v; |
| m_indices[id] = i; |
| } |
| |
| int size() const { return m_size; } |
| void clear() { m_size = 0; } |
| |
| Scalar& value(int i) { return m_values[i]; } |
| const Scalar& value(int i) const { return m_values[i]; } |
| |
| int& index(int i) { return m_indices[i]; } |
| const int& index(int i) const { return m_indices[i]; } |
| |
| protected: |
| |
| void reallocate(int size) |
| { |
| Scalar* newValues = new Scalar[size]; |
| int* newIndices = new int[size]; |
| int copySize = std::min(size, m_size); |
| // copy |
| memcpy(newValues, m_values, copySize * sizeof(Scalar)); |
| memcpy(newIndices, m_indices, copySize * sizeof(int)); |
| // delete old stuff |
| delete[] m_values; |
| delete[] m_indices; |
| m_values = newValues; |
| m_indices = newIndices; |
| m_allocatedSize = size; |
| } |
| |
| protected: |
| Scalar* m_values; |
| int* m_indices; |
| int m_size; |
| int m_allocatedSize; |
| |
| }; |
| |
| #endif // EIGEN_SPARSE_ARRAY_H |