- 前景提示
- 需求
-
分析
- 1、初始化不需要指定矩阵的尺寸,并且可以直接传入数据。
- 2、可以计算2×2矩阵的逆
- 3、可以做2×2的矩阵乘法
-
Java版本开发
-
一、 开发详情
- 1、开发一个子类,如图所示。
-
2、根据问题修改子类,父类,以便真实可用
- 解决1、初始化不需要指定矩阵的尺寸,并且可以直接传入数据。
- 解决 2、可以计算2×2矩阵的逆
- (1) 第二题第一问,全为零打印
- (2)第二题第二问,逆矩阵输出
- 解决 3、可以做2×2的矩阵乘法
- (1) 第三题第一问,逆矩阵乘法
- (2)第三题第二问,复合乘法
- 二、最终完整版
- 三、其他相关方法的测试
-
一、 开发详情
-
Python版本开发
-
一、python代码
- 1、导入 包
- 2、创建数组
- 3、打印数组
- 4、求矩阵的逆
- 5、矩阵的乘法
- 6、完整版
- 7、测试结果
- 8、拓展其他功能
-
一、python代码
- 总结
前景提示
- 最近小伙伴问了一个题目,就是用Java开发线性代数,本身Java的能力并不是很擅长做这样的工作,需要计算的话还是用python开发更好,方便快捷,简单方便,但是,既然有这样的需求还是需要进行开发的,毕竟没有客户会管你多么费劲,只会说你开发不了水平不够,这边进行了九个小时的开发,开发了Java和python两个版本,本文的优势就在于系统全面,并且拿来可用,对于那些急于解决问题,完成作业的小伙伴,非常友好,因此,这篇文章对你帮助极大,希望你喜欢。
需求
- 题目如下如这样。
分析
1、初始化不需要指定矩阵的尺寸,并且可以直接传入数据。
- 题目一的要求翻译一下,就是要(1)写一个子类继承父类,(2)子类要有一个构造方法可以传入double[]类型的数据,(3)打印的结果要像图例那样,所以要重写showInfo方法(这是没重写实际运行发现的,初期没觉得要重写)
2、可以计算2×2矩阵的逆
- 题目翻译:(1) 要开发一个get_inverse()在子类中(2)要增加一个判断判断在矩阵中全是0的时候要有判断输出。
3、可以做2×2的矩阵乘法
- 题目翻译:(1) 要开发一个方法mul(m3),可以做矩阵的乘法 (2)方法之间可以互相调用mul().showInfo().
Java版本开发
一、 开发详情
1、开发一个子类,如图所示。
父类
package com.grandfather.www.marixs;
/**
* @projectName: marixs
* @package: com.grandfathers.www.marixs
* @className: BaseMatrix
* @author: your-father
* @description: TODO
* @date: 2023-09-30 20:58
* @version: 1.0
*/
public class BaseMatrix {
// 矩阵的行列数
int m = 0, n = 0;
// 矩阵的数据
float data[];
public BaseMatrix() {
}
// 构造函数
public BaseMatrix(int m, int n) {
this.m = m;
this.n = n;
this.data = new float[m * n];
}
// 设置矩阵
public void setData(float[] data) {
this.data = data;
}
public float[] getData() {
return data;
}
// 显示矩阵的信息
void showInfo() {
System.out.println("-----------");
System.out.println("矩阵尺寸为: " + m + "x" + n);
System.out.println("矩阵的数据为 : ");
for (int i = 0; i
子类
public class Marix_2X2 extends BaseMatrix {
public static void main(String[] args) {
// 查看矩阵
Marix_2X2 marix2X2 = new Marix_2X2();
marix2X2.setData(new float[]{1, 2, 2, 5});
marix2X2.n=2;
marix2X2.showInfo();
}
}
- 建个基础的版本,可以做个继承BaseMatrix,查看其父类的方法,什么也不改就只能像上面这样使用,可以看到,跟测试完全不一样,打印的结果中间有个大空格,这样不符合题目的要求,因此,需要改造。
2、根据问题修改子类,父类,以便真实可用
解决1、初始化不需要指定矩阵的尺寸,并且可以直接传入数据。
- 首先要在子类里添加构造方法
public class Marix_2X2 extends BaseMatrix {
public Marix_2X2() {
}
public Marix_2X2(float[] data) {
super();
this.data = data;
createBase(data);
}
BaseMatrix createBase(float[] data) {
int m = 0, n = 0;
for (int i = 0; i
-
其次要重写showInfo() 方法
// 显示矩阵的信息 @Override void showInfo() { System.out.println("-----------"); System.out.println("矩阵尺寸为: " + (m - 1) + "x" + n); System.out.println("矩阵的数据为 : "); for (int i = 0; i
-
最终第一个版本结果。(题目一的要求就满足了)
package com.grandfather.www.marixs; /** * @projectName: marixs * @package: com.grandfathers.www.marixs * @className: Marix_2X2 * @author: your-father * @description: TODO * @date: 2023-09-30 21:14 * @version: 1.0 */ public class Marix_2X2 extends BaseMatrix { public Marix_2X2() { } public Marix_2X2(float[] data) { super(); this.data = data; createBase(data); } BaseMatrix createBase(float[] data) { int m = 0, n = 0; for (int i = 0; i
解决 2、可以计算2×2矩阵的逆
- 这里就写的比较复杂了,主要是一般都是按照二维数组的处理方式处理的,而题目给的书传入一个一维数组,所以这里总是要处理,一维数组变二维,二维数组变一维这样的问题。
样例一
// 判断数组的元素是否全为0
boolean flag = true;
private Marix_2X2 get_inverse() {
Marix_2X2 m1 = new Marix_2X2(this.data);
if (null != this.data) {
float[] newdata = this.data;
int temp = 0;
for (int i = 0; i = 0; i--) {
for (j = i - 1; j >= 0; j--) {
tem_3 = W[j][i];
for (k = i; k
测试
// 全为0的矩阵
Marix_2X2 m1 = new Marix_2X2(new float[]{0, 0, 0, 0});
Marix_2X2 tmp = m1.get_inverse();
assert tmp != null;
tmp.showInfo();
(1) 第二题第一问,全为零打印
(2)第二题第二问,逆矩阵输出
解决 3、可以做2×2的矩阵乘法
-
矩阵乘法也没有什么问题,但是这里发现第一个结果跟题目的答案不一样,因此,经过反复debug发现是上个逆矩阵的算法有问题,因此这里又修改了逆矩阵的算法,最终,结果一致了。
-
错误的输出
矩阵的乘法
private Marix_2X2 mul(Marix_2X2 m3) {
float[][] a = new float[this.m - 1][this.n];
one2Two(this.getData(), a);
float[][] b = new float[this.m - 1][this.n];
one2Two(m3.getData(), b);
float[][] c = new float[this.m - 1][this.n];
float[] newdata = this.data;
for (int i = 0; i
替换逆矩阵算法
//求解逆矩阵
public Marix_2X2 get_inverse_2() {
Marix_2X2 m1 = new Marix_2X2(this.data);
if (null != this.data) {
int temp = 0;
float[] onwResult = this.data;
temp = isAllZero(temp, onwResult);
if (temp == onwResult.length) {
m1.flag = false;
} else {
float[][] floats = new float[this.m - 1][this.n];
float[][] floats2 = one2Two(m1.getData(), float服务器托管网s);
int row = floats2.length;
float[][] floats1 = CopyArry(floats2);
float[][] floats6 = new float[row][row];
float[][] floats7 = AdjointMatrix(floats1);
for (int i = 0; i arrayList = new ArrayList((n - 1) * (n - 1));
for (int i = 0; i
(1) 第三题第一问,逆矩阵乘法
-
测试代码
// 矩阵的乘法 Marix_2X2 m2 = new Marix_2X2(new float[]{2, 5, 1, 3}); Marix_2X2 m3 = new Marix_2X2(new float[]{4, -6, 2, 1}); m2.get_inverse_2().mul(m3).showInfo();
(2)第三题第二问,复合乘法
-
测试代码
// 矩阵的复合乘法 Marix_2X2 m4 = new Marix_2X2(new float[]{1, 4, -1, 2}); Marix_2X2 m5 = new Marix_2X2(new float[]{3, 1, 0, -1}); Marix_2X2 m6 = new Marix_2X2(new float[]{2, 0, -1, 1}); m4.get_inverse_2().mul(m5).mul(m6.get_inverse_2()).showInfo();
二、最终完整版
- 父类
package com.grandfathers.www.exersice;/**
* @author: MrLiu
* @createTime: 2023/09/30 20:58
* @description: xxx
*/
/**
* @projectName: anlysistSentence
* @package: com.grandfathers.www.exersice
* @className: BaseMatrix
* @author: your-father
* 服务器托管网@description: TODO
* @date: 2023-09-30 20:58
* @version: 1.0
*/
public class BaseMatrix {
// 矩阵的行列数
int m = 0, n = 0;
// 矩阵的数据
float data[];
public BaseMatrix() {
}
// 构造函数
public BaseMatrix(int m, int n) {
this.m = m;
this.n = n;
this.data = new float[m * n];
}
// public BaseMatrix(float[] data) {
// this.data = data;
// createBase(data);
// }
// 设置矩阵睡觉
public void setData(float[] data) {
this.data = data;
}
public float[] getData() {
return data;
}
// 显示矩阵的信息
void showInfo() {
System.out.println("-----------");
System.out.println("矩阵尺寸为: " + m + "x" + n);
System.out.println("矩阵的数据为 : ");
for (int i = 0; i
-
子类
package com.grandfathers.www.exersice;/** * @author: MrLiu * @createTime: 2023/09/30 21:14 * @description: xxx */ import java.util.ArrayList; import java.util.Objects; import static java.lang.Math.pow; /** * @projectName: anlysistSentence * @package: com.grandfathers.www.exersice * @className: Marix_2X2 * @author: your-father * @description: TODO * @date: 2023-09-30 21:14 * @version: 1.0 */ public class Marix_2X2 extends BaseMatrix { // 判断数组的元素是否全为0 boolean flag = true; public Marix_2X2(float[] data) { super(); this.data = data; createBase(data); } BaseMatrix createBase(float[] data) { int m = 0, n = 0; for (int i = 0; i 使用高斯消元法对矩阵进行求逆 * * @param arr 二维矩阵 * @return 矩阵的逆 */ float[][] gaussianElimination(float[][] arr) { int i, j, k; float tem_1, tem_2, tem_3; int N = arr.length; float[][] W = new float[N][2 * N]; float[][] result = new float[N][N]; // 对矩阵右半部分进行扩增 for (i = 0; i = 0; i--) { for (j = i - 1; j >= 0; j--) { tem_3 = W[j][i]; for (k = i; k arrayList = new ArrayList(); for (int i = 0; i = 0; i--) { float p = DeterminantProduct(floats1[index], floats1[i]) / DeterminantProduct(floats1[i], floats1[i]); float[] floats2 = NumberTimesArray(-p, floats1[i]); result = DeterminAntddition(result, floats2); } result = DeterminAntddition(result, floats1[index]); } return result; } //定义一个数和数组的乘法 public static float[] NumberTimesArray(float f, float[] floats) { int row = floats.length; float[] floats1 = new float[row]; for (int i = 0; i arrayList = new ArrayList((n - 1) * (n - 1)); for (int i = 0; i
三、其他相关方法的测试
// 转置
Marix_2X2 m7 = new Marix_2X2(new float[]{2, 5, -1, 1});
Marix_2X2 transpose = m7.Transpose();
transpose.showInfo();
// 伴随矩阵
Marix_2X2 m8 = new Marix_2X2(new float[]{2, 5, -1, 1});
float[][] floats = m8.AdjointMatrix(getData(m8));
m8.setData(two2One(floats, m8.getData()));
m8.showInfo();
// 余子式
m8.setData(two2One(m8.confactor(getData(m8), 2, 2), m8.getData()));
m8.Transpose();
m8.showInfo();
Python版本开发
- 都是面向对象的语言,因此操作步骤也是大同小异。
一、python代码
1、导入 包
# 这个一定要导入,不然的话,是用不了的
import numpy as np
2、创建数组
A = np.array([[1,2],[2,5]])
3、打印数组
# 矩阵信息打印
def showInfo(x):
print("------------")
print("矩阵的尺寸为:",np.shape(x)[0],"x",np.shape(x)[1])
print(x)
print("------------")
4、求矩阵的逆
# 求逆矩阵
def getInverse(x):
if(np.all(x==0)):
print("行列为0,不能求逆矩阵")
else:
B = np.linalg.inv(x)
print("逆矩阵")
return B
5、矩阵的乘法
# 矩阵乘法
def mul(x,y):
c = np.matmul(x,y)
return c
6、完整版
import numpy as np
from numpy import *
# 矩阵信息打印
def showInfo(x):
print("------------")
print("矩阵的尺寸为:",np.shape(x)[0],"x",np.shape(x)[1])
print(x)
print("------------")
# 求逆矩阵
def getInverse(x):
if(np.all(x==0)):
print("行列为0,不能求逆矩阵")
else:
B = np.linalg.inv(x)
print("逆矩阵")
return B
# 矩阵乘法
def mul(x,y):
c = np.matmul(x,y)
return c
def main():
pass
if __name__ == '__main__':
main()
A = np.array([[1,2],[2,5]])
showInfo(A)
B = np.array([[0,0],[0,0]])
getInverse(B)
H = getInverse(A)
showInfo(H)
print("-----矩阵乘法-------")
C = np.array([[2,5],[1,3]])
D = np.array([[4,-6],[2,1]])
m2 = getInverse(C)
result1 = mul(m2,D)
showInfo(result1)
print("-----混合乘法-------")
E = np.array([[1,4],[-1,2]])
F = np.array([[3,1],[0,-1]])
G = np.array([[2,0],[-1,1]])
m3 = getInverse(E)
result2 = mul(m3,F)
m4 = getInverse(G)
result3 = mul(result2,m4)
showInfo(result3)
7、测试结果
- 明显可以看到python的写法比Java的更加简洁,容易理解,因此,这种题目如果可以自己选择,最好使用python开发。
8、拓展其他功能
# 求单位矩阵
def singleArray(x):
F = np.eye(x)
return F
# 矩阵转置
def transArray(x):
H = x.T
return H
# 计算行列式的值
def getValue(x):
H = np.linalg.det(x)
return H
# A的伴随矩阵
def adjointMatrix(A):
n,_=A.shape #获取阶数n
Am=np.zeros((n,n)) #Am初始化为零阵
for i in range(n): #每一行
for j in range(n): #每一列
Am[i,j]=Aij(A,i,j) #伴随阵元素
return Am.T
#代数余子式
def Aij(A,i,j):
up=np.hstack((A[:i,:j],A[:i,j+1:])) #横向连接上方片段
lo=np.hstack((A[i+1:,:j],A[i+1:,j+1:])) #横向连接下方片段
M=np.vstack((up,lo)) #纵向连接
return ((-1)**(i+j))*np.linalg.det(M) #代数余子式
# 求代数余子式
def cofactor(matrix, i, j):
m = np.delete(matrix, i, axis=0)
m = np.delete(m, j, axis=1)
return np.linalg.det(m)
def cofactor_matrix(matrix):
n = matrix.shape[0]
cofactors = np.zeros((n, n))
for i in range(n):
for j in range(n):
cofactors[i, j] = (-1) ** (i + j) * cofactor(matrix, i, j)
return cofactors
-
测试代码
if __name__ == '__main__': print("-----单位矩阵-------") H =np.array([[1,2,3],[4,5,6],[6,1,3]]) lie = np.shape(H)[1] result4=singleArray(lie) showInfo(result4) print("-----转置-------") result5=transArray(H) showInfo(result5) print("-----计算行列式的值-------") I =np.array([[1,1,1],[1,1,0],[1,1,3]]) result6=getValue(H) print(result6) print("-----伴随矩阵-------") #设置矩阵A A1=np.array([[1,2,3],[2,2,1],[3,4,3]]) Am=adjointMatrix(A1) #A的伴随阵 print("A∗=",Am) print("AA∗=",np.matmul(A1,Am)) # 也是求伴随,结果跟上边不一样 B1=np.linalg.inv(A1) A_bs = B1*np.linalg.det(A) print(A_bs) print("-----求代数余子式-------") A3 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # 求解余子式矩阵 C3 = cofactor_matrix(A3) print(C3)
-
测试结果
总结
-
明显的可以看出Java开发线性代数的代码量多于python好多,同时,复杂度和便于理解方面也是相形见拙,因为Java是一门开发网站的编程语言,因此处理科学计算类问题功能弱于python,因此,如果没有特殊要求,建议使用python开发这类题目,或者用更加偏向数学的matlab开发,本文的很多代码也是引用了别人的代码,属于利用拼接的方式,最终完成了题目的所有要求。
-
因为开发这个人和借鉴资料实在混杂,最后找找测测,使用了大量的时间,希望大家多多点赞,关注,支持,特此感谢,你的支持就是每位用心写作的博主最大的动力,只有每位博主共同努力,你才能更好的完成作业,更便捷的找到答案,生态区才能活跃,技术才能发展,才有更璀璨的未来,因此不要林西你的支持点赞,关注。
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
源创会,线下重启!2023年7月1日深圳站—基础软件技术面面谈!免费票限时抢购! 2023年5月,由 Stackoverflow 发起的2023年度开发者调查数据显示,PostgreSQL 已经超越 MySQL 位居第一,成为开发人员首选。PostgreSQL…