首页 > 编程语言 >用 python 和 java 实现线性代数计算(1)—— 矩阵基本操作

用 python 和 java 实现线性代数计算(1)—— 矩阵基本操作

时间:2022-11-22 10:33:33浏览次数:31  
标签:getRowNum java Matrix python getColNum 矩阵 int 基本操作 mat


  • 参考:《机器学习算法框架实战:Java和Python实现》
  • python实现主要是调用 NumPy 库做的;java实现基本没有调库

文章目录

  • ​​1. 说明​​
  • ​​1.1 程序组织​​
  • ​​1.2 数据结构​​
  • ​​1.2.1 python实现​​
  • ​​1.2.2 java实现​​
  • ​​2. 矩阵基本操作​​
  • ​​2.1 基本运算(加、减、叉乘、点乘、转置)​​
  • ​​2.1.1 python实现​​
  • ​​2.1.2 java实现​​
  • ​​2.2 其他基本操作(生成单位阵、合并、复制)​​
  • ​​2.2.1 python实现​​
  • ​​2.2.2 java实现​​

1. 说明

1.1 程序组织

  • python实现主要是调用 NumPy 库做的,不需要什么程序组织
  • java实现中,一共写三个类
  1. ​Main​​:程度入口,用于编写测试代码
  2. ​Matrix​​:矩阵类,实现矩阵的创建、修改、信息获取等方法
  3. ​AlgebraUtil​​:矩阵运算类,提供矩阵运算的静态方法,可以直接使用 ​​AlgebraUtil.function​​的方式调用,而无需创建此类实例

在 IDEA 环境中,组织如下

用 python 和 java 实现线性代数计算(1)—— 矩阵基本操作_线性代数

1.2 数据结构

1.2.1 python实现

  • 直接使用 NumPy 提供的 ​​ndarray​​ 数组作为矩阵即可
import numpy as np
def test_mat_basic():
# 调用np.array直接创建矩阵
mat1 = np.array([[1, 2, 3], [4, 5, 6]])
print(mat1)
# 调用np.zeros创建一个3行2列元素全为0的矩阵
mat2 = np.zeros((3, 2))
print(mat2)
# 调用np.ones创建一个3行2列元素全为1的矩阵
mat3 = np.ones((3, 2))
print(mat3)
# 调用np.random.rand创建一个3行2列元素全为随机数的矩阵
mat4 = np.random.rand(3, 2)
print(mat4)

if __name__ == "__main__":
test_mat_basic()
  • 更多构造方法如下

方法名

描述

​array​

将输入数据(列表、元组、数组及其他序列)转换为​​ndarray​​,如不显式指明数据类型,将自动推断;默认复制所有输入数据

​asarray​

将输入转换为​​ndarray​​​,但若输入已经是​​ndarray​​则不再复制

​arange​

python内置​​range​​​函数的​​ndarray​​​版本,返回一个​​ndarray​

​ones​

根据给定形状和数据类型生成全​​1​​数组

​ones_like​

根据给定的数组生成一个形状一样的全​​1​​数组

​zeros​

根据给定形状和数据类型生成全​​0​​数组

​zeros_like​

根据给定的数组生成一个形状一样的全​​0​​数组

​empty​

根据给定形状生成一个没有初始化数值的空数组(通常是0,但也可能是一些未初始化的垃圾数值

​empty_like​

根据给定的数组生成一个形状一样但没有初始化数值的空数组

​full​

根据给定形状和数据类型生成指定数值的数组

​full_like​

根据给定的数组生成一个形状一样但内容是指定数值的数组

​eye,identity​

生成一个 NxN 特征矩阵(对角线位置都是1,其余位置为0)

1.2.2 java实现

  • java中,矩阵的数据结构设计如下
package LinearAlgebra;
import java.math.BigDecimal;

public class Matrix {
private BigDecimal[][] mat; // 用一个二维数组存储矩阵的实体
private int rowNum; // 矩阵的行数
private int colNum; // 矩阵的列数

// 构造函数
public Matrix(int rowNum, int colNum) {
this.rowNum = rowNum;
this.colNum = colNum;

mat = new BigDecimal[rowNum][colNum];
initializeMatrix();
}

// 初始化矩阵
private void initializeMatrix(){
for (int i = 0; i < rowNum; i++) {
for (int j = 0; j < colNum; j++) {
mat[i][j] = new BigDecimal(0.0);
}
}
}

// getter & setter
public void setValue(int x1,int x2,double value){
mat[x1][x2] = new BigDecimal(value);
}

public void setValue(int x1,int x2,BigDecimal value){
mat[x1][x2] = value;
}

public void setValue(BigDecimal[][] matrix){
for (int i = 0; i < rowNum; i++) {
for (int j = 0; j < colNum; j++) {
mat[i][j] = matrix[i][j];
}
}
}

public void setValue(double[][] matrix){
for (int i = 0; i < rowNum; i++) {
for (int j = 0; j < colNum; j++) {
mat[i][j] = new BigDecimal(matrix[i][j]);
}
}
}

public BigDecimal getValue(int x1,int x2){
return mat[x1][x2];
}

public int getRowNum() {
return rowNum;
}

public int getColNum() {
return colNum;
}

// 格式化打印
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < rowNum; i++) {
for (int j = 0; j < colNum; j++) {
sb.append(String.format("%15f",mat[i][j].doubleValue()));
}
sb.append('\n');
}
return sb.toString();
}
}
  • 矩阵运算类示意如下
package LinearAlgebra;
import java.math.BigDecimal;

// final修饰的方法,不能被子类覆盖定义;static表示这是静态方法,可以使用类名调用
public class AlgebraUtil {

// 矩阵加法
public final static Matrix add(Matrix a,Matrix b){
//...
}

//...
}

2. 矩阵基本操作

2.1 基本运算(加、减、叉乘、点乘、转置)

2.1.1 python实现

  • python中,矩阵相当于2维的 ndarray 数组,可以直接使用numpy库方法实现矩阵的全部基本运算
import numpy as np

m1 = np.array([[1,2,3],
[4,5,6],
[7,8,9]])

m2 = np.array([[9,8,7],
[6,5,4],
[3,2,1]])

# 矩阵基本操作
result = m1 + m2 # 矩阵加法
result = m1 - m2 # 矩阵减法
result = m1 * m2 # 矩阵点乘
result = np.dot(m1,m2) # 矩阵叉乘, 等价于 result = m1.dot(m2)
result = m1.T # 矩阵转置

print(result)

2.1.2 java实现

  1. 在​​LinearAlgebra​​类中添加五个静态类,实现基本运算 加、减、叉乘、点乘、转置
  1. 矩阵加法:实现静态方法 ​​LinearAlgebra.add​​,要求矩阵a和矩阵b尺寸相同
public final static Matrix add(Matrix a,Matrix b){
if(a==null || b==null ||
a.getRowNum() != b.getRowNum() ||
a.getColNum() != b.getColNum()) {
return null;
}

Matrix mat = new Matrix(a.getRowNum(),a.getColNum());
for (int i = 0; i < mat.getRowNum(); i++) {
for (int j = 0; j < mat.getColNum(); j++) {
BigDecimal value = a.getValue(i,j).add(b.getValue(i,j));
mat.setValue(i,j,value);
}
}
return mat;
}
  1. 矩阵减法:实现静态方法 ​​LinearAlgebra.subtract​​,要求矩阵a和矩阵b尺寸相同
public final static Matrix subtract(Matrix a,Matrix b){
if(a==null || b==null ||
a.getRowNum() != b.getRowNum() ||
a.getColNum() != b.getColNum()) {
return null;
}

Matrix mat = new Matrix(a.getRowNum(),a.getColNum());
for (int i = 0; i < mat.getRowNum(); i++) {
for (int j = 0; j < mat.getColNum(); j++) {
BigDecimal value = a.getValue(i,j).subtract(b.getValue(i,j));
mat.setValue(i,j,value);
}
}
return mat;
}
  1. 矩阵叉乘:实现静态方法 ​​LinearAlgebra.multiply​​,要求矩阵a的列数等于矩阵b的行数
public final static Matrix multiply(Matrix a,Matrix b){
if(a==null || b==null || a.getColNum() != b.getRowNum()) {
return null;
}

Matrix mat = new Matrix(a.getRowNum(),b.getColNum());
for (int i = 0; i < mat.getRowNum(); i++) {
for (int j = 0; j < mat.getColNum(); j++) {
BigDecimal value = new BigDecimal(0.0);
for (int c = 0; c < a.getColNum(); c++) {
value = value.add(a.getValue(i,c).multiply(b.getValue(c,j)));
}
mat.setValue(i,j,value);
}
}
return mat;
}
  1. 矩阵点乘:实现静态方法 ​​LinearAlgebra.dot​​,要求矩阵a和矩阵b尺寸相同
public final static Matrix dot(Matrix a,Matrix b){
if(a==null || b==null ||
a.getRowNum() != b.getRowNum() ||
a.getColNum() != b.getColNum()) {
return null;
}

Matrix mat = new Matrix(a.getRowNum(),a.getColNum());
for (int i = 0; i < mat.getRowNum(); i++) {
for (int j = 0; j < mat.getColNum(); j++) {
BigDecimal value = a.getValue(i,j).multiply(b.getValue(i,j));
mat.setValue(i,j,value);
}
}
return mat;
}
  1. 矩阵转置:实现静态方法 ​​LinearAlgebra.transpose​
public final static Matrix transpose(Matrix a){
if(a==null){
return null;
}

Matrix mat = new Matrix(a.getColNum(),a.getRowNum());
for (int i = 0; i < mat.getRowNum(); i++) {
for (int j = 0; j < mat.getColNum(); j++) {
BigDecimal value = a.getValue(i,j);
mat.setValue(j,i,value);
}
}
return mat;
}
  1. 测试代码
package LinearAlgebra;

public class Main {
public static void main(String[] args) {
Matrix m1 = new Matrix(3,3);
Matrix m2 = new Matrix(3,3);

m1.setValue(new double[][] {{1,2,3},
{4,5,6},
{7,8,9}});
m2.setValue(new double[][] {{9,8,7},
{6,5,4},
{3,2,1}});

Matrix result;
result = AlgebraUtil.add(m1,m2); // 矩阵加法
result = AlgebraUtil.subtract(m1,m2); // 矩阵减法
result = AlgebraUtil.dot(m1,m2); // 矩阵点乘
result = AlgebraUtil.multiply(m1,m2); // 矩阵叉乘
result = AlgebraUtil.transpose(m1); // 矩阵转置

System.out.println(result.toString());
}
}

2.2 其他基本操作(生成单位阵、合并、复制)

2.2.1 python实现

  • python中,矩阵相当于2维的 ndarray 数组,可以直接使用numpy库方法实现矩阵的全部基本运算
import numpy as np

m1 = np.array([[1,2,3],
[4,5,6],
[7,8,9]])

m2 = np.array([[9,8,7],
[6,5,4],
[3,2,1]])

# 矩阵其他操作
result = np.eye(3) # 生成单位矩阵
result = np.vstack((m1,m2)) # 纵向合并
result = np.hstack((m1,m2)) # 横向合并
result = m1.copy() # 复制矩阵

print(result)

2.2.2 java实现

  1. 在​​LinearAlgebra​​类中添加三个静态类,实现基本操作 生成单位矩阵、矩阵合并、矩阵复制
  1. 生成单位矩阵:实现静态方法 ​​LinearAlgebra.identityMatrix​​,可以用类似的操作构造其他特殊矩阵
public final static Matrix identityMatrix(int dimension){
Matrix mat = new Matrix(dimension,dimension);
for (int i = 0; i < mat.getRowNum(); i++) {
mat.setValue(i,i,1.0);
}
return mat;
}
  1. 矩阵合并:实现静态方法 ​​LinearAlgebra.mergeMatrix​​​,使用参数​​direction​​决定合并方向(维度),要求合并维度长度一致
public final static Matrix mergeMatrix(Matrix a,Matrix b,int direction){
// direction=0纵向合并
if(direction == 0){
Matrix mat = new Matrix(a.getRowNum()+b.getRowNum(),a.getColNum());
for (int r = 0; r < a.getRowNum(); r++) {
for (int c = 0; c < a.getColNum(); c++) {
BigDecimal value = a.getValue(r, c);
mat.setValue(r,c,value);
}
}
for (int r = 0; r < b.getRowNum(); r++) {
for (int c = 0; c < b.getColNum(); c++) {
BigDecimal value = b.getValue(r, c);
mat.setValue(r+a.getRowNum(),c,value);
}
}
return mat;
// direction=1横向合并
} else if (direction == 1){
Matrix mat = new Matrix(a.getRowNum(),a.getColNum()+b.getColNum());
for (int r = 0; r < a.getRowNum(); r++) {
for (int c = 0; c < a.getColNum(); c++) {
BigDecimal value = a.getValue(r, c);
mat.setValue(r,c,value);
}
}
for (int r = 0; r < b.getRowNum(); r++) {
for (int c = 0; c < b.getColNum(); c++) {
BigDecimal value = b.getValue(r, c);
mat.setValue(r,c+a.getColNum(),value);
}
}
return mat;
} else {
return null;
}
}
  1. 矩阵复制:实现静态方法 ​​LinearAlgebra.copy​
public final static Matrix copy(Matrix x){
Matrix mat = new Matrix(x.getRowNum(),x.getColNum());
for (int i = 0; i < mat.getRowNum(); i++) {
for (int j = 0; j < mat.getColNum(); j++) {
BigDecimal value = x.getValue(i,j);
mat.setValue(i,j,value);
}
}
return mat;
}
  1. 测试代码
package LinearAlgebra;

public class Main {
public static void main(String[] args) {
Matrix m1 = new Matrix(3,3);
Matrix m2 = new Matrix(3,3);

m1.setValue(new double[][] {{1,2,3},
{4,5,6},
{7,8,9}});
m2.setValue(new double[][] {{9,8,7},
{6,5,4},
{3,2,1}});

Matrix result;
result = AlgebraUtil.copy(m1); // 复制矩阵
result = AlgebraUtil.identityMatrix(3); // 生成单位阵
result = AlgebraUtil.mergeMatrix(m1,m2,0); // 纵向合并
result = AlgebraUtil.mergeMatrix(m1,m2,1); // 横向合并

System.out.println(result.toString());
}
}


标签:getRowNum,java,Matrix,python,getColNum,矩阵,int,基本操作,mat
From: https://blog.51cto.com/u_15887260/5876716

相关文章

  • git笔记(1)—— 基本操作
    文章目录​​1.git组织结构​​​​2.git基本操作​​​​3.分支管理​​1.git组织结构git由“工作区”和“版本库”组成,其中版本库由分为“暂存区”和“分支区......
  • JavaWeb课程上用到的方法-11.22
    PrintWriterwriter=resp.getWriter();//响应流StringcontextPath=req.getContextPath();//返回站点根目录resp.sendRedirect(contextPath);//重定向Enumeration<S......
  • Java设计模式 - 24种
    设计模式的七大原则   开闭原则:对扩展开放、对修改关闭。   单一指责原则:一个类只做一件事。   依赖倒转原则:类似于ioc,采用接口编程。   迪米特原则:高内聚......
  • 极客编程python入门-切片
    切片取一个list或tuple的部分元素是非常常见的操作。>>>L=['Michael','Sarah','Tracy','Bob','Jack']>>>[L[0],L[1],L[2]]['Michael','Sarah','Tracy']Python提......
  • Java中的Iterator迭代器详解
    ......
  • 这11个JavaScript小技巧,你在大多数教程中是找不到的!
    英文原文| ​​https://medium.com/@bretcameron/12-javascript-tricks-you-wont-find-in-most-tutorials-a9c9331f169d​​​当我开始学习JavaScript时,我把我在别人的代......
  • javaweb
    Tomcat1.下载1.官网https://tomcat.apache.org/2.左侧download下选择版本3.选择下载的格式4.直接解压即可2.配置1.打开环境变量2.打开系统变量的pat......
  • java8 (jdk 1.8) 新特性——Stream ApI
    在java8中,有两个最重要的改变,一个就是之前了解的Lmbda java8(jdk1.8)新特性——Lambda ,还有一个就是StreamApi 1.什么是StreamAPI 简单来说就是一个类库,里边......
  • java日志之log4j、log4j2、slf4j以及整合关系
    了解log4j、log4j2之间的关系;以及与slf4j整合时使用的中间jar包:slf4j-log4j12、log4j-slf4j-impl。1.Log4jlog4j核心包只有一个,即log4j.jar。上图是log4j最后的版本......
  • Java工具库Guava并发相关工具类的使用示例
    场景Java核心工具库Guava介绍以及Optional和Preconditions使用进行非空和数据校验:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/127683387Java中Executo......