Merge of itasc branch. Project files, scons and cmake should be working. Makefile...
[blender.git] / extern / Eigen2 / Eigen / src / Sparse / MappedSparseMatrix.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra. Eigen itself is part of the KDE project.
3 //
4 // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
5 //
6 // Eigen is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // Alternatively, you can redistribute it and/or
12 // modify it under the terms of the GNU General Public License as
13 // published by the Free Software Foundation; either version 2 of
14 // the License, or (at your option) any later version.
15 //
16 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License and a copy of the GNU General Public License along with
23 // Eigen. If not, see <http://www.gnu.org/licenses/>.
24
25 #ifndef EIGEN_MAPPED_SPARSEMATRIX_H
26 #define EIGEN_MAPPED_SPARSEMATRIX_H
27
28 /** \class MappedSparseMatrix
29   *
30   * \brief Sparse matrix
31   *
32   * \param _Scalar the scalar type, i.e. the type of the coefficients
33   *
34   * See http://www.netlib.org/linalg/html_templates/node91.html for details on the storage scheme.
35   *
36   */
37 template<typename _Scalar, int _Flags>
38 struct ei_traits<MappedSparseMatrix<_Scalar, _Flags> > : ei_traits<SparseMatrix<_Scalar, _Flags> >
39 {};
40
41 template<typename _Scalar, int _Flags>
42 class MappedSparseMatrix
43   : public SparseMatrixBase<MappedSparseMatrix<_Scalar, _Flags> >
44 {
45   public:
46     EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(MappedSparseMatrix)
47
48   protected:
49     enum { IsRowMajor = Base::IsRowMajor };
50
51     int m_outerSize;
52     int m_innerSize;
53     int m_nnz;
54     int* m_outerIndex;
55     int* m_innerIndices;
56     Scalar* m_values;
57
58   public:
59
60     inline int rows() const { return IsRowMajor ? m_outerSize : m_innerSize; }
61     inline int cols() const { return IsRowMajor ? m_innerSize : m_outerSize; }
62     inline int innerSize() const { return m_innerSize; }
63     inline int outerSize() const { return m_outerSize; }
64     inline int innerNonZeros(int j) const { return m_outerIndex[j+1]-m_outerIndex[j]; }
65
66     //----------------------------------------
67     // direct access interface
68     inline const Scalar* _valuePtr() const { return m_values; }
69     inline Scalar* _valuePtr() { return m_values; }
70
71     inline const int* _innerIndexPtr() const { return m_innerIndices; }
72     inline int* _innerIndexPtr() { return m_innerIndices; }
73
74     inline const int* _outerIndexPtr() const { return m_outerIndex; }
75     inline int* _outerIndexPtr() { return m_outerIndex; }
76     //----------------------------------------
77
78     inline Scalar coeff(int row, int col) const
79     {
80       const int outer = RowMajor ? row : col;
81       const int inner = RowMajor ? col : row;
82
83       int start = m_outerIndex[outer];
84       int end = m_outerIndex[outer+1];
85       if (start==end)
86         return Scalar(0);
87       else if (end>0 && inner==m_innerIndices[end-1])
88         return m_values[end-1];
89       // ^^  optimization: let's first check if it is the last coefficient
90       // (very common in high level algorithms)
91
92       const int* r = std::lower_bound(&m_innerIndices[start],&m_innerIndices[end-1],inner);
93       const int id = r-&m_innerIndices[0];
94       return ((*r==inner) && (id<end)) ? m_values[id] : Scalar(0);
95     }
96
97     inline Scalar& coeffRef(int row, int col)
98     {
99       const int outer = RowMajor ? row : col;
100       const int inner = RowMajor ? col : row;
101
102       int start = m_outerIndex[outer];
103       int end = m_outerIndex[outer+1];
104       ei_assert(end>=start && "you probably called coeffRef on a non finalized matrix");
105       ei_assert(end>start && "coeffRef cannot be called on a zero coefficient");
106       int* r = std::lower_bound(&m_innerIndices[start],&m_innerIndices[end],inner);
107       const int id = r-&m_innerIndices[0];
108       ei_assert((*r==inner) && (id<end) && "coeffRef cannot be called on a zero coefficient");
109       return m_values[id];
110     }
111
112     class InnerIterator;
113
114     /** \returns the number of non zero coefficients */
115     inline int nonZeros() const  { return m_nnz; }
116
117     inline MappedSparseMatrix(int rows, int cols, int nnz, int* outerIndexPtr, int* innerIndexPtr, Scalar* valuePtr)
118       : m_outerSize(IsRowMajor?rows:cols), m_innerSize(IsRowMajor?cols:rows), m_nnz(nnz), m_outerIndex(outerIndexPtr),
119         m_innerIndices(innerIndexPtr), m_values(valuePtr)
120     {}
121
122     #ifdef EIGEN_TAUCS_SUPPORT
123     explicit MappedSparseMatrix(taucs_ccs_matrix& taucsMatrix);
124     #endif
125
126     #ifdef EIGEN_CHOLMOD_SUPPORT
127     explicit MappedSparseMatrix(cholmod_sparse& cholmodMatrix);
128     #endif
129
130     #ifdef EIGEN_SUPERLU_SUPPORT
131     explicit MappedSparseMatrix(SluMatrix& sluMatrix);
132     #endif
133
134     /** Empty destructor */
135     inline ~MappedSparseMatrix() {}
136 };
137
138 template<typename Scalar, int _Flags>
139 class MappedSparseMatrix<Scalar,_Flags>::InnerIterator
140 {
141   public:
142     InnerIterator(const MappedSparseMatrix& mat, int outer)
143       : m_matrix(mat),
144         m_outer(outer),
145         m_id(mat._outerIndexPtr()[outer]),
146         m_start(m_id),
147         m_end(mat._outerIndexPtr()[outer+1])
148     {}
149
150     template<unsigned int Added, unsigned int Removed>
151     InnerIterator(const Flagged<MappedSparseMatrix,Added,Removed>& mat, int outer)
152       : m_matrix(mat._expression()), m_id(m_matrix._outerIndexPtr()[outer]),
153         m_start(m_id), m_end(m_matrix._outerIndexPtr()[outer+1])
154     {}
155
156     inline InnerIterator& operator++() { m_id++; return *this; }
157
158     inline Scalar value() const { return m_matrix._valuePtr()[m_id]; }
159     inline Scalar& valueRef() { return const_cast<Scalar&>(m_matrix._valuePtr()[m_id]); }
160
161     inline int index() const { return m_matrix._innerIndexPtr()[m_id]; }
162     inline int row() const { return IsRowMajor ? m_outer : index(); }
163     inline int col() const { return IsRowMajor ? index() : m_outer; }
164
165     inline operator bool() const { return (m_id < m_end) && (m_id>=m_start); }
166
167   protected:
168     const MappedSparseMatrix& m_matrix;
169     const int m_outer;
170     int m_id;
171     const int m_start;
172     const int m_end;
173 };
174
175 #endif // EIGEN_MAPPED_SPARSEMATRIX_H