// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2008-2009 Guillaume Saupin <guillaume.saupin@cea.fr> // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
/** \ingroup Skyline_Module * * \class SkylineMatrix * * \brief The main skyline matrix class * * This class implements a skyline matrix using the very uncommon storage * scheme. * * \param _Scalar the scalar type, i.e. the type of the coefficients * \param _Options Union of bit flags controlling the storage scheme. Currently the only possibility * is RowMajor. The default is 0 which means column-major. * *
*/ namespace internal { template<typename _Scalar, int _Options> struct traits<SkylineMatrix<_Scalar, _Options> > { typedef _Scalar Scalar; typedef Sparse StorageKind;
if (outer == inner) return this->m_data.diag(outer);
if (IsRowMajor) { if (col > row) //upper matrix
{ const Index minOuterIndex = inner - m_data.upperProfile(inner);
eigen_assert(outer >= minOuterIndex && "You tried to access a coeff that does not exist in the storage"); return this->m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));
} if (col < row) //lower matrix
{ const Index minInnerIndex = outer - m_data.lowerProfile(outer);
eigen_assert(inner >= minInnerIndex && "You tried to access a coeff that does not exist in the storage"); return this->m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));
}
} else { if (outer > inner) //upper matrix
{ const Index maxOuterIndex = inner + m_data.upperProfile(inner);
eigen_assert(outer <= maxOuterIndex && "You tried to access a coeff that does not exist in the storage"); return this->m_data.upper(m_colStartIndex[inner] + (outer - inner));
} if (outer < inner) //lower matrix
{ const Index maxInnerIndex = outer + m_data.lowerProfile(outer);
eigen_assert(inner <= maxInnerIndex && "You tried to access a coeff that does not exist in the storage"); return this->m_data.lower(m_rowStartIndex[outer] + (inner - outer));
}
}
}
if (IsRowMajor) { const Index minInnerIndex = outer - m_data.lowerProfile(outer);
eigen_assert(inner >= minInnerIndex && "You tried to access a coeff that does not exist in the storage"); return this->m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));
} else { const Index maxInnerIndex = outer + m_data.lowerProfile(outer);
eigen_assert(inner <= maxInnerIndex && "You tried to access a coeff that does not exist in the storage"); return this->m_data.lower(m_rowStartIndex[outer] + (inner - outer));
}
}
inlinebool coeffExistLower(Index row, Index col) { const Index outer = IsRowMajor ? row : col; const Index inner = IsRowMajor ? col : row;
if (IsRowMajor) { const Index minOuterIndex = inner - m_data.upperProfile(inner);
eigen_assert(outer >= minOuterIndex && "You tried to access a coeff that does not exist in the storage"); return this->m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));
} else { const Index maxOuterIndex = inner + m_data.upperProfile(inner);
eigen_assert(outer <= maxOuterIndex && "You tried to access a coeff that does not exist in the storage"); return this->m_data.upper(m_colStartIndex[inner] + (outer - inner));
}
}
inlinebool coeffExistUpper(Index row, Index col) { const Index outer = IsRowMajor ? row : col; const Index inner = IsRowMajor ? col : row;
/** \returns the number of non zero coefficients */ inline Index nonZeros() const { return m_data.diagSize() + m_data.upperSize() + m_data.lowerSize();
}
/** Preallocates \a reserveSize non zeros */ inlinevoid reserve(Index reserveSize, Index reserveUpperSize, Index reserveLowerSize) {
m_data.reserve(reserveSize, reserveUpperSize, reserveLowerSize);
}
/** \returns a reference to a novel non zero coefficient with coordinates \a row x \a col.
* * \warning This function can be extremely slow if the non zero coefficients * are not inserted in a coherent order. * * After an insertion session, you should call the finalize() function.
*/
EIGEN_DONT_INLINE Scalar & insert(Index row, Index col) { const Index outer = IsRowMajor ? row : col; const Index inner = IsRowMajor ? col : row;
if (IsRowMajor) { if (outer < inner) //upper matrix
{
Index minOuterIndex = 0;
minOuterIndex = inner - m_data.upperProfile(inner);
if (outer < minOuterIndex) //The value does not yet exist
{ const Index previousProfile = m_data.upperProfile(inner);
m_data.upperProfile(inner) = inner - outer;
const Index bandIncrement = m_data.upperProfile(inner) - previousProfile; //shift data stored after this new one const Index stop = m_colStartIndex[cols()]; const Index start = m_colStartIndex[inner];
if (outer > inner) //lower matrix
{ const Index minInnerIndex = outer - m_data.lowerProfile(outer); if (inner < minInnerIndex) //The value does not yet exist
{ const Index previousProfile = m_data.lowerProfile(outer);
m_data.lowerProfile(outer) = outer - inner;
const Index bandIncrement = m_data.lowerProfile(outer) - previousProfile; //shift data stored after this new one const Index stop = m_rowStartIndex[rows()]; const Index start = m_rowStartIndex[outer];
//zeros new data
memset(this->_lowerPtr() + start, 0, (bandIncrement - 1) * sizeof (Scalar)); return m_data.lower(m_rowStartIndex[outer]);
} else { return m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));
}
}
} else { if (outer > inner) //upper matrix
{ const Index maxOuterIndex = inner + m_data.upperProfile(inner); if (outer > maxOuterIndex) //The value does not yet exist
{ const Index previousProfile = m_data.upperProfile(inner);
m_data.upperProfile(inner) = outer - inner;
const Index bandIncrement = m_data.upperProfile(inner) - previousProfile; //shift data stored after this new one const Index stop = m_rowStartIndex[rows()]; const Index start = m_rowStartIndex[inner + 1];
if (outer < inner) //lower matrix
{ const Index maxInnerIndex = outer + m_data.lowerProfile(outer); if (inner > maxInnerIndex) //The value does not yet exist
{ const Index previousProfile = m_data.lowerProfile(outer);
m_data.lowerProfile(outer) = inner - outer;
const Index bandIncrement = m_data.lowerProfile(outer) - previousProfile; //shift data stored after this new one const Index stop = m_colStartIndex[cols()]; const Index start = m_colStartIndex[outer + 1];
/** Must be called after inserting a set of non zero entries.
*/ inlinevoid finalize() { if (IsRowMajor) { if (rows() > cols())
m_data.resize(cols(), cols(), rows(), m_colStartIndex[cols()] + 1, m_rowStartIndex[rows()] + 1); else
m_data.resize(rows(), cols(), rows(), m_colStartIndex[cols()] + 1, m_rowStartIndex[rows()] + 1);
/** Resizes the matrix to a \a rows x \a cols matrix and initializes it to zero * \sa resizeNonZeros(Index), reserve(), setZero()
*/ void resize(size_t rows, size_t cols) { const Index diagSize = rows > cols ? cols : rows;
m_innerSize = IsRowMajor ? cols : rows;
eigen_assert(rows == cols && "Skyline matrix must be square matrix");
if (diagSize % 2) { // diagSize is odd const Index k = (diagSize - 1) / 2;
m_data.resize(diagSize, IsRowMajor ? cols : rows, IsRowMajor ? rows : cols,
2 * k * k + k + 1,
2 * k * k + k + 1);
} else// diagSize is even
{ const Index k = diagSize / 2;
m_data.resize(diagSize, IsRowMajor ? cols : rows, IsRowMajor ? rows : cols,
2 * k * k - k + 1,
2 * k * k - k + 1);
}
if (m_colStartIndex && m_rowStartIndex) { delete[] m_colStartIndex; delete[] m_rowStartIndex;
}
m_colStartIndex = new Index [cols + 1];
m_rowStartIndex = new Index [rows + 1];
m_outerSize = diagSize;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.