- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
大家好,我实现了一个存储在修改后的压缩稀疏行中的稀疏矩阵!构造函数工作正常,我可以验证它,但 operator+ 有一个奇怪的行为:如果我有一个非零值,则总和不会计算出正确的结果。描述了改进的压缩稀疏行方法 here我的最低工作代码如下:
# include <initializer_list>
# include <vector>
# include <iosfwd>
# include <string>
# include <cstdlib>
# include <cassert>
# include <iomanip>
# include <cmath>
# include <set>
# include <fstream>
# include <algorithm>
# include <exception>
template <typename data_type>
class MCSRmatrix;
template <typename T>
std::ostream& operator<<(std::ostream& os ,const MCSRmatrix<T>& m) noexcept ;
template <typename T>
MCSRmatrix<T> operator+(const MCSRmatrix<T>& m1, const MCSRmatrix<T>& m2 ) ;
template <typename data_type>
class MCSRmatrix {
public:
using itype = std::size_t ;
template <typename T>
friend std::ostream& operator<<(std::ostream& os ,const MCSRmatrix<T>& m) noexcept ;
template <typename T>
friend MCSRmatrix<T> operator+(const MCSRmatrix<T>& m1, const MCSRmatrix<T>& m2 ) ;
public:
constexpr MCSRmatrix( std::initializer_list<std::initializer_list<data_type>> rows);
constexpr MCSRmatrix(const std::size_t& ) noexcept;
const data_type& operator()(const itype r , const itype c) const noexcept ;
data_type operator()(const itype r , const itype c) noexcept ;
auto constexpr printMCSR() const noexcept ;
private:
std::vector<data_type> aa_ ; // vector of value
std::vector<itype> ja_ ; // pointer vector
int dim ;
std::size_t constexpr findIndex(const itype row , const itype col) const noexcept ;
};
template <typename T>
constexpr MCSRmatrix<T>::MCSRmatrix( std::initializer_list<std::initializer_list<T>> rows)
{
this->dim = rows.size();
auto _rows = *(rows.begin());
aa_.resize(dim+1);
ja_.resize(dim+1);
if(dim != _rows.size())
{
throw std::runtime_error("Error in costructor! MCSR format require square matrix!");
}
itype w = 0 ;
ja_.at(w) = dim+2 ;
for(auto ii = rows.begin(), i=1; ii != rows.end() ; ++ii, i++)
{
for(auto ij = ii->begin(), j=1, elemCount = 0 ; ij != ii->end() ; ++ij, j++ )
{
if(i==j)
aa_[i-1] = *ij ;
else if( i != j && *ij != 0 )
{
ja_.push_back(j);
aa_.push_back(*ij);
elemCount++ ;
}
ja_[i] = ja_[i-1] + elemCount;
}
}
printMCSR();
}
template <typename T>
constexpr MCSRmatrix<T>::MCSRmatrix(const std::size_t& n ) noexcept
{
this->dim = n;
aa_.resize(dim+1);
ja_.resize(dim+1);
for(std::size_t i = 0; i < aa_.size()-1 ; i++)
aa_.at(i) = 1 ;
for(std::size_t i = 0; i < ja_.size() ; i++)
ja_.at(i) = aa_.size()+1 ;
}
template <typename T>
std::size_t constexpr MCSRmatrix<T>::findIndex(const itype row , const itype col) const noexcept
{
assert( row > 0 && row <= dim && col > 0 && col <= dim );
if(row == col)
{
return row-1;
}
int i = -1;
for(int i = ja_.at(row-1)-1 ; i < ja_.at(row)-1 ; i++ )
{
if( ja_.at(i) == col )
{
return i ;
}
}
return -1;
}
template <typename T>
inline auto constexpr MCSRmatrix<T>::printMCSR() const noexcept
{
for(auto& x : aa_ )
std::cout << x << ' ' ;
std::cout << std::endl;
for(auto& x : ja_ )
std::cout << x << ' ' ;
std::cout << std::endl;
}
template <typename T>
const T& MCSRmatrix<T>::operator()(const itype r , const itype c) const noexcept
{
auto i = findIndex(r,c);
if( i != -1 && i < aa_.size() )
{
return aa_.at(i) ;
}
else
{
return aa_.at(dim) ;
}
}
template <typename T>
T MCSRmatrix<T>::operator()(const itype r , const itype c) noexcept
{
auto i = findIndex(r,c);
if( i != -1 && i < aa_.size() )
{
return aa_.at(i) ;
}
else
{
return aa_.at(dim) ;
}
}
// non member operator
template <typename T>
std::ostream& operator<<(std::ostream& os ,const MCSRmatrix<T>& m) noexcept
{
for(std::size_t i=1 ; i <= m.dim ; i++ )
{
for(std::size_t j=1 ; j <= m.dim ; j++)
os << std::setw(8) << m(i,j) << ' ' ;
os << std::endl;
}
return os;
}
// perform sum by 2 Mod Comp Sparse Row matrices
template <typename T>
MCSRmatrix<T> operator+(const MCSRmatrix<T>& m1, const MCSRmatrix<T>& m2 )
{
if(m1.dim != m2.dim)
{
throw std::runtime_error("Matrixs dimension does not match! Error in operator +");
}
else
{
MCSRmatrix<T> res(m1.dim);
for(auto i=0; i < res.dim ; i++)
res.aa_.at(i) = m1.aa_.at(i) + m2.aa_.at(i) ;
res.ja_.at(0) = res.dim+2;
std::set<unsigned int> ctrl;
int n1=0, n2=0, j1=0 , j2 =0;
for(auto i=0 ; i < res.dim ; i++)
{
ctrl.clear();
n1 = m1.ja_.at(i+1)- m1.ja_.at(i) ;
n2 = m2.ja_.at(i+1)- m2.ja_.at(i) ;
j1=0 , j2=0 ;
auto sum1 = 0. , sum2 = 0. , sum=0.;
for(auto j = 0; j < std::max(n1,n2) ; j++ )
{
if(n1 && n2)
{
if(m1.ja_.at(m1.ja_.at(i)-1 + j1 ) == m2.ja_.at(m2.ja_.at(i)-1 + j2))
{
ctrl.insert(m1.ja_.at(m1.ja_.at(i)-1 + j1 ));
sum = m1.aa_.at(m1.ja_.at(i)-1 + j1 ) + m2.aa_.at(m2.ja_.at(i)-1 + j2) ;
}
else if(m1.ja_.at(m1.dim+1 + j1 ) != m2.ja_.at(m2.dim+1 + j2))
{
ctrl.insert(m1.ja_.at(m1.ja_.at(i)-1 + j1 ));
ctrl.insert(m2.ja_.at(m1.ja_.at(i)-1 + j2 ));
sum1 = m1.aa_.at(m1.ja_.at(i)-1 + j1);
sum2 = m2.aa_.at(m2.ja_.at(i)-1 + j1);
}
}
else if(n1)
{
ctrl.insert(m1.ja_.at(m1.ja_.at(i)-1 + j1 ));
sum1 = m1.aa_.at(m1.ja_.at(i)-1 + j1);
}
else if(n2)
{
ctrl.insert(m2.ja_.at(m2.ja_.at(i)-1 + j2 ));
sum2 = m2.aa_.at(m2.ja_.at(i)-1 + j2);
}
if(sum1)
{
res.aa_.push_back(sum1);
res.ja_.push_back(m1.ja_.at(m1.ja_.at(i)-1 + j1)) ;
}
if(sum2)
{
res.aa_.push_back(sum2);
res.ja_.push_back(m2.ja_.at(m2.ja_.at(i)-1 + j2 ));
}
if(sum)
{
res.aa_.push_back(sum);
res.ja_.push_back(m1.ja_.at(m1.ja_.at(i)-1 + j1 ));
}
if(j1 < n1) j1++ ;
if(j2 < n2) j2++ ;
}
res.ja_.at(i+1) = res.ja_.at(i) + ctrl.size() ;
}
return res ;
}
}
这是主程序:
# include "ModifiedCSRmatrix.H"
using namespace std ;
int main() {
MCSRmatrix<int> m01 = {{0,1,0,0},{0,3,0,0},{0,0,0,3},{0,0,0,1}};
MCSRmatrix<int> m02 = {{1,1,0,14},{0,22,0,3},{0,0,33,34},{0,0,1,44}};
cout << endl;
MCSRmatrix<int> m03 = m01+m02 ;
cout << m03 << endl;
cout << endl;
m03.printMCSR();
return 0;
}
这个特殊的 2 矩阵给我正确的结果!那就是:
1 2 0 17
0 25 0 3
0 0 33 37
0 0 1 45
但如果我更改 m01
矩阵中元素 (3,2)
的值..所以矩阵变成了:
MCSRmatrix<int> m01 = {{0,1,0,0},{0,3,0,0},{0,2,0,3},{0,0,0,1}};
代码给我这个错误的结果:
1 2 0 0
0 25 0 14
0 2 33 0
0 0 0 45
但查看 vector aa_
(值 vector ,其中第一个 matrix.dim
是对角线元素,后面的元素是对角线元素非零元素看起来矩阵与此结果不同)他们是:
aa_ = 1 25 33 45 0 2 2 14 2 3 3 1 1
ja_ = 6 8 9 10 11 2 2 4 2 4 4 3 3
另一个例子,如果我把这一行放到主目录中:
MCSRmatrix<double> m3 = {{1.01, 0 , 0,0}, {0, 4.07, 0,0},{0,0,6.08,0},{1.06,0,2.2,9.9} };
MCSRmatrix<double> m4 = {{ 1.21, 0 , 1.06,0 }, {0, 3.31, 1.06,0},{0,1.06,-6.01,0},{4.12,0,1.06,-8.3}};
MCSRmatrix<double> m5 = m3+m4 ;
cout << m5 ;
给我正确的结果:
2.22 0 1.06 0
0 7.38 1.06 0
0 1.06 0.07 0
5.18 0 3.26 1.6
如果我稍微改变一下 m1 和 m2 :
MCSRmatrix<double> m6 = {{1.01, 0 , 0,0}, {0, 4.07, 0,0},{0,0,6.08,0},{1.06,0,2.2,9.9} };
MCSRmatrix<double> m7 = {{ 1.21, 0 , 0,2.15 }, {0, 3.31, 1.03,0},{0,1.06,-6.01,1.01},{4.12,1.1,1.06,-8.3}};
cout << m6+m7 ;
此程序退出并在抛出“std::out_of_range”实例后调用terminate
最佳答案
在设置 sum1
和 sum2
的添加循环部分,您不想两者都做,只做索引值较低的那个.这是因为较高的列号可能在另一个矩阵中,但在行中更远。
此外,sum2
的索引计算应该使用 j2
而不是 j1
。
关于c++ - 运算符 + 在稀疏矩阵 : I don't find any bug,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47418747/
Or 运算符 对两个表达式进行逻辑“或”运算。 result = expression1 Or expression2 参数 result 任意数值变量。 expression1 任意
Not 运算符 对表达式执行逻辑非运算。 result = Not expression 参数 result 任意数值变量。 expression 任意表达式。 说明 下表显示如何
Is 运算符 比较两个对象引用变量。 result = object1 Is object2 参数 result 任意数值变量。 object1 任意对象名。 object2 任意
\ 运算符 两个数相除并返回以整数形式表示的结果。 result = number1\number2 参数 result 任意数值变量。 number1 任意数值表达式。 numbe
And 运算符 对两个表达式进行逻辑“与”运算。 result = expression1 And expression2 参数 result 任意数值变量。 expression1
运算符(+) 计算两个数之和。 result = expression1 + expression2 参数 result 任意数值变量。 expression1 任意表达式。 exp
我对此感到困惑snippet : var n1 = 5-"4"; var n2 = 5+"4"; alert(n1); alert(n2); 我知道 n1 是 1。那是因为减号运算符会将字符串“4”转
我想我会得到 12,而不是 7。 w++,那么w就是4,也就是100,而w++, w 将是 8,1000;所以 w++|z++ 将是 100|1000 = 1100 将是 12。 我怎么了? int
Xor 运算符 对两个表达式进行逻辑“异或”运算。 result = expression1 Xor expression2 参数 result 任意数值变量。 expression1
Mod 运算符 两个数值相除并返回其余数。 result = number1 Mod number2 参数 result 任意数值变量。 number1 任意数值表达式。 numbe
Imp 运算符 对两个表达式进行逻辑蕴涵运算。 result = expression1 Imp expression2 参数 result 任意数值变量。 expression1 任
Eqv 运算符 执行两个表达式的逻辑等价运算。 result = expression1 Eqv expression2 参数 result 任意数值变量。 expression1 任
我有一个运算符重载的简单数学 vector 类。我想为我的运算符(operator)获取一些计时结果。我可以通过计时以下代码轻松计时我的 +=、-=、*= 和/=: Vector sum; for(s
我是用户定义比较运算符的新手。我正在读一本书,其中提到了以下示例: struct P { int x, y; bool operator、运算符<等),我们
在 SQL 的维基百科页面上,有一些关于 SQL 中 bool 逻辑的真值表。 [1] 维基百科页面似乎来源于 SQL:2003 标准。 等号运算符 (=) 的真值表与 SQL:2003 草案中的 I
我遇到了一个奇怪的 C++ 运算符。 http://www.terralib.org/html/v410/classoracle_1_1occi_1_1_number.html#a0f2780081f
我正在阅读关于 SO 和 answers 中的一个问题,它被提到为: If no unambiguous matching deallocation function can be found, pr
我偶然发现了这个解决方案,但我无法理解其中到底发生了什么。谁能解释一下! 据我了解,它试图通过计算一半的单元格然后将其加倍来计算 a*b 网格中的单元格数量。但是我无法理解递归调用。 请不要建议其他解
Go的基本类型 布尔类型bool 长度:1字节 取值:布尔类型的取值只能是true或者false,不能用数字来表示 整型 通用整型 int / uint(有符号 / 无符号,下面也类似) 长度:根据运
在本教程中,您将学习JavaScript中可用的不同运算符,以及在示例的帮助下如何使用它们。 什么是运算符? 在JavaScript中,运算符是一种特殊符号,用于对运算数(值和变量)执行操作。例如,
我是一名优秀的程序员,十分优秀!