查了java实现逆矩阵变换的代码,竟然很少发现。 想偷懒也不行。 关于矩阵的基本运算:加减法,矩阵倒排,相当简单,可以看到很多别人写的东西,但是看不到逆矩阵,很不舒服。
自己实现逆矩阵功能,可以是任意的n阶矩阵。
由于它不熟悉矩阵,所以代码具有思维的逻辑性,因为代码从0开始,到最后实现,每一步都呈现思维代码。
分为两步:
的逆矩阵=A*/|A|;
1:请求A*
2:要求|A|
随着矩阵A*的实现,采用代数馀数公式。 实现比较简单
//*
* 1
求解代数馀数公式的输入:原矩阵矩阵的现实真行数和列数
*/
公共静态浮动[ ] [ ] get dy (浮动[ ] [ ] data,int h,int v ) {
int H=data.length;
int V=data[0].length;
float [ ] [ ] new data=newfloat [ h-1 ] [ v-1 ];
for(intI=0; i newData.length; I ) {
if(Ih-1 ) {
for(intj=0; j newData[i].length; j ) {
if(jv-1 ) {
newData[i][j]=data[i][j];
} else {
newData[i][j]=data[i][j 1];
}
}
} else {
for(intj=0; j newData[i].length; j ) {
if(jv-1 ) {
newData[i][j]=data[i 1][j];
} else {
newData[i][j]=data[i 1][j 1];
}
}
}
}
//system.out.println------------------------代数残子表达式测试
//for(intI=0; I
//for(intj=0; Jj
//system.out.print (' new data [ ' I ' ] ' [ ' j ' ]=' new data [ I ] [ j ] ' );
//}
//
//System.out.println (;
//}
返回新数据;
}
写了这个代数馀数式后,就要计算那个行列式的值。
行列式沿行和列展开,一定具有递归意义。 但是,与平时写的不同,由于循环太多,不知道位置,所以依次实现了2次、3次、4次、5次行列式,并进行了测试,用归纳法找到了正确的实现位置。
二楼
//*
* 2
*求二次行列式的数值
* @param data
* @return
*/
publicstaticfloatgethl2(float [ ] [ ] data ) {
//data必须是2*2的数组
浮动编号1=data [0] [0] * data [1] [1];
浮动编号2=-data [0] [1] * data [1] [0];
返回编号1编号2;
}
第三步
//*
*求三阶行列式的数值
*
* @param data
* @return
*/
publicstaticfloatgethl3(float [ ] [ ] data ) {
float num1=data [0] [0] * gethl2(get dy (数据,1,1 ) );
float num2=-data [0] [1] * gethl2(get dy (数据,1,2 );
float num3=data [0] [2] * gethl2(get dy (数据,1,3 ) );
//system.out.println(----'num1);
//system.out.println(----'num2);
//system.out.println(----'num3);
system.out.println('3阶行列式的数值为--------'(n
um1 + num2 + num3));return num1 + num2 + num3;
}
4阶
/**
* 求4阶行列式的数值
*
* @param data
* @return
*/
public static float getHL4(float[][] data) {
float num1 = data[0][0] * getHL3(getDY(data, 1, 1));
float num2 = -data[0][1] * getHL3(getDY(data, 1, 2));
float num3 = data[0][2] * getHL3(getDY(data, 1, 3));
float num4 = -data[0][3] * getHL3(getDY(data, 1, 4));
// System.out.println("--------->"+num1);
// System.out.println("--------->"+num2);
// System.out.println("--------->"+num3);
// System.out.println("--------->"+num4);
// System.out.println("4阶行列式的数值------->"+(num1+num2+num3+num4));
return num1 + num2 + num3 + num4;
}
5阶
/**
* 求5阶行列式的数值
*/
public static float getHL5(float[][] data) {
float num1 = data[0][0] * getHL4(getDY(data, 1, 1));
float num2 = -data[0][1] * getHL4(getDY(data, 1, 2));
float num3 = data[0][2] * getHL4(getDY(data, 1, 3));
float num4 = -data[0][3] * getHL4(getDY(data, 1, 4));
float num5 = data[0][4] * getHL4(getDY(data, 1, 5));
System.out.println("5 阶行列式的数值是: ------->"
+ (num1 + num2 + num3 + num4 + num5));
return num1 + num2 + num3 + num4 + num5;
}
最终的归纳是:
/**
* 求解行列式的模----------->最终的总结归纳
*
* @param data
* @return
*/
public static float getHL(float[][] data) {
// 终止条件
if (data.length == 2) {
return data[0][0] * data[1][1] - data[0][1] * data[1][0];
}
float total = 0;
// 根据data 得到行列式的行数和列数
int num = data.length;
// 创建一个大小为num 的数组存放对应的展开行中元素求的的值
float[] nums = new float[num];
for (int i = 0; i < num; i++) {
if (i % 2 == 0) {
nums[i] = data[0][i] * getHL(getDY(data, 1, i + 1));
} else {
nums[i] = -data[0][i] * getHL(getDY(data, 1, i + 1));
}
}
for (int i = 0; i < num; i++) {
total += nums[i];
}
System.out.println("total=" + total);
return total;
}
上面用到的是归纳。
实现了行列式求值还没完,下面才是求逆矩阵:
/**
* 求解3阶矩阵的逆矩阵
* @param data
* @return
*/
public static float[][] getN3(float[][] data) {
// 先是求出整个行列式的数值|A|
float A = getHL3(data);
float[][] newData = new float[3][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
float num;
if ((i + j) % 2 == 0) {// i+j 是偶数 实际是(i+1)+(j+1)
num = getHL2(getDY(data, i + 1, j + 1));
} else {
num = -getHL2(getDY(data, i + 1, j + 1));
}
System.out.println("num=" + num);
newData[i][j] = num / A;
}
}
// 再转制
newData = getA_T(newData);
// 打印
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
System.out.print("newData[" + i + "][" + j + "]= "
+ newData[i][j] + " ");
}
System.out.println();
}
return newData;
}
最终的结果是:
/**
* 求解逆矩阵------>z最后的总结和归纳
*
* @param data
* @return
*/
public static float[][] getN(float[][] data) {
// 先是求出行列式的模|data|
float A = getHL(data);
// 创建一个等容量的逆矩阵
float[][] newData = new float[data.length][data.length];
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data.length; j++) {
float num;
if ((i + j) % 2 == 0) {
num = getHL(getDY(data, i + 1, j + 1));
} else {
num = -getHL(getDY(data, i + 1, j + 1));
}
newData[i][j] = num / A;
}
}
// 转置 代数余子式转制
newData = getA_T(newData);
// 打印
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data.length; j++) {
System.out.print("newData[" + i + "][" + j + "]= "
+ newData[i][j] + " ");
}
System.out.println();
}
return newData;
}
会用到转置矩阵,代码较为简单:
/**
* 取得转置矩阵
* @param A
* @return
*/
public static float[][] getA_T(float[][] A) {
int h = A.length;
int v = A[0].length;
// 创建和A行和列相反的转置矩阵
float[][] A_T = new float[v][h];
// 根据A取得转置矩阵A_T
for (int i = 0; i < v; i++) {
for (int j = 0; j < h; j++) {
A_T[j][i] = A[i][j];
}
}
System.out.println("取得转置矩阵 wanbi........");
return A_T;
}
下面是自己的测试:
/**
* @param args
*/
public static void main(String[] args) {
MartrixTest t = new MartrixTest();
// t.getDY(data6, 2, 3);
// getHL3(data3);
// getHL4(data4);
// getHL5(data5);
// getN3(data3);
// getHL(data5);
getN(data3);
}
static float[][] data6 = { { 1, 2, 3, 4, 5, 6 },
{ 1, 2, 3, 4, 5, 6 },
{ 3, 4, 3, 2, 2, 1 },
{ 1, 2, 3, 4, 5, 6 },
{ 1, 2, 3, 4, 5, 6 },
{ 1, 2, 3, 4, 5, 6 },
};
static float[][] data5 = { { 1, 2, 3, 4, 5 },
{ 2, 3, 4, 5, 1 },
{ 3, 4, 5, 1, 2 },
{ 4, 5, 1, 2, 3 },
{ 5, 1, 2, 3, 4 },
};
static float[][] data4 = { { 1, 0, -1, 2 },
{ -2, 1, 3, 1 },
{ 0, 2, 0, -2 },
{ 1, 3, 4, -2 },
};
static float[][] data3 = { {1,2,-1 },
{3,1,0 },
{-1,-1,-2 }, };
测试了5阶的,结果和课本例题其他解法结果相同。把摄影测量的图像处理原理和矩阵都学了下,搞了2天还是蛮爽的。
分享到:
2011-10-31 12:30
浏览 14851
评论