矩阵运算总结

#define LL __int64  
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 100;                // 矩阵的最大行和列  
const int MOD = 1e5;              // 如果可以不用取模,则尽量不用  
const double eps = 1e-6;             // 处理细小的精度问题  
const double pi = acos(-1.0);       // 圆周率  
class Mat
{
public:
	int n, m;
	double mat[MAXN][MAXN];
	Mat()
	{
		memset(mat, 0, sizeof(mat));
		n = m = MAXN - 1;
	};
	void init()                                       // 初始化为单位矩阵  
	{
		for (int i = 1; i <= n; ++i)
			for (int j = 1; j <= m; ++j)
				mat[i][j] = (i == j);
	}
	Mat operator * (Mat b)                            // 重载乘法  
	{
		Mat c;
		c = Mat();
		c.n = n;
		c.m = b.m;
		for (int i = 1; i <= n; ++i)                       // 注意这里从1开始  
			for (int j = 1; j <= b.m; ++j)
			{
				//if(mat[j][i] <= 0)  continue;       // 剪枝  
				for (int k = 1; k <= m; ++k)
				{
					//if(b.mat[i][k] <= 0) continue;  // 剪枝  
					//c.mat[i][j] += (mat[i][k] * b.mat[k][j]) % MOD;
					//c.mat[i][j] %= MOD;
					c.mat[i][j] += mat[i][k] * b.mat[k][j];
				}
			}
		return c;
	}
	Mat operator + (Mat b)                            // 重载加法  
	{
		Mat c;
		c.n = n;
		c.m = m;
		for (int i = 1; i <= n; ++i)
			for (int j = 1; j <= m; ++j)
				c.mat[i][j] = mat[i][j] + b.mat[i][j];
		return c;
	}
	Mat QuickPow(Mat a, int k)                        // 快速幂  
	{
		Mat c;
		c.n = a.n;
		c.m = a.n;
		c.init();                                     // 初始化为单位矩阵  
		while (k)
		{
			if (k & 1)//化为二进制然后看1 的个数
				c = c*a;
			a = a*a;
			k >>= 1;
		}
		return c;
	}
	Mat transpose()                                   // 求矩阵的转置  
	{
		Mat c;
		c.n = m;
		c.m = n;
		for (int i = 1; i <= n; ++i)
			for (int j = 1; j <= m; ++j)
				c.mat[j][i] = mat[i][j];
		/*for(int i=1,j=m; i<j; ++i,--j)             // 如果加上这里的代码的话,就是矩阵旋转本身
		for(int k=1; k<=n; ++k)
		{
		int tmp = c.mat[k][i];
		c.mat[k][i] = c.mat[k][j];
		c.mat[k][j] = tmp;
		}*/
		return c;
	}

	Mat slove(Mat init, int k)                        // 递归二分求解递增幂次和  
	{
		if (k == 1)
			return init;
		Mat c;
		c.n = init.n;
		c.m = init.m;
		c = slove(init, k >> 1);
		c = c + c * init.QuickPow(init, k >> 1);
		if (k & 1)
			return c + init.QuickPow(init, k);
		else
			return c;
	}

	void translate(Mat &a, double x, double y, double z)        // 平移(三维)  
	{
		Mat c;
		c.init();
		c.mat[1][4] = x;
		c.mat[2][4] = y;
		c.mat[3][4] = z;
		a = c * a;
	}
	void scale(Mat &a, double x, double y, double z)            // 缩放(三维)  
	{
		Mat c;
		c.init();
		c.mat[1][1] = x;
		c.mat[2][2] = y;
		c.mat[3][3] = z;
		a = c * a;
	}
	void rotat(Mat &a, double x, double y, double z, double d)  // 旋转(三维),以(0,0,0),(x,y,z)线段为旋转轴,旋转d度  
	{
		d = d / 180 * pi;
		double di = sqrt(x*x + y*y + z*z);                          // 单位化  
		x /= di, y /= di, z /= di;
		Mat c;
		c.init();
		c.mat[1][1] = (1 - cos(d))*x*x + cos(d);
		c.mat[1][2] = (1 - cos(d))*x*y - z*sin(d);
		c.mat[1][3] = (1 - cos(d))*x*z + y*sin(d);
		c.mat[2][1] = (1 - cos(d))*x*y + z*sin(d);
		c.mat[2][2] = (1 - cos(d))*y*y + cos(d);
		c.mat[2][3] = (1 - cos(d))*y*z - x*sin(d);
		c.mat[3][1] = (1 - cos(d))*x*z - y*sin(d);
		c.mat[3][2] = (1 - cos(d))*y*z + x*sin(d);
		c.mat[3][3] = (1 - cos(d))*z*z + cos(d);
		a = c * a;
	}

	void in(int x, int y)                     // 输入矩阵  
	{
		n = x;
		m = y;
		for (int i = 1; i <= n; ++i)
			for (int j = 1; j <= m; ++j)
				cin>>mat[i][j];
		
	}
	void out()                                // 输出矩阵  
	{
		for (int i = 1; i <= n; ++i)
		{			
			for (int j = 1; j <= m; ++j)
				cout<< mat[i][j];
			puts("");
		}
	}
	double getvalue()
	{
		if (n != m)
		{
			cout << "无法计算行列式" << endl;
			return 0;
		}
		if (n == 1)
		{
		 return mat[1][1];
		}
		
		Mat c;
		double res=0;
		c.m = c.n = n - 1;
		for (int i = 1; i <= n; i++)
		{
			for (int j = 1; j <= n - 1; j++)
				for (int k = 1; k <= n - 1; k++)
					c.mat[j][k] = mat[j + 1][(k >=i) ? (k + 1) : k];
			double tmp= c.getvalue();
			if (i % 2 == 0)
				res += tmp*mat[1][i];
			else
				res -= tmp*mat[1][i];
		}
		return res;
	}
	Mat company()
	{
		Mat res;
		res.m = res.n = n ;
		if (n != m)
		{
			cout << "无法计算伴随矩阵" << endl;
			return res;
		}
		if (n == 1)
		{
			res.mat[1][1] = 1;
			return res;
		}
		Mat tmp;
		tmp.m = tmp.n = n - 1;
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
			{
				for (int k = 1; k <= n - 1; k++)
					for (int t = 1; t <= n - 1; t++)
						tmp.mat[k][t] = mat[(k >= i) ? (k + 1) : k][(t >= j) ? (t + 1) : t];
				res.mat[j][i] = tmp.getvalue();
				if ((i+j)%2==1)
					res.mat[j][i] = -tmp.getvalue();
			}
		return res;
	}
	Mat convert()
	{
		double value = this->getvalue();
		Mat res = this->company();
		res.m = res.n = n;
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				res.mat[i][j] /= value;
		return res;

	}
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值