【发布时间】:2017-11-06 11:16:44
【问题描述】:
我正在实现一个稀疏矩阵类,使用映射向量来存储数据(映射表示一行矩阵,其中键是列的索引,值是该位置的矩阵的值) 我已经编写了计算行列式的函数,但我不知道是否有办法计算这个节省时间(因为矩阵是稀疏的,大部分值为零) 这是我的实现:
template <typename T>
T det(const SparseMatrix<T>& a )
{
T d =0 ; // value of determinant !
std::size_t row = a.getRows() ;
std::size_t cols = a.getCols() ;
if(row == cols) // square Matrix;
{
if(row == 1)
{
d = a(1,1); // matrix 1x1
}
else if(row == 2)
{
d = a(1,1) * a(2,2) - a(2,1) * a (1,2);
}
else // 3x3 of greather ..
{
for(std::size_t c = 1 ; c <= cols ; c++ )
{
SparseMatrix<T> m = a.minors(1,c);
d += pow(-1,1+c) * a(1,c) * det(m) ;
}
}
}
else
{
throw std::runtime_error("Matrix must be square! Error occured in SparseMatrix::det()");
}
return d ;
}
这是类接口
template <typename element_type>
class SparseMatrix {
public:
template<class T>
friend SparseMatrix<T> operator+(const SparseMatrix<T>& m1 , const SparseMatrix<T>& m2 );
template<class T>
friend SparseMatrix<T> operator-(const SparseMatrix<T>& m1 , const SparseMatrix<T>& m2 );
template <class T>
friend SparseMatrix<T> operator*(const SparseMatrix<T>& m1 , const SparseMatrix<T>& m2 );
template <class T>
friend std::ostream& operator<<(std::ostream& out , const SparseMatrix<T>& m);
template <class T>
friend SparseMatrix<T> dot(const SparseMatrix<T>& m1 , const SparseMatrix<T>& m2 );
template <class T>
T det(const SparseMatrix<T>& a );
public:
// container type ;
using data_type = std::vector<std::map<std::size_t , element_type >> ;
using it_rows = typename std::map<std::size_t , element_type>::iterator ;
constexpr SparseMatrix(std::size_t rows , std::size_t cols) : rows{rows} , columns{cols}
{
data.resize(rows);
}
SparseMatrix(std::initializer_list<std::initializer_list<element_type>> l );
SparseMatrix(const std::string );
auto insert(std::size_t i , std::pair<std::size_t, element_type> p )
{
assert( i < rows && p.first < columns); // , "Index out of bound" );
data.at(i).insert(p);
}
auto insert(std::size_t i, std::size_t j, element_type val)
{
assert(i<rows && j <columns);
data.at(i)[j] = val ;
}
auto identity() noexcept ;
auto diag(const element_type& v) noexcept ;
auto print() const noexcept ;
auto dataType() const noexcept ;
auto traspose() noexcept ;
auto printf()const noexcept ;
constexpr auto getRows() const noexcept { return rows; }
constexpr auto getCols() const noexcept { return columns; }
SparseMatrix<element_type> operator*=(const SparseMatrix<element_type>) ;
const element_type operator()(std::size_t , std::size_t) const noexcept ;
element_type operator()(std::size_t , std::size_t) noexcept ;
constexpr SparseMatrix<element_type> minors(const std::size_t , const std::size_t ) const;
private:
std::size_t rows ;
std::size_t columns ;
data_type data ; // vector containing row element
};
我计算行列式的方式是什么? 考虑到 operator() 是以这种方式重载的
template <typename T>
T SparseMatrix<T>::operator()(std::size_t i, std::size_t j) noexcept
{
i -= 1 ;
j -= 1 ;
if(data.at(i).find(j) != data.at(i).end())
{
return data.at(i).at(j) ;
}
else
{
return 0.0 ;
}
}
提前感谢您的帮助
【问题讨论】:
-
我有点惊讶你没有使用
std::map<std::pair<size_t, size_t>, double>,那么你希望operator() 是const auto it = data.find(std::make_pair(i, j); return it == data.end() ? 0.0 : *it;。 -
这应该更紧凑(并且避免在地图中重复查找和无意义的-1。)哦!另外,你不想要
map,你想要unordered_map。 -
@MartinBonner 我发现地图矢量更适应..你不知道吗?给我一个优势的例子!感谢您的帮助
-
@martin 您实际上想知道差距在哪里,因此有序可能会更好。或者您需要以某种方式存储间隙数据。
-
恕我直言,您不会浪费时间阅读有关数值线性代数的更多信息。我们通常从不使用坐标方法存储稀疏矩阵,但我们更喜欢像 CRS 这样的专用存储。我们通常从不计算大矩阵的行列式。您有关于稀疏矩阵的非常好的免费在线书籍,例如:www-users.cs.umn.edu/~saad/books.html
标签: c++ matrix determinants