优化了一些算法
#pragma once
#include <iostream>
#include <iomanip>
#include <string> #define OVERFLOWED 1E-12
class Matrix
{
public:
Matrix(int m, int n); //构建一个m*n的全零矩阵
Matrix(int n); //构建一个n*n的单位矩阵
Matrix(const Matrix &); //拷贝构造函数,深拷贝
Matrix(double* items, int m, int n);//根据数组拷贝一个矩阵
~Matrix();
static Matrix FromFile(std::string file);
int getRowNum() const; //返回矩阵的行数
int getColNum() const; //返回矩阵的列数 Matrix Trans() const; //将矩阵转置 double get(int i, int j) const; //返回矩阵第i行j列元素
void set(int i, int j, double val); //设置矩阵第i行j列元素 Matrix operator +(const Matrix &m); //两个矩阵相加
Matrix operator -(const Matrix &m); //两个矩阵相减
Matrix operator *(const Matrix &m); //两个矩阵相乘
Matrix operator *(const double f); //矩阵乘以常数
Matrix& operator=(const Matrix& m);
Matrix Inverse(); friend std::ostream& operator <<(std::ostream &os, const Matrix &m); private:
double *item; //指向矩阵首元素
int rowNum; //矩阵行数
int colNum; //矩阵列数 private:
//矩阵初等行变换
//如果j=-1,则对i扩大multiply倍
//如果j在取值范围内,则将第i行扩大multiply倍加到j行
void RowSwap(int i, int j, double multiply);
//交换两行
void RowSwap(int i, int j);
void FlowOver();
};
#include "Matrix.h"
#include <vector>
#include <cmath>
#include <fstream>
#include <sstream> using namespace std;
Matrix::Matrix(int m, int n)
{
if (m < || n < )
{
cout << "矩阵大小不能为负\n";
return;
}
rowNum = m;
colNum = n;
item = new double[m*n];
for (int i = ; i < m*n; i++)
{
item[i] = ;
}
} //也可用二维数组初始化
Matrix::Matrix(double* items, int m, int n)
{
rowNum = m;
colNum = n;
item = new double[m*n];
for (int i = ; i < colNum*rowNum; i++)
{
item[i] = items[i];
}
}
Matrix::Matrix(int n)
{
rowNum = colNum = n;
item = new double[n*n];
for (int i = ; i < n; i++)
{
for (int j = ; j < n; j++)
{
if (i == j)
set(i, j, 1.0);
else
set(i, j, );
}
}
}
Matrix::Matrix(const Matrix &M)
{
colNum = M.colNum;
rowNum = M.rowNum;
//这里不能对指针直接赋值,复制对求逆、转置等操作会影响原矩阵
item = new double[colNum*rowNum];
for (int i = ; i < colNum*rowNum; i++)
{
item[i] = M.item[i];
}
}
Matrix& Matrix::operator=(const Matrix & M)
{
colNum = M.colNum;
rowNum = M.rowNum;
if (item != nullptr) delete[] item;
item = new double[colNum*rowNum];
for (int i = ; i < colNum*rowNum; i++)
{
item[i] = M.item[i];
}
return *this;
} Matrix Matrix::FromFile(std::string file)
{
ifstream read(file);
if (!read.is_open())
{
cout << "Matrix::未能打开文件\n";
}
int rows = ;
string line;
vector<double> nums;
while (getline(read, line))
{
istringstream record(line);
double num = 0.0;
while (record >> num) nums.push_back(num);
rows++;
}
return Matrix(&(*nums.begin()), rows, nums.size() / rows);
} Matrix::~Matrix()
{
delete[] item;
}
double Matrix::get(int i, int j) const
{
return item[i*colNum + j];
}
void Matrix::set(int i, int j, double value)
{
item[i*colNum + j] = value;
}
void Matrix::RowSwap(int i, int j, double multiply)
{
if (j == -)
{
for (int k = ; k < colNum; k++)
{
set(i, k, multiply*get(i, k));
}
}
else
{
for (int k = ; k < colNum; k++)
{
set(j, k, multiply*get(i, k) + get(j, k));
}
}
}
void Matrix::RowSwap(int i, int j)
{
Matrix _copy = *this;
for (int k = ; k < colNum; k++)
{
double swap = _copy.get(j, k);
set(j, k, _copy.get(i, k));
set(i, k, swap);
}
}
Matrix Matrix::Trans() const
{
Matrix _copy = *this;
_copy.rowNum = this->colNum;
_copy.colNum = this->rowNum;
for (int i = ; i < _copy.rowNum; i++)
{
for (int j = ; j < _copy.colNum; j++)
{
_copy.set(i, j, get(j, i));
}
}
return _copy;
}
int Matrix::getRowNum() const
{
return rowNum;
}
int Matrix::getColNum() const
{
return colNum;
}
ostream& operator <<(ostream &os, const Matrix &m)
{
for (int i = ; i < m.rowNum; i++)
{
for (int j = ; j < m.colNum; j++)
os << std::setw() << std::fixed << std::setprecision() << m.get(i, j) << " ";
os << "\n";
}
os.flush();
return os;
}
Matrix Matrix::operator +(const Matrix &m)
{
if (m.colNum != colNum || m.rowNum != rowNum) return *this;
Matrix _copy = *this;
for (int i = ; i < rowNum; i++)
{
for (int j = ; j < colNum; j++)
{
_copy.set(i, j, get(i, j) + m.get(i, j));
}
}
return _copy;
}
Matrix Matrix::operator -(const Matrix &m)
{
if (m.colNum != colNum || m.rowNum != rowNum) return *this;
Matrix _copy = *this;
for (int i = ; i < rowNum; i++)
{
for (int j = ; j < colNum; j++)
{
_copy.set(i, j, get(i, j) - m.get(i, j));
}
}
return _copy;
}
Matrix Matrix::operator *(const double f)
{
Matrix _copy = *this;
for (int i = ; i < rowNum; i++)
{
for (int j = ; j < colNum; j++)
{
_copy.set(i, j, get(i, j)*f);
}
}
return _copy;
}
Matrix Matrix::operator *(const Matrix &m)
{
if (colNum != m.rowNum)
{
cout << "无法相乘!";
return *this;
}
Matrix _copy(rowNum, m.getColNum());
for (int i = ; i < rowNum; i++)
{
for (int j = ; j < m.colNum; j++)
{
double sum = ;
for (int k = ; k < m.rowNum; k++)
{
sum += get(i, k)*m.get(k, j);
}
_copy.set(i, j, sum);
}
}
return _copy;
}
Matrix Matrix::Inverse()
{
Matrix _copy = *this;
//变换结果
Matrix result(colNum);
if (colNum != rowNum)
{
cout << "矩阵不可逆!" << endl;
return *this;
}
for (int i = ; i < rowNum; i++)
{
int MaxRow = i;
//首先找到第i列的绝对值最大的数,并将该行和第i行互换
double max = abs(_copy.get(i, i));
for (int j = i; j < colNum; j++)
{
if (abs(_copy.get(j, i))>max)
{
max = abs(_copy.get(j, i));
MaxRow = j;
}
}
//交换j,i两行
if (MaxRow != i)
{
result.RowSwap(i, MaxRow);
_copy.RowSwap(i, MaxRow);
}
//将第i行做初等行变换,将第一个非0元素化为1
double r = 1.0 / _copy.get(i, i);
_copy.RowSwap(i, -, r);
result.RowSwap(i, -, r);
//消元
for (int j = ; j < rowNum; j++)
{
if (j == i) continue;
r = -_copy.get(j, i);
_copy.RowSwap(i, j, r);
result.RowSwap(i, j, r);
}
}
//result.FlowOver();
return result;
}
void Matrix::FlowOver()
{
for (int i = ; i < rowNum;i++)
{
for (int j = ; j < colNum;j++)
{
if (abs(get(i, j)) <= OVERFLOWED) set(i, j, );
}
}
}
 

最新文章

  1. Win8.1安装mysql-installer-community-5.6.21.0.mis
  2. 错误:ORA-28009: connection as SYS should be as SYSDBA or SYSOPER 的解决办法--转载但验证过后可以用
  3. 使用SDWebImage下载图片,sharedDownloader方法下载成功,new 方法下载失败
  4. android中在代码中设置margin属性
  5. bignum 大数模板
  6. ContactsContract中涉及数据库中的一些列属性值【Written By KillerLegend】
  7. Class&lt;Object&gt;与Class&lt;?&gt;有何区别呢
  8. Android开发之隐式Intent中Intent-filter的三个属性-action,category,data
  9. js如何获取一个月的天数 data javascript
  10. 【Java】Java里String 的equals和==
  11. @ManyToMany中间表附加字段设计
  12. 挂载mount、卸载umount、挂载光盘U盘
  13. java中抽象类和接口之间的异同点
  14. ECMA Script 6_唯一容器 Set_映射容器 Map
  15. 《大型网站系统与Java中间件实现》有感
  16. Python Day 9
  17. ES6 迭代器
  18. Java NIO -- 管道 (Pipe)
  19. 【Spark 深入学习 07】RDD编程之旅基础篇03-键值对RDD
  20. 【CSV文件】CSV文件内容读取

热门文章

  1. ie8如何支持html5
  2. inline-block的垂直居中
  3. SecureCRT 颜色
  4. LeetCode_3 sum closet
  5. 【转】微信Android SDK示例代码及运行方法
  6. Request.ServerVariables详细说明
  7. 如何优雅的输出PHP调试信息
  8. 出现 HTTP Error 503. The service is unavailable 错误
  9. MacOS下的生活——RescueTime,时间规划利器
  10. windows下安装python的C扩展编译环境(解决“Unable to find vcvarsall.bat”)