优化了一些算法
#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, );
}
}
}
 

c++矩阵运算的更多相关文章

  1. [Python学习] python 科学计算库NumPy—矩阵运算

    NumPy库的核心是矩阵及其运算. 使用array()函数可以将python的array_like数据转变成数组形式,使用matrix()函数转变成矩阵形式. 基于习惯,在实际使用中较常用array而 ...

  2. [OSG]矩阵运算

    我们都知道,OpenGL规定矩阵使用列主序存储,即glLoadMatrix等函数要求输入的数组是按列主序存储的矩阵.然而,一个很奇怪的事实是,OSG中矩阵存储是使用的标准C二维数组(行主序),并且也是 ...

  3. 基本矩阵运算的Java实现

      一: 矩阵的加法与减法 规则:矩阵的加法与减法要求两个矩阵的行列完全相等,方可以完成两个矩阵的之间的运算. 举例说明如下 二:矩阵的乘法 规则:矩阵的乘法要求两个矩阵符合A(mx k),  B( ...

  4. C#矩阵运算类库

    这个类库是本人参考许多相关资料之后做出的C#矩阵运算类库,因为C#的数值计算库相对比较少,所以希望这个类库能够给大家带来一些帮助. 源码github网址:https://github.com/Josh ...

  5. 【Unity】矩阵运算

    http://www.cnblogs.com/wywnet/p/3585075.html Vector3:  Unity3D中Vector3类定义(只写有用的):  属性:  x,y,z       ...

  6. C++矩阵运算库armadillo配置笔记

    前言 最近在用C++实现神经网络模型,优化算法需要用到矩阵操作,一开始我用的是boost的ublas库,但用着用着感觉很不习惯,接口不够友好.于是上网搜索矩阵运算哪家强,大神们都推荐armadillo ...

  7. C++矩阵运算库推荐

    最近在几个地方都看到有人问C++下用什么矩阵运算库比较好,顺便做了个调查,做一些相关的推荐吧.主要针对稠密矩阵,有时间会再写一个稀疏矩阵的推荐. Armadillo:C++下的Matlab替代品 地址 ...

  8. 实验12:Problem G: 强悍的矩阵运算来了

    这个题目主要是乘法运算符的重载,卡了我好久,矩阵的乘法用3个嵌套的for循环进行,要分清楚矩阵的乘法结果是第一个矩阵的行,第二个矩阵的列所组成的矩阵. 重载+,*运算符时,可以在参数列表中传两个矩阵引 ...

  9. python矩阵运算 不断收集整理

    python矩阵运算 转自:http://blog.sina.com.cn/s/blog_5f234d4701012p64.html Python使用NumPy包完成了对N-维数组的快速便捷操作.使用 ...

  10. 用cudamat做矩阵运算的GPU加速

    1. cudamat简介 cudamat是一个python语言下,利用NVIDIA的cuda sdk 进行矩阵运算加速的库.对于不熟悉cuda编程的程序员来说,这是一个非常方便的GPU加速方案.很多工 ...

随机推荐

  1. (转载)Convolutional Neural Networks卷积神经网络

    Convolutional Neural Networks卷积神经网络 Contents 一:前导 Back Propagation反向传播算法 网络结构 学习算法 二:Convolutional N ...

  2. IIs工作原理

    http://www.cnblogs.com/szhy222/archive/2008/07/14/1242576.html 问题: HTTP.SYS 的内置驱动程序 IIS 工作者进程

  3. 简单易学的机器学习算法——EM算法

    简单易学的机器学习算法——EM算法 一.机器学习中的参数估计问题 在前面的博文中,如“简单易学的机器学习算法——Logistic回归”中,采用了极大似然函数对其模型中的参数进行估计,简单来讲即对于一系 ...

  4. SKProductsRequest ios 7不调用delegate

    在iOS7中,内购只能在真机上才会调用 - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProdu ...

  5. Spark Streaming 结合FlumeNG使用实例

    SparkStreaming是一个对实时数据流进行高通量.容错处理的流式处理系统,可以对多种数据源(如Kdfka.Flume.Twitter.Zero和TCP 套接字)进行类似map.reduce.j ...

  6. hdu 2289 Cup (二分法)

    http://acm.hdu.edu.cn/showproblem.php?pid=2289 二分法解题. 这个题很恶心...一开始测试样例都不能过,这个π一开始取3.1415926结果是99.999 ...

  7. C/C++中程序在使用堆内存时的内存复用问题

    在一个C/C++程序中,如果使用了堆内存的管理机制,那么内存究竟是怎么分配与回收的呢? 先看一个程序: #include <iostream> using namespace std; i ...

  8. 【HDOJ】1881 毕业bg

    01背包. #include <cstdio> #include <cstring> #include <cstdlib> #define MAXN 1005 ty ...

  9. Unity 物体围绕圆周运动

    用Unity开发游戏中,经常会有搜寻的功能,这时候我们需要一个放大镜的图标在那圆周运动.写了相关脚本直接挂载在要圆周运动的物体上即可: using UnityEngine; using System. ...

  10. java桌面项目打包_by icewee_写得太棒了,直接转载了

    前言: 我们都知道Java可以将二进制程序打包成可执行jar文件,双击这个jar和双击exe效果是一样一样的,但感觉还是不同.其实将java程序打包成exe也需要这个可执行jar文件. 准备: ecl ...