📄 antprogram.txt
字号:
}
}
else if(g==1){
size_t nn;
fin>>nn;
for(int i=0;i<(int)rownum;i++)
for(int j=0;j<(int)colnum;j++)
set(i,j,0);
for(size_t i=0;i<(size_t)nn;i++){
int ii,jj;
double val;
fin>>ii>>jj>>val;
set(ii-1,jj-1,val);
}
}
else{
throw -1;
}
checksym(); // 检查是否为对称阵
}
void matrix::savefile(char * filename,int g){
size_t rownum1,colnum1;
ofstream fout(filename);
rownum1=getrownum();
colnum1=getcolnum();
if(g==2){
fout<<2<<"\n";
fout<<"matrix "<<rownum1<<" "<<colnum1<<endl;
for(size_t i=1;i<=rownum1;i++){
fout<<i<<":";
size_t j;
for(j=0;j<colnum1;j++){
fout<<" "<<value(i-1,j);
if((j%10)==9) fout<<endl;
}
if(((j-1)%10)!=9) fout<<endl;
}
}
else if(g==1){
fout<<1<<"\n";
fout<<"matrix "<<rownum1<<" "<<colnum1<<endl;
size_t nn=0;
for(int i=0;i<(int)rownum1;i++)
for(int j=0;j<(int)colnum1;j++)
if(value(i,j)!=0.0) nn++;
fout<<nn<<"\n";
for(int i=0;i<(int)rownum1;i++)
for(int j=0;j<(int)colnum1;j++){
if(value(i,j)!=0.0)
fout<<(i+1)<<" "<<(j+1)<<" "<<value(i,j);
}
}
else{
throw -1;
}
}
DOUBLE & matrix::operator()(size_t r, size_t c)
{
if(r>= rownum || c>= colnum)
throw TMESSAGE("Out range!");
return value(r,c);
}
matrix matrix::operator=(matrix m) // 赋值重载
{
rownum = m.rownum; // 行数和列数的拷贝
colnum = m.colnum;
istrans = m.istrans; // 转置标志的拷贝
isneg = m.isneg; // 取负标志的拷贝
issym = m.issym; // 对称标志的拷贝
if(buf == m.buf) // 如果原缓存与m的缓存一样,则返回
return (*this);
buf->refnum--; // 原缓存不同,则原缓存的引用数减1
if(!buf->refnum)delete buf; // 减1后的原缓存如果引用数为0,则删除原缓存
buf = m.buf; // 将原缓存指针指向m的缓存
buf->refnum++; // 新缓存的引用数增1
checksym(); // 检查是否为对称阵
return (*this); // 返回自己的引用
}
matrix matrix::operator=(DOUBLE a) // 通过赋值运算符将矩阵所有元素设为a
{
if(rownum == 0 || colnum == 0) return (*this);
for(size_t i=0; i<rownum; i++)
for(size_t j=0; j<colnum; j++)
set(i,j,a);
if(rownum == colnum)issym = 1;
return (*this);
}
matrix matrix::operator-() // 矩阵求负,产生负矩阵
{
matrix mm(*this);
mm.neg();
return mm;
}
ostream& operator<<(ostream& o, matrix& m) // 流输出运算符
{
// 先输出关键字matrix,然后是行号,制表符,列号,换行
o << "matrix " << m.rownum << '\t' << m.colnum << endl;
for(size_t i=0; i<m.rownum; i++) { // 依次输出各行
o<< (i+1) <<':'; // 行号后跟冒号。注意输出的行号是从1开始
// 是内部编程的行号加1
size_t k=8; // 后面输入一行的内容,每次一行数字超过八个时
// 就换一行
for(size_t j=0; j<m.colnum; j++) {
o<<'\t'<<m.value(i,j);
if(--k==0) {
k=8;
o<<endl;
}
}
o<<endl; // 每行结束时也换行
}
return o;
}
istream& operator>>(istream& in, matrix& m) // 流输入运算符
{
char label[10];
in.width(sizeof(label));
in >> label; // 输入matrix关键字
if(strcmp(label, "matrix")!=0)
throw TMESSAGE("format error!\n");
in >> m.rownum >> m.colnum; // 输入行号和列号
if(!in.good()) throw TMESSAGE("read file error!");
m.buf->refnum--; // 原缓存引用数减1
if(!m.buf->refnum) delete m.buf; // 如原缓存引用数为0,则删去原缓存
m.isneg = m.istrans = 0; // 转置和取负标志清零
m.buf = getnewbuffer(m.rownum*m.colnum); // 按缺省子类产生新缓存
size_t line; // 按矩阵行输入
for(size_t i=0; i<m.rownum; i++) {
in >> line; // 先输入行号
if(line != i+1) throw TMESSAGE("format error!\n");
in.width(sizeof(label)); // 行号后应跟冒号
in >> label;
if(label[0] != ':') throw TMESSAGE("format error!\n");
DOUBLE a; // 随后是本行的各个数值
for(size_t j=0; j<m.colnum; j++) {
in >> a;
m.set(i,j,a);
}
if(!in.good()) throw TMESSAGE("read file error!");
}
m.checksym(); // 检查是否为对称阵
return in;
}
matrix matrix::operator*=(DOUBLE a) // 矩阵数乘常数a,结果放在原矩阵
{
for(size_t i=0; i<rownum; i++)
for(size_t j=0; j<colnum; j++)
set(i,j,a*value(i,j));
return (*this);
}
matrix matrix::operator*(DOUBLE a) // 矩阵数乘常数a,原矩阵内容不变,返回一新矩阵
{
matrix m(rownum, colnum);
for(size_t i=0; i<rownum; i++)
for(size_t j=0; j<colnum; j++)
m.set(i,j,a*value(i,j));
return m;
}
matrix matrix::operator+(matrix& m) // 矩阵相加,产生一新的矩阵并返回它
{
if(rownum != m.rownum || colnum != m.colnum) // 对应行列必须相同
throw TMESSAGE("can not do add of matrix\n");
matrix mm(rownum, colnum); // 产生一同自己同形的矩阵
DOUBLE a;
for(size_t i=0; i<rownum; i++) // 求和
for(size_t j=0; j<colnum; j++)
{
a = value(i,j)+m.value(i,j);
mm.set(i,j,a);
}
mm.checksym(); // 检查是否为对称阵
return mm;
}
matrix matrix::operator+=(matrix m) // 矩阵求和,自己内容改变为和
{
DOUBLE a;
for(size_t i=0; i<rownum; i++)
for(size_t j=0; j<colnum; j++)
{
a = value(i,j)+m.value(i,j);
set(i,j,a);
}
checksym(); // 检查是否为对称阵
return (*this);
}
matrix matrix::operator+(DOUBLE a) // 矩阵加常数,指每一元素加一固定的常数,产生
// 新矩阵,原矩阵不变
{
matrix m(rownum, colnum);
for(size_t i=0; i<rownum; i++)
for(size_t j=0; j<colnum; j++)
m.set(i,j,a+value(i,j));
return m;
}
matrix matrix::operator+=(DOUBLE a) // 矩阵自身加常数,自身内容改变
{
for(size_t i=0; i<rownum; i++)
for(size_t j=0; j<colnum; j++)
set(i,j,a+value(i,j));
return (*this);
}
matrix operator-(DOUBLE a, matrix& m) { // 常数减矩阵,产生新的矩阵
return (-m)+a;
};
matrix matrix::operator-(matrix m) // 矩阵相减,产生新的矩阵
{
matrix mm(*this); // 产生一同自己同形的矩阵
//mm += -m; // 加上相应的负矩阵
matrix mm1;
mm1 = mm.operator-();
mm+= mm1;
return mm;
}
matrix matrix::operator-=(matrix m) // 矩阵相减,结果修改原矩阵
{
(*this) += (-m);
return (*this);
}
matrix matrix::operator*(matrix m) // 矩阵相乘,原矩阵内容不变,产生一新矩阵
{
if(colnum != m.rownum) // 必须满足相乘条件
throw TMESSAGE("can not multiply!");
matrix mm(rownum,m.colnum); // 计算并产生一合要求的矩阵放乘积
DOUBLE a;
for(size_t i=0; i<rownum; i++) // 计算乘积
for(size_t j=0; j<m.colnum; j++){
a = 0.0;
for(size_t k=0; k<colnum; k++)
a += value(i,k)*m.value(k,j);
mm.set(i,j,a);
}
mm.checksym(); // 检查是否为对称阵
return mm; // 返回乘积
}
matrix matrix::operator*=(matrix m) // 矩阵相乘,自己修改成积矩阵
{
(*this) = (*this)*m;
return (*this);
}
matrix matrix::t() // 矩阵转置,产生新的矩阵
{
matrix mm(*this);
mm.trans();
return mm;
}
int matrix::isnear(matrix m, double e) // 检查二矩阵是否近似相等
{
if(rownum != m.rownum || colnum != m.colnum) return 0;
for(size_t i=0; i< rownum; i++)
for(size_t j=0; j< colnum; j++)
if(fabs(value(i,j)-m.value(i,j)) > e) return 0;
return 1;
}
int matrix::isnearunit(double e) // 检查矩阵是否近似为单位矩阵
{
if(rownum != colnum) return 0;
return isnear(unit(rownum), e);
}
matrix matrix::row(size_t r) // 提取第r行行向量
{
matrix mm(1, colnum);
for(size_t i=0; i< colnum; i++)
mm.set(0, i, value(r,i));
return mm;
}
matrix matrix::col(size_t c) // 提取第c列列向量
{
matrix mm(rownum, 1);
for(size_t i=0; i< rownum; i++)
mm.set(i, value(i, c));
return mm;
}
void matrix::swapr(size_t r1, size_t r2, size_t k) // 交换矩阵r1和r2两行
{
DOUBLE a;
for(size_t i=k; i<colnum; i++) {
a = value(r1, i);
set(r1, i, value(r2, i));
set(r2, i, a);
}
}
void matrix::swapc(size_t c1, size_t c2, size_t k) // 交换c1和c2两列
{
DOUBLE a;
for(size_t i=k; i<colnum; i++) {
a = value(i, c1);
set(i, c1, value(i, c2));
set(i, c2, a);
}
}
DOUBLE matrix::maxabs(size_t &r, size_t &c, size_t k) // 求第k行和第k列后的主元及位置
{
DOUBLE a=0.0;
for(size_t i=k;i<rownum;i++)
for(size_t j=k;j<colnum;j++)
if(a < fabs(value(i,j))) {
r=i;c=j;a=fabs(value(i,j));
}
return a;
}
size_t matrix::zgsxy(matrix & m, int fn) // 进行主高斯消元运算,fn为参数,缺省为0
/* 本矩阵其实是常数阵,而矩阵m必须是方阵
运算过程其实是对本矩阵和m同时作行初等变换,
运算结果m的对角线相乘将是行列式,而本矩阵则变换成
自己的原矩阵被m的逆阵左乘,m的秩被返回,如果秩等于阶数
则本矩阵中的内容已经是唯一解
*/
{
if(rownum != m.rownum || m.rownum != m.colnum) // 本矩阵行数必须与m相等
// 且m必须是方阵
throw TMESSAGE("can not divide!");
lbuffer * bb = getnewlbuffer(rownum); // 产生一维数为行数的长整数缓存区
lbuffer & b = (*bb); // 用引用的办法使下面的程序容易懂
size_t is;
DOUBLE a;
size_t i,j,rank=0;
size_t k;
for(k=0; k<rownum; k++) { // 从第0行到第k行进行主高斯消元
if(m.maxabs(is, i, k)==0) // 求m中第k级主元,主元所在的行,列存在is,i中
break; // 如果主元为零,则m不可逆,运算失败
rank = k+1; // rank存放当前的阶数
b.retrieve(k) = i; // 将长整数缓存区的第k个值设为i
if(i != k)
m.swapc(k, i); // 交换m中i,k两列
if(is != k) {
m.swapr(k, is, k); // 交换m中i,k两行,从k列以后交换
swapr(k, is); // 交换本矩阵中i,k两行
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -