OpenCv Java Mat的基本使用-行列式计算(6)

矩阵在形式上和行列式是一样 的,这两天看Mat,想起之前学历的行列式,那么我们如何求解一个矩阵对应的行列式的求解方法

行列式计算:

最简单的二维的行列式:

     哈哈,上面是一个简单的计算的规则,希望你勾起你的青春的回忆

当然上面是二维和三维的,还有四维的甚至更高维度的

我们大概总结出来就是:某一行或者是某一列中的每一个元素乘以其对应的代数余子式的和

如何来求解代数余子式:

某一个元素对应的代数余子式,就是去掉这个元素所在的行和列,得到的行列式,称为改元素的代数余子式

代码:

首先我们使用Mat类创建一个矩阵:

创建上面的一个3x3的矩阵

\begin{bmatrix} 1 & 2 & 3\\ 4& 5 & 6\\ 7 & 8 & 9 \end{bmatrix}

首先我们求解a_i_j的代数余子式M_i_j

private static Mat Detsub(Mat mat, int i, int j) {
		// 删除行
		int rows = mat.rows();
		int cols = mat.cols();

		Mat tmp = mat.submat(0, i, 0, cols);

		Mat mat_result = mat.submat(i + 1, rows, 0, cols);

		tmp.push_back(mat_result);

        //删除列
		tmp = tmp.t();
		mat_result = tmp.submat(0, j, 0, rows - 1);
		tmp = tmp.submat(j + 1, cols, 0, rows - 1);
		mat_result.push_back(tmp);
		tmp.release();
		return mat_result.t();
	}

然后递归计算:

	// 矩阵行列式求值
	public static double Det(Mat mat) {
		// 单通道
		if (mat.channels() > 1) {
			throw new RuntimeException("Mat 对应的通道必须单通道");
		}
		// 并且是方阵
		if (mat.rows() != mat.cols()) {
			throw new RuntimeException("Mat 必须是方阵");
		}
		double sum = 0.0;
		// 矩阵的维度,也就是矩阵对应的行列式化简之后的结果
		if (mat.size().height == 2) {
			return mat.get(0, 0)[0] * mat.get(1, 1)[0] - mat.get(0, 1)[0] * mat.get(1, 0)[0];
		}

		for (int col = 0; col < mat.size().height; col++) {
			double a = mat.get(0, col)[0];
			if (col % 2 == 0) {

				double one = Det(Detsub(mat, 0, col));
				sum += a * one;
			} else {

				double two = Det(Detsub(mat, 0, col));
				sum -= a * two;
			}
		}

		return sum;

	}

 开始计算:测试1

测试2:

 

 为了检验结果的正确性,我从网上找了一个二维数组的列子,求解行列式值的例子:


class aij {
	// A函数可用于求余子阵
	int[][] A(int[][] a, int row, int column) {
		int[][] ans = new int[a.length - 1][a.length - 1];// ans用于储存返回的最终结果
		int[] temp = new int[(a.length - 1) * (a.length - 1)];// 临时一维数组temp用于按顺序储存剔除相应行和列元素后的数组
		int k = 0;
		// 剔除行和列并按顺序储存到temp内
		for (int i = 0; i < a.length; i++) {
			for (int j = 0; j < a[i].length; j++) {
				if (i == row - 1) {
					continue;
				} else if (j == column - 1) {
					continue;
				}
				temp[k++] = a[i][j];
			}
		}
		// 按顺序从temp中读取数据并储存到ans内
		k = 0;
		for (int i = 0; i < ans.length; i++) {
			for (int j = 0; j < ans[i].length; j++) {
				ans[i][j] = temp[k++];
			}
		}
		return ans;
	}

	// det用于求行列式
	int det(int[][] a) {
		if (a.length == 1) {
			return a[0][0];
		} else {
			int ans = 0;
			for (int i = 0; i < a.length; i++) {
				ans += a[i][0] * (int) Math.pow(-1, i) * det(A(a, i + 1, 1));
			}
			return ans;
		}
	}
}

 可以看到的是两次的计算结果是一样的

 希望对你有所帮助

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值