Java进阶(四十九)实现矩阵秩的求解-转置-行列式-逆矩阵操作

应论文需求,需要计算矩阵的逆矩阵。相应的矩阵操作工具类如下:

package cn.edu.ujn.paper.matrix;

public class MatrixUtil {
	
    /**
     * 实现矩阵相乘 (AB)
     * @param a 矩阵A
     * @param b 矩阵B
     */
    private static double[][] matrixMulti(double[][] a,double[][] b){
 
    	double c[][] = new double[a.length][b[0].length];
          
        int x,i,j;
        for(i = 0;i<a.length ;i++)
        {  
            for(j = 0;j<b[0].length;j++)
            {  
                int temp = 0;
                for(x = 0;x<b.length;x++)
                {  
                    temp+=a[i][x]*b[x][j];
                      
                }  
                c[i][j] = temp;
                  
            }  
        }  
        System.out.println("矩阵相乘后结果为:");  
        for(int m = 0; m < a.length; m++)  
        {  
            for(int n = 0; n < b[0].length; n++)  
            {  
                System.out.print(c[m][n]+"\t");
            }  
            System.out.println();  
        }
        
        MatrixUtil.getHL(c);
        
		return c;  
    }
    
	/**
	 * 矩阵打印
	 * @param matrix 矩阵
	 * @param r 行
	 * @param c 列
	 */
	public static void printMatrix(double[][] matrix, int r, int c){
		System.out.println("打印矩阵:");
		String Strr = new String("");
		for (int i = 0; i < r; i++) {
			for (int j = 0; j < c; j++) {
				String str = String.valueOf(matrix[i][j]);
				Strr += str;
				Strr += "\t";
			}
			Strr += "\n";
		}
		
		System.out.println(Strr);
	}
	
	/**
	 * 求解代数余子式
	 * @param data 原始矩阵
	 * @param h 待求解元素的行
	 * @param v 待求解元素的列
	 * @return
	 */
    public static double[][] getDY(double[][] data, int h, int v) {  
        int H = data.length;  
        int V = data[0].length;  
        
        double[][] newData = new double[H - 1][V - 1];  
  
        for (int i = 0; i < newData.length; i++) {
  
            if (i < h - 1) {  
                for (int j = 0; j < newData[i].length; j++) {
                    if (j < v - 1) {
                        newData[i][j] = data[i][j];
                    } else {
                        newData[i][j] = data[i][j + 1];
                    }
                }
            } else {
                for (int j = 0; j < newData[i].length; j++) {
                    if (j < v - 1) {
                        newData[i][j] = data[i + 1][j];
                    } else {
                        newData[i][j] = data[i + 1][j + 1];
                    }
                }
  
            }
        }
        
//        System.out.println("---------------------代数余子式测试---------------------------------");
        
/*        for(int i = 0; i < newData.length; i++){  
        	for(int j = 0; j < newData[i].length; j++){  
        		System.out.print("newData[" + i + "]" + "[" + j + "]=" + newData[i][j] + "   ");  
        	}  
          
        	System.out.println();  
         }*/
  
        return newData;  
    }  	
	
	/** 
     * 求解行列式的模
     *  
     * @param data 
     * @return float
     */  
    public static double getHL(double[][] data) {  
  
        // 终止条件  
        if (data.length == 2) {
            return data[0][0] * data[1][1] - data[0][1] * data[1][0];
        }
        
        if (data.length == 1) {
            return data[0][0];
        }
  
        double total = 0;
        // 根据data 得到行列式的行数和列数
        int num = data.length;
        // 创建一个大小为num 的数组存放对应的展开行中元素求的的值
        double[] nums = new double[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;  
    }  
    
    /** 
     * 取得转置矩阵 
     * @param A 
     * @return float[][] 
     */  
    public static double[][] getA_T(double[][] A) {  
        int h = A.length;  
        int v = A[0].length;  
        // 创建和A行和列相反的转置矩阵  
        double[][] A_T = new double[v][h];  
        // 根据A取得转置矩阵A_T  
        for (int i = 0; i < h; i++) {  
            for (int j = 0; j < v; j++) {  
                A_T[j][i] = A[i][j];  
            }  
        }  
//        System.out.println("取得转置矩阵  wanbi........");
        return A_T;  
    }  
    
    /** 
     * 求解逆矩阵
     *  
     * @param data 
     * @return 
     */  
    public static double[][] getReverseMatrix(double[][] data) {
    	
        // 1.求出行列式的模|data|  
    	double m = getHL(data);  
    	
    	// 若行列式的值为0,则表明逆矩阵不存在
    	if(Arith.compareTo(m, 0) == 0){
    		System.out.println("----------------行列式的模为0,逆矩阵不存在-----------------");
    		return null;
    	}
    	
    	if(m == 0){
    		
    	}
    	
    	System.out.println("行列式:" + m);
    	
        // 创建一个等容量的逆矩阵  
    	double[][] newData = new double[data.length][data.length];
  
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data.length; j++) {
            	double 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 / m;
            }
        }
  
        // 2.转置代数余子式
        newData = getA_T(newData);
        
        // 打印
        System.out.println("逆矩阵:");
        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 Matrix 矩阵
     * @param error_
     * @param List
     * @return
     */
    public static int Rank(double[][] Matrix, int error_, int List)  
    {  
        int n = List;  
        int m = Matrix.length ;  
        int i = 0;  
        int j = 0;  
        int i1, j1;  
        double temp1;
        
        if(m > n)  
        {  
            i = m;
            m = n;
            n = i;
            i = 1;
        }
        
        m -= 1;  
        n -= 1;
        
        double[][]temp = new double[m+1][n+1];
        
        if(i == 0)  
        {
          for(i = 0; i <= m; i++)  
          {
              for(j = 0; j <= n; j++)  
              {  
                  temp[i][j] = Matrix[i][j];  
              }
          }
        } else  
        {  
            for(i = 0; i <= m; i++)  
            {  
                for(j = 0; j <= n; j++)  
                {  
                    temp[i][j] = Matrix[j][i];  
                }
            }  
        }  
        
        if(m == 0)  
        {  
            i = 0;  
            while(i <= n)  
            {  
                if(Matrix[0][i] != 0)  
                {  
                    return 1;  
                }  
                i += 1;  
            }  
            return 0;
        }
        
        double error0;
        if(error_ == -1)  
        {  
            error0 = Math.pow(0.1, 10);
        }  
        else  
        {  
            error0 = Math.pow(0.1, error_);  
        }  
        
        i = 0;
        
        while(i <= m)
        {
            j = 0;
            while(j <= n)
            {
                if(temp[i][j] != 0)
                {
                    error0 *= temp[i][j];
                    i = m;
                    break;
                }
                j += 1;
            }
            i += 1;
        }
        
        double error1;
        for(i = 0; i <= m; i++)
        {  
            j = 0;  
            while(j <= n)  
            {  
                if(temp[i][j] != 0)  
                {  
                    break;  
                }  
                j += 1;
            }
            
            if(j <= n)
            {
                i1 = 0;  
                while(i1 <= m)  
                {  
                    if(temp[i1][j] != 0 && i1 != i)
                    {
                        temp1 = temp[i][j]/temp[i1][j];
                        error1 = Math.abs((temp[i][j] - temp[i1][j]*temp1))*100;
                        error1 += error0;
                        for(j1 = 0; j1 <= n; j1++)
                        {  
                            temp[i1][j1] = temp[i][j1] - temp[i1][j1]*temp1;  
                            if(Math.abs(temp[i1][j1]) < error1)  
                            {  
                                temp[i1][j1] = 0;
                            }  
                        }  
                    }
                    i1 += 1;
                }
            }
        }
          
        i1 = 0;
        for(i = 0; i <= m; i++)
        {
            for(j = 0; j <= n; j++)  
            {  
                if(temp[i][j] != 0)
                {  
                    i1 += 1;
                    break;
                }
            }
        }
        return i1;
    }
	
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

No Silver Bullet

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值