Java实现计算矩阵的伴随矩阵、逆矩阵

Java实现计算矩阵的伴随矩阵、逆矩阵

基本类代码

Matrix

Phalanx

Matrixs

RowLineFormula

测试

简单使用

由于需要用到行列式的运算与矩阵间的运算的原因,代码会有点多.

首先需要一个及矩阵的类Matrix,命名为Matrix.


import java.util.Arrays;

/**
 * @author yiran
 * @creat 2021-11-26-13:58
 */
public class Matrix{

    // 矩阵
    private double[][] matrix;
    private int m;
    private int n;

    public double[][] getMatrix() {
        return matrix;
    }


    public Matrix() {

    }


    public Matrix(double[][] matrix) {
        this.matrix = matrix;
        this.m=matrix.length;
        this.n=matrix[0].length;
    }

    public Matrix(int m, int n) {
        this.matrix=new double[m][n];
        this.m=m;
        this.n=n;
    }

    public void setMatrix(double[][] matrix) {
        this.matrix = matrix;
        this.m=matrix.length;
        this.n=matrix[0].length;
    }

    public int getM() {
        return m;
    }

    public void setM(int m) {
        this.m = m;
    }

    public int getN() {
        return n;
    }

    public void setN(int n) {
        this.n = n;
    }

    public void print()
    {
        System.out.println("------------------结果-------------------");
        for (int i=0;i<m;i++)
        {
            for (int j=0;j<n;j++)
            {
                System.out.print(matrix[i][j]+"    ");
            }
            System.out.println();
        }
        System.out.println("----------------------------------------");
    }

    @Override
    public String toString() {
        return "Matrix{" +
                "matrix=" + Arrays.toString(matrix) +
                '}';
    }
}

还需要一个方阵的Phalanx类(由于求伴随矩阵和逆矩阵的前提是矩阵的方阵).
命名为Phalanx.


/**
 * @author yiran
 * @creat 2021-11-26-14:01
 */
public class Phalanx extends Matrix {

    // 调用父类的构造函数,构造方阵
    public Phalanx(int n) {
        super(n, n);
    }

    public Phalanx() {
    }

    // 初始化方阵,并进行校验
    public Phalanx(double[][] matrix) {
        if(matrix.length!=matrix[0].length)
        {
            // 传入参数不符合方阵的要求
            System.out.println("初始化失败:传入参数不符合方阵的要求!");
        }
        else
        {
            this.setMatrix(matrix);
        }

    }

    public double[][] getPhalanx() {
        return getMatrix();
    }


    public void setPhalanx(double [][] phalanx) {
        if(phalanx.length!=phalanx[0].length)
        {
            // 传入参数不符合方阵的要求
            System.out.println("初始化失败:传入参数不符合方阵的要求!");
        }
        else
        {
            super.setMatrix(phalanx);
        }

    }

}

之后是操作矩阵运算的工具类Matrixs.


/**
 * 方阵的辅助类
 * @author yiran
 * @creat 2021-11-26-14:08
 */
public class Matrixs{

  
  
    // 矩阵转置
    public static Matrix reverse(Matrix m)
    {
        if(m!=null)
        {
            Matrix new_m=new Matrix();
            double[][] m_data = m.getMatrix();
            double[][] new_m_data=new double[m.getN()][m.getM()];
            for (int i=0;i<m.getN();i++)
            {
                for (int  j=0;j<m.getM();j++)
                {
                    new_m_data[i][j]=m_data[j][i];
                }
            }

            m.setMatrix(new_m_data);
            return m;

        }
        return null;
    }

    // 矩阵数乘
    public static Matrix numtil(Matrix m,double num)
    {
        if(m!=null)
        {
            Matrix new_m=new Matrix();
            double[][] m_data = m.getMatrix();
            double[][] new_m_data=new double[m.getM()][m.getN()];
            for (int i=0;i<m.getM();i++)
            {
                for (int  j=0;j<m.getN();j++)
                {
                    new_m_data[i][j] = num * m_data[i][j];
                }
            }

            new_m.setMatrix(new_m_data);
            return new_m;

        }
        return null;
    }


    

   /**
     *
     * @param origin  矩阵数组
     * @param i
     * @param j
     * @return  矩阵对应 i,j 位置的余子式
     */
    public static double[][] getLess(double [][] origin,int i,int j)
    {
        if (origin!=null)
        {
            int c_i=i-1;
            int c_j = j-1;

            int n = origin.length;
            // 取出余子式
            double[][] newArr = new double[n - 1][n - 1];
            int index_i = 0;
            // 对数组进行赋值
            for (int l = 0; l < n; l++) {
                // 如果该行不等于所在行
                if (c_i != l) {
                    int index_j = 0;
                    for (int o = 0; o < n; o++) {
                        // 列不等该列
                        if (c_j != o)
                        {
                            newArr[index_i][index_j] = origin[l][o];
                            index_j++;
                        }
                    }
                    // 到第下一行赋值
                    index_i++;
                }
            }
            return newArr;
        }

        return null;
    }

    // 求方阵的伴随矩阵
    public static Phalanx getAccompany(Phalanx p)
    {

        if (p!=null)
        {
            // 用于存储伴随矩阵的数据
            double[][] pMatrix = p.getMatrix();
            int n = p.getN();
            double [][] new_p=new double[n][n];
            // 调用递归算法将余子式算出
            if(n>2)
            {
                for (int i = 0; i< n; i++)
                {
                    for (int j=0;j<n;j++)
                    {
                        // 取出来余子项,并进行传参并代入代数余子式
                        new_p[i][j] = Math.pow(-1,(1+1+i+j))*RowLineFormula.interf(new Phalanx(getLess(pMatrix,i+1,j+1)));
                    }

                }
            }else
            {
                // 仅对二阶的进行特殊处理,不要进行转置
                if (n==2)
                {
                    new_p[0][0] = pMatrix[1][1];
                    new_p[0][1] = -1*pMatrix[1][0];
                    new_p[1][0] = -1*pMatrix[0][1];
                    new_p[1][1] = pMatrix[0][0];

                }
            }

            // 得到了矩阵后还要将其反转才得到伴随矩阵
            return (Phalanx) Matrixs.reverse(new Phalanx(new_p));

        }
        else
        {
            System.out.println("传入参数为空!");
            return null;
        }
    }

    // 求矩阵的逆矩阵  使用伴随矩阵的方法
    public static Matrix getAlter(Phalanx p)
    {
        if (p!=null)
        {
            // 判断方阵是否可逆  后进行行列式的计算,看结果是否为0
            double[][] matrix = p.getPhalanx();
            double a = RowLineFormula.interf(p);
            if (matrix.length!=0 && matrix.length==matrix[0].length && a != 0.0){
                // 方阵可逆,则求其伴随矩阵
                Phalanx accompany = getAccompany(new Phalanx(matrix));
                // 将伴随矩阵乘以 矩阵的行列式的结果
                Matrix numtil = Matrixs.numtil(accompany, Math.pow(a,-1));
                return  numtil;
            }
            else
            {
                // 方阵不可逆
                System.out.println("方阵不可逆!");
                return null;
            }
        }
        else {
            System.out.println("传入参数为空!");
            return null;
        }
    }
}

还有一个是计算行列式的类RowLineFormula.


/**
 * @author yiran
 * @creat 2021-11-23-13:23
 */
// 实现行列式的计算
public class RowLineFormula {

    // 行列式展开方法计算行列式 使用递归
    public double core(int rank,double[][]a) {

        if (rank>2)
        {
            // ----------------核心代码--------------------
            double result=0;

            for (int k=0;k<rank;k++)
            {
                // 取出余子式
                double [][]newArr=new double[rank-1][rank-1];
                int index=0;
                // 对数组进行赋值
                for (int i=0;i<rank;i++)
                {
                    if (k!=i)
                    {
                        for (int j=1;j<rank;j++)
                        {
                            // 如果该行不等于所在行
                            newArr[index][j-1]=a[i][j];
                        }
                        // 到第下一行赋值
                        index++;
                    }
                }

                // 重点注意  由于此处取的是  a11 所以 (-1)^(1+1) = 1  可以进行处理
                result+=Math.pow(-1,(k+1+1))*a[k][0]*core(rank-1,newArr);
            }
            // --------------------------------------
            return result;
        }
        else
        {
            // 二级行列式计算
            return a[0][0]*a[1][1]-a[0][1]*a[1][0];
        }

    }

    // 让其他类调用的API接口
    // 传入矩阵计算结果,看结果是否可逆
    /**
     * 矩阵的行列式求解结果
     * @param m 方阵
     * @return  |A|
     */
    public static double interf(Phalanx m)
    {
        return new RowLineFormula().core(m.getM(),m.getPhalanx());
    }


}

就是上面的代码了,将代码复制到idea或者eclipse,再在各个类中导一下包就可以运行了.
由于代码比较乱,大家可以参照下面的测试类进行调用.

求伴随矩阵和逆矩阵的函数分别是Matrixs类中的getAccompany(),getAlter()方法


import org.junit.Test;

/**
 * @author yiran
 * @creat 2021-11-26-16:18
 */
public class MatrixsTest {



 
    // 测试伴随矩阵
    @Test
    public void test06()
    {
        double [][] m1= {
                {1,0,1},
                {2, 1,0},
                {-3,2,-5}
        };
        double [][] m2= {
                {2, 1},
                {5, 3}

        };
        Phalanx accompany = Matrixs.getAccompany(new Phalanx(m1));

        accompany.print();

    }


    // 测试获取余子式
    @Test
    public void test07()
    {

        double [][]  arr=
                {{1,2,3,8},
                 {2,3,4,7},
                  {5,8,9,6},
                  {4,8,9,2}};

        double[][] less = Matrixs.getLess(arr, 4, 2);

        new Matrix(less).print();
    }



    /**
     * 测试矩阵的行列式计算
     */
    @Test
    public void test09()
    {
        // 首先需要一个方阵
        double [][] arr = {
                {2,1},
                {5,3}
        };

        System.out.println(RowLineFormula.interf(new Phalanx(arr)));

    }

    /**
     * 测试逆矩阵的计算
     */
    @Test
    public void test10()
    {
        double [][] m2= {
                {2, 1},
                {5, 3}

        };

        double [][] m1= {
                {1,0,1},
                {2, 1,0},
                {-3,2,-5}
        };


        double [][] m3= {
                {1,-1,-1},
                {0,1,-1},
                {0,0,1}
        };

        double [][] m4= {
                {2,1},
                {7,4}
        };

        Matrixs.getAlter(new Phalanx(m4)).print();
    }
}

同理,导一下包,再导一下单元测试,就可以运行测试类了.

如果只是希望求解伴随矩阵和逆矩阵的话,使用下面的轻松使用的代码即可 类名为AlterMatrixFormula.



import java.util.Arrays;
import java.util.Scanner;

/**
 * 轻松使用,计算矩阵的伴随矩阵和逆矩阵
 * @author yiran
 * @creat 2021-12-03-17:21
 */
public class AlterMatrixFormula {


    // 方阵的阶数
    private static double [][] arr=null;
    // 方阵的阶数
    private static int n;

    private static Scanner scan = null;
    private static Phalanx phalanx = null;

    private static boolean flag = false;

    // 读取矩阵
    private static void read()
    {

        while(true)
        {
            System.out.print("请输入矩阵的阶数(n):");
            String s = scan.nextLine();
            String[] s1 = s.trim().split(" ");
            if (s1!=null&&s1.length!=1)
            {
                System.out.println("输入错误!请重新输入");
                continue;
            }
            n =Integer.parseInt(s1[0]);
            arr =new double[n][n];

            System.out.println("请输入矩阵的数据:");
//            System.out.println("如果遇到要输入多一行的情况,请直接回车");
            for (int i=0;i<n;i++)
            {
                // 一行一行地赋值
                System.out.print("第"+(i+1)+"行: ");
                String s2 = scan.nextLine();
                String[] s3 = s2.trim().split(" ");
                if (s3.length!=n)
                {
                    // 再次输入
                    i--;
                    System.out.println("输入格式错误,请重新输入!");
                    continue;
                }
                for (int j=0;j<n;j++)
                {
                    arr[i][j]=Double.parseDouble(s3[j]);
                }
            }
            phalanx = new Phalanx(arr);
            break;
        }
    }


    public static void main(String[] args) {

        scan = new Scanner(System.in);

        while(true)
        {
            if (flag)
            {
                scan.nextLine();
            }
            read();
            // 行列式的伴随矩阵为:
            System.out.println("该矩阵的伴随矩阵为:");
            Matrixs.getAccompany(phalanx).print();

            System.out.println("该矩阵的逆矩阵为");
            Matrixs.getAlter(phalanx).print();

            System.out.print("输入0可以继续:");
            flag =true;
            int sign = scan.nextInt();
            if (sign == 0)
            {
                continue;
            }
            else
            {
                System.out.println("Bye!");
                break;
            }
        }


    }

}

class Matrix{

    // 矩阵
    private double[][] matrix;
    private int m;
    private int n;

    public double[][] getMatrix() {
        return matrix;
    }


    public Matrix() {

    }


    public Matrix(double[][] matrix) {
        this.matrix = matrix;
        this.m=matrix.length;
        this.n=matrix[0].length;
    }

    public Matrix(int m, int n) {
        this.matrix=new double[m][n];
        this.m=m;
        this.n=n;
    }

    public void setMatrix(double[][] matrix) {
        this.matrix = matrix;
        this.m=matrix.length;
        this.n=matrix[0].length;
    }

    public int getM() {
        return m;
    }

    public void setM(int m) {
        this.m = m;
    }

    public int getN() {
        return n;
    }

    public void setN(int n) {
        this.n = n;
    }

    public void print()
    {
        System.out.println("------------------结果-------------------");
        for (int i=0;i<m;i++)
        {
            for (int j=0;j<n;j++)
            {
                System.out.print(matrix[i][j]+"    ");
            }
            System.out.println();
        }
        System.out.println("----------------------------------------");
    }

    @Override
    public String toString() {
        return "Matrix{" +
                "matrix=" + Arrays.toString(matrix) +
                '}';
    }
}

class Phalanx extends Matrix {

    // 调用父类的构造函数,构造方阵
    public Phalanx(int n) {
        super(n, n);
    }

    public Phalanx() {
    }

    // 初始化方阵,并进行校验
    public Phalanx(double[][] matrix) {
        if(matrix.length!=matrix[0].length)
        {
            // 传入参数不符合方阵的要求
            System.out.println("初始化失败:传入参数不符合方阵的要求!");
        }
        else
        {
            this.setMatrix(matrix);
        }

    }

    public double[][] getPhalanx() {
        return getMatrix();
    }


    public void setPhalanx(double [][] phalanx) {
        if(phalanx.length!=phalanx[0].length)
        {
            // 传入参数不符合方阵的要求
            System.out.println("初始化失败:传入参数不符合方阵的要求!");
        }
        else
        {
            super.setMatrix(phalanx);
        }

    }

}

/**
 * 方阵的辅助类
 * @author yiran
 * @creat 2021-11-26-14:08
 */
class Matrixs{



    // 矩阵转置
    public static Matrix reverse(Matrix m)
    {
        if(m!=null)
        {
            Matrix new_m=new Matrix();
            double[][] m_data = m.getMatrix();
            double[][] new_m_data=new double[m.getN()][m.getM()];
            for (int i=0;i<m.getN();i++)
            {
                for (int  j=0;j<m.getM();j++)
                {
                    new_m_data[i][j]=m_data[j][i];
                }
            }

            m.setMatrix(new_m_data);
            return m;

        }
        return null;
    }

    // 矩阵数乘
    public static Matrix numtil(Matrix m,double num)
    {
        if(m!=null)
        {
            Matrix new_m=new Matrix();
            double[][] m_data = m.getMatrix();
            double[][] new_m_data=new double[m.getM()][m.getN()];
            for (int i=0;i<m.getM();i++)
            {
                for (int  j=0;j<m.getN();j++)
                {
                    new_m_data[i][j] = num * m_data[i][j];
                }
            }

            new_m.setMatrix(new_m_data);
            return new_m;

        }
        return null;
    }




    /**
     *
     * @param origin  矩阵数组
     * @param i
     * @param j
     * @return  矩阵对应 i,j 位置的余子式
     */
    public static double[][] getLess(double [][] origin,int i,int j)
    {
        if (origin!=null)
        {
            int c_i=i-1;
            int c_j = j-1;

            int n = origin.length;
            // 取出余子式
            double[][] newArr = new double[n - 1][n - 1];
            int index_i = 0;
            // 对数组进行赋值
            for (int l = 0; l < n; l++) {
                // 如果该行不等于所在行
                if (c_i != l) {
                    int index_j = 0;
                    for (int o = 0; o < n; o++) {
                        // 列不等该列
                        if (c_j != o)
                        {
                            newArr[index_i][index_j] = origin[l][o];
                            index_j++;
                        }
                    }
                    // 到第下一行赋值
                    index_i++;
                }
            }
            return newArr;
        }

        return null;
    }

    // 求方阵的伴随矩阵
    public static Phalanx getAccompany(Phalanx p)
    {

        if (p!=null)
        {
            // 用于存储伴随矩阵的数据
            double[][] pMatrix = p.getMatrix();
            int n = p.getN();
            double [][] new_p=new double[n][n];
            // 调用递归算法将余子式算出
            if(n>2)
            {
                for (int i = 0; i< n; i++)
                {
                    for (int j=0;j<n;j++)
                    {
                        // 取出来余子项,并进行传参并代入代数余子式
                        new_p[i][j] = Math.pow(-1,(1+1+i+j))*RowLineFormula.interf(new Phalanx(getLess(pMatrix,i+1,j+1)));
                    }

                }
            }else
            {
                // 仅对二阶的进行特殊处理,不要进行转置
                if (n==2)
                {
                    new_p[0][0] = pMatrix[1][1];
                    new_p[0][1] = -1*pMatrix[1][0];
                    new_p[1][0] = -1*pMatrix[0][1];
                    new_p[1][1] = pMatrix[0][0];

                }
            }

            // 得到了矩阵后还要将其反转才得到伴随矩阵
            return (Phalanx) Matrixs.reverse(new Phalanx(new_p));

        }
        else
        {
            System.out.println("传入参数为空!");
            return null;
        }
    }

    // 求矩阵的逆矩阵  使用伴随矩阵的方法
    public static Matrix getAlter(Phalanx p)
    {
        if (p!=null)
        {
            // 判断方阵是否可逆  后进行行列式的计算,看结果是否为0
            double[][] matrix = p.getPhalanx();
            double a = RowLineFormula.interf(p);
            if (matrix.length!=0 && matrix.length==matrix[0].length && a != 0.0){
                // 方阵可逆,则求其伴随矩阵
                Phalanx accompany = getAccompany(new Phalanx(matrix));
                // 将伴随矩阵乘以 矩阵的行列式的结果
                Matrix numtil = Matrixs.numtil(accompany, Math.pow(a,-1));
                return  numtil;
            }
            else
            {
                // 方阵不可逆
                System.out.println("方阵不可逆!");
                return null;
            }
        }
        else {
            System.out.println("传入参数为空!");
            return null;
        }
    }
}

class RowLineFormula {

    // 行列式展开方法计算行列式 使用递归
    public double core(int rank,double[][]a) {

        if (rank>2)
        {
            // ----------------核心代码--------------------
            double result=0;

            for (int k=0;k<rank;k++)
            {
                // 取出余子式
                double [][]newArr=new double[rank-1][rank-1];
                int index=0;
                // 对数组进行赋值
                for (int i=0;i<rank;i++)
                {
                    if (k!=i)
                    {
                        for (int j=1;j<rank;j++)
                        {
                            // 如果该行不等于所在行
                            newArr[index][j-1]=a[i][j];
                        }
                        // 到第下一行赋值
                        index++;
                    }
                }

                // 重点注意  由于此处取的是  a11 所以 (-1)^(1+1) = 1  可以进行处理
                result+=Math.pow(-1,(k+1+1))*a[k][0]*core(rank-1,newArr);
            }
            // --------------------------------------
            return result;
        }
        else
        {
            // 二级行列式计算
            return a[0][0]*a[1][1]-a[0][1]*a[1][0];
        }

    }

    // 让其他类调用的API接口
    // 传入矩阵计算结果,看结果是否可逆
    /**
     * 矩阵的行列式求解结果
     * @param m 方阵
     * @return  |A|
     */
    public static double interf(Phalanx m)
    {
        return new RowLineFormula().core(m.getM(),m.getPhalanx());
    }

}

编译

javac -encoding utf-8 AlterMatrixFormula.java

编译后产生5个class文件,运行其中的AlterMatrixFormula的class文件即可
运行

java AlterMatrixFormula

测试:
在这里插入图片描述
如果对行列式的计算感兴趣的,还可以看我的另一篇文章:Java实现行列式的计算.
如果对矩阵的运算感兴趣的,还可以看我的另一篇文章: Java实现矩阵的运算.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值