精华内容
下载资源
问答
  • C++矩阵求逆

    2018-05-18 16:03:52
    该资源是对于多入多出矩阵求逆C++编程语言实现,用于多入多出的矩阵求逆算法,本人是用机器人系统设计控制算法,亲自验证代码的可行性
  • c++ 矩阵求逆

    千次阅读 2018-09-07 15:29:27
    //矩阵乘法 void pbgMatricMul(zdouble_t C[DN * DN], double A[DN * DN],double B[DN * DN]) { for (int32_t i = 0; i < DN; i++) { for (int32_t j = 0; j < DN; j++) { f...
    //矩阵乘法
    void pbgMatricMul(zdouble_t C[DN * DN], double A[DN * DN],double B[DN * DN])
    {
        for (int32_t i = 0; i < DN; i++)
        {
            for (int32_t j = 0; j < DN; j++)
            {
                for (int32_t k = 0; k < DN; k++)
                {
                    C[i * DN + j] += A[ i * DN + k] * B[k * DN + j];
                }
            }
        }
    
        //若绝对值小于10^-5,则置为0
        for (int32_t i = 0; i < DN * DN ; i++)
        {
            if (abs(C[i]) < 1e-5)
            {
                C[i] = 0;
            }
        }
    }
    
    //LUP分解
    void pbgLupDescomposition(zdouble_t A[DN * DN], zdouble_t L[DN * DN], zdouble_t U[DN * DN], int32_t P[DN])
    {
        int32_t row = 0;
        for (int32_t i = 0;i < DN; i++)
        {
            P[i] = i;
        }
        for (int32_t i = 0; i < DN - 1;i++)
        {
            zdouble_t p = 0.0;
            for (int32_t j = i; j < DN; j++)
            {
                if (abs( A[j * DN + i]) > p)
                {
                    p   = abs(A[j * DN + i]);
                    row = j;
                }
            }
            if(0 == p)
            {
                //cout<< "矩阵奇异,无法计算逆" <<endl;
                return ;
            }
    
            //交换P[i]和P[row]
            int32_t tmp = P[i];
            P[i]        = P[row];
            P[row]      = tmp;
    
            zdouble_t tmp2 = 0.0;
            for (int32_t j = 0; j < DN; j++)
            {
                //交换A[i][j]和 A[row][j]
                tmp2 = A[i * DN + j];
                A[i * DN + j]   = A[row * DN + j];
                A[row * DN + j] = tmp2;
            }
    
            //以下同LU分解
            zdouble_t u = A[i * DN + i], l = 0.0;
            for (int32_t j = i + 1; j < DN; j++)
            {
                l = A[j * DN + i] / u;
                A[j * DN + i] = l;
                for (int32_t k = i + 1; k < DN; k ++)
                {
                    A[j * DN + k] = A[j * DN + k] - A[i * DN + k] * l;
                }
            }
        }
    
        //构造L和U
        for (int32_t i = 0; i < DN; i++)
        {
            for (int32_t j = 0; j <= i; j++)
            {
                if (i != j)
                {
                    L[i * DN + j] = A[i * DN + j];
                }
                else
                {
                    L[i * DN + j] = 1;
                }
            }
            for (int32_t k = i; k < DN; k++)
            {
                U[i * DN + k] = A[i * DN + k];
            }
        }
    }
    
    //LUP求解方程
    zdouble_t * pbgLupSolve(zdouble_t L[DN * DN], zdouble_t U[DN * DN], int P[DN], zdouble_t b[DN])
    {
        zdouble_t *x=new double[DN]();
        zdouble_t *y=new double[DN]();
    
        //正向替换
        for (int32_t i = 0;i < DN;i++)
        {
            y[i] = b[P[i]];
            for (int32_t j = 0;j < i;j++)
            {
                y[i] = y[i] - L[i * DN + j] * y[j];
            }
        }
        //反向替换
        for (int32_t i = DN-1;i >= 0; i--)
        {
            x[i] = y[i];
            for (int32_t j = DN-1;j > i;j--)
            {
                x[i] = x[i] - U[i * DN + j] * x[j];
            }
            x[i] /= U[i * DN + i];
        }
        return x;
    }
    
    /*****************矩阵原地转置BEGIN********************/
    
    /* 后继 */
    int32_t pbgGetNext(int32_t i, int32_t m, int32_t n)
    {
        return (i % n) * m + i / n;
    }
    
    /* 前驱 */
    int32_t pbgGetPre(int32_t i, int32_t m, int32_t n)
    {
        return (i % m) * n + i / m;
    }
    
    /* 处理以下标i为起点的环 */
    void pbgMovedata(zdouble_t *mtx, int32_t i, int32_t m, int32_t n)
    {
        zdouble_t temp = mtx[i]; // 暂存
        int32_t   cur = i;    // 当前下标
        int32_t   pre = pbgGetPre(cur, m, n);
        while(pre != i)
        {
            mtx[cur] = mtx[pre];
            cur = pre;
            pre = pbgGetPre(cur, m, n);
        }
        mtx[cur] = temp;
    }
    
    /* 转置,即循环处理所有环 */
    void pbgTranspose(zdouble_t *mtx, int32_t m, int32_t n)
    {
        for (int32_t i =0; i < m * n; ++i)
        {
            int32_t next = pbgGetNext(i, m, n);
    
            while(next > i) // 若存在后继小于i说明重复,就不进行下去了(只有不重复时进入while循环)
            {
                next = pbgGetNext(next, m, n);
            }
            if(next == i)  // 处理当前环
            {
                pbgMovedata(mtx, i, m, n);
            }
        }
    }
    /*****************矩阵原地转置END********************/
    
    //LUP求逆(将每列b求出的各列x进行组装)
    void pbgLupSolveInverse(zdouble_t inv_A[DN * DN], zdouble_t A[DN * DN])
    {
        //创建矩阵A的副本,注意不能直接用A计算,因为LUP分解算法已将其改变
        zdouble_t *A_mirror   = new zdouble_t[DN * DN]();
        //zdouble_t *inv_A      = new zdouble_t[DN * DN]();//最终的逆矩阵(还需要转置)
        zdouble_t *inv_A_each = new zdouble_t[DN]();//矩阵逆的各列
        //double *B    =new double[DN*DN]();
        zdouble_t *b          =new zdouble_t[DN]();//b阵为B阵的列矩阵分量
    
        for(int32_t i = 0; i < DN; i++)
        {
            zdouble_t *L = new zdouble_t[DN * DN]();
            zdouble_t *U = new zdouble_t[DN * DN]();
            int32_t   *P = new int32_t[DN]();
    
            //构造单位阵的每一列
            for(int32_t j = 0; j < DN; j++)
            {
                b[j] = 0;
            }
            b[i] = 1;
    
            //每次都需要重新将A复制一份
            for(int32_t j = 0; j < DN * DN; j++)
            {
                A_mirror[j] = A[j];
            }
    
            pbgLupDescomposition(A_mirror, L, U, P);
    
            inv_A_each = pbgLupSolve (L, U, P, b);
            memcpy(inv_A + i * DN, inv_A_each, DN * sizeof(zdouble_t));//将各列拼接起来
        }
        pbgTranspose(inv_A, DN, DN);//由于现在根据每列b算出的x按行存储,因此需转置
    
       // return inv_A;
    }

     

    展开全文
  • c++矩阵求逆 可以运行

    2010-05-20 16:01:01
    c++矩阵求逆 可以选择矩阵的阶数 矩阵化输出
  • c++矩阵求逆矩阵源代码 原创

    热门讨论 2009-11-08 21:35:41
    c++矩阵求逆矩阵源代码,采用初等变换法进行矩阵的求逆,时间耗费小。可调节矩阵维数(改变程序中常量M即可)。
  • 利用矩阵lu分解的优秀特性进行矩阵求逆的代码,减少求逆计算量,大约200行 求逆矩阵思路: 1.求矩阵的crout(LU)分解,其中L为下三角矩阵,U为上三角矩阵 2.L,U矩阵的伴随阵,参考文献:三角形矩阵求伴随矩阵...
  • c++矩阵求逆的lu分解实现

    千次阅读 2019-12-29 15:21:31
    初学c++,尝试利用基础知识编写矩阵求逆。但发现求解伴随阵的过程非常复杂且难以实现,而我正好看到一篇三角阵伴随矩阵的文章,故尝试编程实现。在这种方法下,计算量明显减小,实现方法,思路适合初学者。 参考...
    c++矩阵求逆的lu分解实现

    初学c++,尝试利用基础知识编写矩阵求逆。但发现求解伴随阵的过程非常复杂且难以实现,而我正好看到一篇求三角阵伴随矩阵的文章,故尝试编程实现。在这种方法下,计算量明显减小,实现方法,思路适合初学者。

    参考文献:三角形矩阵求伴随矩阵的一种方法(曾月新)

    求逆矩阵思路:
    1.求矩阵的crout(LU)分解,其中L为下三角矩阵,U为上三角矩阵
    2.求L,U矩阵的伴随阵,见参考文献
    3.求L,U矩阵的逆(伴随阵A* /det(A))
    4.inv_A = inv_U * inv_L

    附上代码如下:

    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    
    const int n=3;//逆矩阵阶数,求不同阶数矩阵请修改n的值
    int main()
    {
    	double a[n][n],inv_a[n][n];
    	memset(a, 0, n * n * sizeof(double));
    	printf("Please input the %dX%d matrix A:\n",n,n);
    	for (int i = 0; i < n; i++)
    	{
    		for (int j = 0; j < n; j++)
    		{
    			cin>>a[i][j];
    		}
    	}
    	void out(double matrix[][n], const char* s);
    	void product(double matrix1[][n], double matrix2[][n], double matrix_result[n][n]);
    	//初始化
    	double l[n][n], u[n][n], c[n][n], ad_l[n][n], ad_u[n][n];
    	memset(inv_a, 0, n * n * sizeof(double));
    	memset(l, 0, n * n * sizeof(double));
    	memset(u, 0, n * n * sizeof(double));
    	memset(c, 0, n * n * sizeof(double));
    	memset(ad_l, 0, n * n * sizeof(double));
    	memset(ad_u, 0, n * n * sizeof(double));
    	
    
    	//LU分解
    	for (int i = 0; i < n; i++)
    		l[i][i] = 1;
    	for (int i = 0; i < n - 1; i++)
    	{
    		for (int j = i; j < n; j++)
    		{
    			double tem = 0;
    			for (int k = 0; k < i; k++)
    				tem += l[i][k] * u[k][j];
    			u[i][j] = a[i][j] - tem;
    		}
    		for (int j = i + 1; j < n; j++)
    		{
    			double tem = 0;
    			for (int k = 0; k < i; k++)
    				tem += l[j][k] * u[k][i];
    			l[j][i] = (a[j][i] - tem) / u[i][i];
    		}
    	}
    	u[n - 1][n - 1] = a[n - 1][n - 1];
    	for (int i = 0; i < n - 1; i++)
    		u[n - 1][n - 1] -= l[n - 1][i] * u[i][n - 1];
    	//矩阵L
    	//out(l, "矩阵L");
    	//矩阵U
    	//out(u, "矩阵U");
    	//L*U
    	//product(l,u, c);
    	//out(c, "矩阵L*U");
    
    
    	//U的逆矩阵
    	for (int i = 0; i < n; i++)
    	{
    		for (int j = 0; j < n; j++)
    		{
    			if (i > j) ad_u[i][j] = 0;
    			else if (i == j)
    			{
    				ad_u[i][j] = 1;
    				for (int k = 0; k < n; k++)
    					if (k != j)
    						ad_u[i][j] *= u[k][k];
    			}
    			else if (j - i == 1)
    			{
    				ad_u[i][j] = -u[i][j];
    				for (int k = 0; k < n; k++)
    					if (k != i && k != j)
    						ad_u[i][j] *= u[k][k];
    			}
    			else if (j - i >= 2)
    			{
    				double deltas_aii = 1;
    				for (int k = 0; k < n; k++)
    					if (k < i || k > j)
    						deltas_aii *= u[k][k];
    				int permutation[n];
    				for (int t = 0; t < j - i; t++) permutation[t] = i + t + 1;
    				double sum = 0;
    				do
    				{
    					int cnt = 0;
    					for (int t2 = 0; t2 < j - i; t2++)
    						for (int t3 = t2; t3 < j - i; t3++)
    							if (permutation[t3] < permutation[t2]) cnt++;
    					double mul = 1;
    					for (int t1 = i; t1 < j; t1++)
                            mul *= u[t1][permutation[t1 - i]];
    					if ((j - i + 1) % 2 == 0)mul *= -1;
    					if (cnt % 2 == 0) sum += mul;
    					else sum -= mul;
    				} while (next_permutation(permutation, permutation + j - i));
    				ad_u[i][j] = sum * deltas_aii;
    			}
    		}
    	}
    	double det_u = 1;
    	for (int k = 0; k < n; k++) det_u *= u[k][k];
    	if (det_u < 1e-16)
    	{
    		printf("矩阵不可逆,请检查输入!\n");
    		return 0;
    	}
    	for (int i = 0; i < n; i++)
    		for (int j = 0; j < n; j++)
    			ad_u[i][j] /= det_u;
    	//inv_U
    	//out(ad_u, "inv_U");
    	//U*U-1
    	//memset(c, 0, n*n * sizeof(double));
    	//product(u, ad_u, c);
    	//out(c, "矩阵U*U-1");
    
    
    	//l的逆矩阵
    	for (int i = 0; i < n; i++)
    	{
    		for (int j = 0; j < n; j++)
    		{
    			if (i < j) ad_l[i][j] = 0;
    			else if (i == j)
    			{
    				ad_l[i][j] = 1;
    				for (int k = 0; k < n; k++)
    					if (k != j)
    						ad_l[i][j] *= l[k][k];
    			}
    			else if (i - j == 1)
    			{
    				ad_l[i][j] = -l[i][j];
    				for (int k = 0; k < n; k++)
    					if (k != i && k != j)
    						ad_l[i][j] *= l[k][k];
    			}
    			else if (i - j >= 2)
    			{
    				double deltas_aii = 1;
    				for (int k = 0; k < n; k++)
    					if (k < i || k > j)
    						deltas_aii *= l[i][i];
    				int permutation[n];
    				for (int t = 0; t < i - j; t++) permutation[t] = j + t + 1;
    				double sum = 0;
    				do
    				{
    					int cnt = 0;
    					for (int t2 = 0; t2 < i - j; t2++)
    						for (int t3 = t2; t3 < i - j; t3++)
    							if (permutation[t3] < permutation[t2]) cnt++;
    					double mul = 1;
    					for (int t1 = j; t1 < i; t1++) 
                            mul *= l[permutation[t1 - j]][t1];
    					if ((i - j + 1) % 2 == 0)mul *= -1;
    					if (cnt % 2 == 0) sum += mul;
    					else sum -= mul;
    				} while (next_permutation(permutation, permutation + i - j));
    				ad_l[i][j] = sum * deltas_aii;
    			}
    		}
    	}
    	double det_l = 1;
    	for (int k = 0; k < n; k++) det_l *= l[k][k];
    	if (det_u < 1e-16)
    	{
    		printf("矩阵不可逆,请检查输入!\n");
    		return 0;
    	}
    	for (int i = 0; i < n; i++)
    		for (int j = 0; j < n; j++)
    			ad_l[i][j] /= det_l;
    	//矩阵inv_L
    	//out(ad_l, "矩阵inv_L=");
    	//L*L-1
    	//memset(c, 0, n*n * sizeof(double));
    	//product(l, ad_l, c);
    	//out(c, "矩阵L*inv_L=");
    
    
    	//矩阵a
    	out(a, "矩阵a=");
    	//inv_a
    	product(ad_u, ad_l, inv_a);
    	out(inv_a, "逆矩阵inv_a=");
    
    	//验证a*inv_a
    	memset(c, 0, n * n * sizeof(double));
    	product(a, inv_a, c);
    	out(c, "矩阵a*inv_a=");
    
    	system("pause");
    	return 0;
    	
    }
    
    
    
    
    void out(double matrix[][n], const char* s)
    {
    	cout << s << endl;
    	for (int i = 0; i < n; i++)
    	{
    		for (int j = 0; j < n; j++)
    			fabs(*(*(matrix + i) + j))<1e-10? cout << 0 << '\t':cout << *(*(matrix + i) + j) << '\t';
    		cout << endl;
    	}
    	cout << endl;
    }
    
    void product(double matrix1[n][n], double matrix2[n][n], double matrix_result[n][n])
    {
    	for (int i = 0; i < n; i++)
    		for (int j = 0; j < n; j++)
    			for (int k = 0; k < n; k++)
    				matrix_result[i][j] += matrix1[i][k] * matrix2[k][j];
    }
    
    展开全文
  • C++矩阵求逆和相乘函数

    热门讨论 2010-10-12 16:45:15
    用与矩阵求逆和两个矩阵的相乘,还有矩阵的转置和正定矩阵的特殊求逆方法
  • 以及矩阵求广义小知识,分为两个方法实现,一个是Eigen库和自编算法。 最小二乘拟合为发散型题。实现方法千千万,矩阵求逆只是其中一个方法。 20200329主要介绍,Eigen库矩阵求广义方法,后续内容慢慢更新 文章...

    本文涵盖内容:
    基于最小二乘法的空间任意方向的圆柱拟合,
    以及矩阵求广义逆小知识,分为两个方法实现,一个是Eigen库和自编算法。
    最小二乘拟合为发散型题。实现方法千千万,矩阵求逆只是其中一个方法。
    20200329主要介绍,Eigen库矩阵求广义逆方法,后续内容慢慢更新

    1.Eigen库基础知识

    https://blog.csdn.net/caomin1hao/article/details/81358911

    2.Eigen求逆算法

    
    /*
    *
    *   Eigen 求解广义逆
    *
    */
    Eigen::MatrixXd pinv(Eigen::MatrixXf  A)
    {
        Eigen::JacobiSVD<Eigen::MatrixXd> svd(A, Eigen::ComputeFullU | Eigen::ComputeFullV);//M=USV*
        double  pinvtoler = 0.00001; //tolerance
        int row = A.rows();
        int col = A.cols();
    	int k = row>col?col:row;
        //int k = min(row,col);
        Eigen::MatrixXd X = Eigen::MatrixXd::Zero(col,row);
        Eigen::MatrixXd singularValues_inv = svd.singularValues();//奇异值
        Eigen::MatrixXd singularValues_inv_mat = Eigen::MatrixXd::Zero(col, row);
        for (long i = 0; i<k; ++i) {
            if (singularValues_inv(i) > pinvtoler)
                singularValues_inv(i) = 1.0 / singularValues_inv(i);
            else singularValues_inv(i) = 0;
        }
        for (long i = 0; i < k; ++i) 
        {
            singularValues_inv_mat(i, i) = singularValues_inv(i);
        }
        X=(svd.matrixV())*(singularValues_inv_mat)*(svd.matrixU().transpose());//X=VS+U*
    
        return X;
    
    }
    

    3.普通数据与Eigen数据交换

    圆柱面方程
    在这里插入图片描述

    展开全文
  • 这是一篇关于用C++计算矩阵的方法,是自己几天奋斗的结果,从有想法开始到详细的数学证明再到计算机程序的实现以及验证。废话就不多说了,按照我的习惯,这里还是先列出这篇文中的结果,方便对号入座,如不相关...
    这是一篇关于用C++计算矩阵的逆的方法,是自己几天奋斗的结果,从有想法开始到详细的数学证明再到计算机程序的实现以及验证。废话就不多说了,按照我的习惯,这里还是先列出这篇文中的结果,方便对号入座,如不相关那就赶紧换一个把:
    

              1.一种容易实现的矩阵求逆算法,且可以判断矩阵是否可逆;

              2.这种算法支持数据的动态增长,例如,最小二乘中计算(X’X)^-1时当来一个新数据时,可以通过简单地计算得到最后的逆矩阵,而不必从头开始。

              3.数学上论证了正确性,并给处计算和测试程序

              4.关于该问题在矩阵乘法上的扩展

    这里如果读者知道一点OenpCV或者matlab会很有裨益的,当然不知道也没有关系,只是如果你要实现它的话你还要实现矩阵的乘法和数乘两种运算就好,有人可能会问数乘是什么,数乘就是矩阵和一个实数相乘,也就是矩阵的每一个元素都乘上该实数,当然一种结构来存储该矩阵也是必要的,最好写个类。

            那么这里可能会问,我都会使用OpenCV(matlab)求个逆还不就是inv(),也就是一行代码的事而已,何必还要在这里看你在这里罗嗦!注意这里如下几个原因让你看下去:

              首先这里只使用OpenCV中的Mat 的较好的封装结构,而这不只必要的,正如前面介绍的那么样逆大可自己实现拥有那两个操作的数据结构,而不必借助于OpenCV或matlab.这里我使用它只要是因为我是做计算机视觉的电脑上自然安装了OpenCV库,而且也是为了方便。

              再来就是,这里本着的是,知其然,还要知其所以然的原则(当然我并不知道OpenCV和matlab到底是这样实现求逆的,但是对于本文中的方法我是清楚的),还因该方法实现简单,编码量少。

              这里,也是为了交流的目的,后面会提到本文的中的一些扩展可自己的一些想法,希望与各位交流。

              好了!不多说了,直接先上程序:

    bool invMat(Mat origMat, Mat& invert)//对origMat求逆,并将结果返回到invert中
    {
    	Size sz=origMat.size();
    	if(sz.height!=sz.width||origMat.depth()!=CV_64F) //这里只处理double类型的方阵
    	  return 0; 
    	double disc;// 用于记录中间的变量,还有一个作用是判别矩阵是否可逆
    	Mat I=Mat::eye(sz,origMat.type());
    	Mat D=origMat-I;
    	Mat temp;
    	disc=1+D.at<double>(0,0);
    	if(abs(disc)<1e-12) // 认为小于1e-12为0,这里可以根据个人习惯可运用需要来定
    	  return 0; // 矩阵不可逆
    	else
    	{
    		Mat invCk(I-(1/disc)*(I.col(0)*D.row(0)));
    		for(long step=1;step<sz.height;step++)
    		{
    			temp=D.row(step)*invCk;
    			disc=1+temp.at<double>(0,step);
    			if(abs(disc)<1e-12) // 同上
    			  return 0;// 同前意义
    			else
    			  invCk=invCk-(invCk.col(step)*temp)/disc;
    		}
    		invert=invCk.clone(); // 拷贝到目标Matrix中;
    	}
    	return 1;
    }
    其中Mat就是OpenCV中的矩阵类,不知道的读者就理解为封装了矩阵操作的类就好。

    你可能会问这是啥!我说这就是矩阵求逆的算法,详细证明如下(其实它就是一个迭代过程,也就是下面证明的结论部分——两句话):

    这里以截图的形式给出(之前是写在word中的),方便阅读:

    这里先给出矩阵的求逆引理,及其推论:





    关于矩阵引理的一个简单的证明,帮我把他放在后面,或者你也可以在矩阵论的相关书籍中找到他的证明,下面将要给出的就是上面的代码的数学支持(注:I为单位阵):




    最后的迭代公式就是上面的程序的核心,这里就得到了矩阵的逆,此外这里利用这个思想我们还可以对最小二乘中矩阵运算有所改进:




    也就是说我们不需要重新计算,只需要再一次的迭代的就可以得到新的矩阵了,时间复杂度为O(n*n).

    到这里我已经证明的结果就全都放在这里了,下面是我的一些想法,也是写这篇文章的另一个目的:与诸位探讨一下可能的性能提升以及其他一些问题。

    首先,可以看到的是无论是一般的矩阵求逆还是最小二乘中,每次迭代都会涉及到一个矩阵与一个向量的乘积也即是上面的,同时还有就是一个列向量与一个行向量相乘得到一个矩阵的情形,两者的时间复杂度都为O(n*n),但是两者的计算过程都很简单,尤其是后者,所以一个问题就是可否利用加速的矩阵乘法对上述算法进行加速?

    其次,如果上面的问题解决了那么,对矩阵的乘法的算法也会有相应的影响,因为:




    对应于第一种情况。而:




    对应第二种情况,所以无论哪一种情况解决了,都会对矩阵的乘法有提高,当然这也是我一直纠结的问题,而且从这里可以看出,上面的算法的时间复杂度其实与矩阵乘法的时间复杂度相当。

    最后还有一点猜想,学过矩阵论的人都知道,其实矩阵的逆与矩阵的特征值是有很大的关系的,所以这里猜想这对矩阵特征值的计算会不会有帮助,当然这里说了只是猜想,依据不足仅供参考。

    好了!写到这里该总结了:这里的结果其实有点像是习题的结果,完全是自己一个人在下面慢慢弄的,当然我也不知道,是否有其他人证明过相关的结论,因为我目前尚未见到,所以才写了这篇文章,倘若已经有人证明过得话,那就当我是孤陋寡闻,班门弄斧了。不过这里我保证是我原创的。


    附录:矩阵引理+测试代码:





    测试代码:

    #ifndef    INVMATRIX_CPP
    #define    INVMATRIX_CPP
    
    #ifndef    INCLUDE_OPENCV2_CORE
    #define    INCLUDE_OPENCV2_CORE
    #include   "opencv2/core/core.hpp"
    #endif
    #include   <iostream>
    #include   <iomanip>
    #include   <cmath>
    
    using namespace std;
    using namespace cv;
    
    void printMat(Mat & m,int precision)// 打印矩阵到屏幕上,且指明精度
    {
    	Size sz=m.size();
    	int i,j;
    	for(i=0;i<sz.height;i++)
    	{
    		for(j=0;j<sz.width;j++)
    		{
    			if(abs(m.at<double>(i,j)<1e-12)) // 将绝对值小于e-12 的数视为0,可自行决定
    			  cout<<0<<"  ";
    			else
    			  cout<<setprecision(precision)<<m.at<double>(i,j)<<"  ";
    		}
    		cout<<endl;
    	}
    }
    
    bool invMat(Mat origMat, Mat& invert)// 这就是上面的算法
    {
    	Size sz=origMat.size();
    	if(sz.height!=sz.width||origMat.depth()!=CV_64F) // 只处理double型的方阵
    	  return 0; 
    	double disc;//记录中间量,并作判别之用
    	Mat I=Mat::eye(sz,origMat.type());
    	Mat D=origMat-I;
    	Mat temp;
    	disc=1+D.at<double>(0,0);
    	if(abs(disc)<1e-12) // 同上
    	  return 0; // 矩阵不可逆
    	else
    	{
    		Mat invCk(I-(1/disc)*(I.col(0)*D.row(0)));
    		for(long step=1;step<sz.height;step++)
    		{
    			temp=D.row(step)*invCk;
    			disc=1+temp.at<double>(0,step);
    			if(abs(disc)<1e-12) // 同上
    			  return 0;// 同上
    			else
    			  invCk=invCk-(invCk.col(step)*temp)/disc;
    		}
    		invert=invCk.clone(); 
    	}
    	return 1;
    }
    
    int main(int argc, char *argv[])
    {
    	RNG rng(1234567);
    	Mat src(26,26,CV_64FC1),dst; //26是我自己选的,你可以用其他的数字
    	rng.fill(src,RNG::UNIFORM,Scalar(-100),Scalar(100));//用 -100~100之间的数随机填充矩阵 
    	cout<<" 原始矩阵:"<<endl;
    		printMat(src,4);
    	if(!invMat(src,dst))
    	  cout<<"错误!矩阵不可逆"<<endl;
    	else
    	{
    		cout<<"其逆矩阵为:"<<endl;
    			printMat(dst,4);
    	}
    	Mat re=src*dst;
    	cout<<"看看两者的乘积:"<<endl;
    		printMat(re,4);
    	return 0;
    }
    
    #endif    /*INVMATRIX_CPP*/

    展开全文
  • 矩阵求逆c++实现

    万次阅读 多人点赞 2014-05-02 08:53:44
    矩阵求逆c++实现
  • 矩阵求逆c++.

    2013-11-25 10:04:54
    矩阵求逆模块 c++语言学习资料
  • C++实现复数矩阵求逆 matlab inv

    千次阅读 2020-07-06 11:10:57
    C++实现复数矩阵求逆 matlab inv一、引言二、原理2.1 实数矩阵求逆2.2 复数矩阵求逆三、代码四、测试 一、引言 之前偶尔一次有用到将matlab转为C++语言的需求,其中matlab有一个inv函数可以非常方便的求矩阵,...
  • 矩阵求逆C++代码

    2012-12-16 08:25:02
    C++代码编写高等代数中矩阵求逆的计算,
  • 矩阵求逆C++代码

    2012-07-02 18:14:10
    C++写的矩阵求逆的代码,输入维数和矩阵,利用矩阵初等变换求逆矩阵,代码比较精简。
  • C++矩阵求逆

    万次阅读 2015-11-01 21:28:52
    systemvue是一款专用的雷达,通信仿真软件,其底层的封装的模块库是用c++写的。 听博士哥哥说该软件目前处于推广阶段,由于目前模块库匮乏,所以比较...最近接到博士哥哥的一个任务,让我写一个矩阵求逆的模块,
  • 本程序用于复数矩阵求逆,用到了高斯-乔丹法,刚写好的分享给大家
  • 矩阵求逆迭代法

    2014-05-24 10:18:49
    C++ 矩阵求逆 可以定义多维矩阵,通过代数余子式的方式来计算矩阵
  • C++三阶矩阵求逆矩阵

    千次阅读 2020-07-26 22:05:02
    //三阶矩阵求逆矩阵 //=================== #include <stdio.h> #include <math.h> #include <stdlib.h> #include <iostream> #include <fstream> #include<string> #include&...
  • 测量平差课上可以用到,用C++写的能任意阶的矩阵的程序,有错误检查的过程,能检查是否存在!
  • c++求矩阵

    2012-08-10 11:37:10
    c++求矩阵.。
  • 矩阵求行列式、伴随矩阵逆矩阵 这是通过行列式和伴随矩阵求逆矩阵的方法,分别将行列式、伴随矩阵的功能提取了出来, 逆矩阵 等于伴随矩阵/行列式。如果你想学习如何对矩阵求逆, 可以仔细阅读这篇文章,代码很好...
  • C++语言实现的矩阵求逆,经典算法,矩阵大小可以修改,欢迎点评
  • 基于C++语言的高斯消元法矩阵求逆运算,在Visual Stdio 2015中调试通过,希望对大家有所帮助!
  • 矩阵求逆c++

    千次阅读 2017-09-21 17:55:10
    矩阵求逆c++)标签(空格分隔): 技术博客简要过程介绍方法的名称是“Gauss-Jordan (or reduced row) elimination method”。设单位对角矩阵为I,则MM−1=IMM^{-1}=I主要过程为,摆一个相同大小的对角矩阵在旁边...
  • 矩阵求逆C++源代码

    2010-03-08 15:03:29
    矩阵求逆的经典C程序实现,数据结构利用数组。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,676
精华内容 3,470
关键字:

c++矩阵求逆

c++ 订阅