文章目录
前言
这是笔者用 Java 编写的数学函数库,最初用于解决中学、大学里的一些数学计算,后面笔者逐渐将其发展为信号处理、股票、彩票等的数据分析,也是笔者其它 Java 项目依赖的基础数学库。可视化界面最初在高中时期用 VB 制作,之后大学阶段笔者将其用 C 语言重写,部署在单片机上。后面又用 C++ 编写,通过 MFC 编写可视化界面,提供了更复杂的功能。最后,笔者将底层算法用 Java 重写,将可视化界面分别用 Java Swing、JavaFX 进行迭代。
此项目是笔者当年踏入编程领域,自主独立开发的第一个完整项目,对笔者而言意义非凡。随着笔者自己开发的项目越来越庞大,笔者决定将其抽取成一个独立的项目。经过多年打磨,抽取出了一个不含 UI 界面、Spring 等等 Java 框架的底层数学函数库。项目代码已在 GitHub 上开源免费发布,笔者将对此项目提供持续更新与维护。
为什么用 Java 编写
既然是一种数学函数库,为什么选择用 Java 编写,而不是用 MATLAB、Python 呢?笔者确实也用 MATLAB、Python 编写过一些数学函数库,并非拒绝使用它们。但是,它们不能用于解决所有的问题。一方面,笔者编写的其它很多库都是 Java 编写的,用 MATLAB、Python 的库将会变成难以调用。虽然不是完全不可行,但如果强行使用,会增加很多额外的工作量。
另一方面,展开来说,MATLAB 主要用于终端的数学计算。如果这种数据计算只是一种中间结果,供程序的其它部分使用,MATLAB 将不太适合。而对于一些 CPU 密集型的计算,Java 因为天生支持多线程、协程,因此比 Python 要更有效率。很多运算在笔者的电脑经常要至少要 CPU 运行至 99% 计算十几分钟才能出结果,用 Python 将会更慢。此外,Java 天生支持 UI 界面,使用 Java 编写,数学计算结果也很方便在一种 UI 界面中展示。
诚然,MATLAB、Python 的数学函数生态并不是 Java 可比拟的,因此笔者在必要时也会直接使用 MATLAB、Python 来解决问题。但本项目只是关于用 Java 编写的数学函数库。
代码量
-
总计:16979
-
Java 代码:16484
-
文本语言代码:495
- XML:495
项目结构
mathlab-fx
├── externally-exposed
├── math-expression
├── math-library
├── math-built-in-type
├── common-tool
└── math-exception
其中,模块 math-library、math-built-in-type 是核心模块,模块 math-expression 是拓展模块,模块 common-tool、math-exception 是基础模块。模块 externally-exposed 是集成模块,依赖此模块相当于依赖了其它的所有模块。
核心模块 math-library
本模块提供了笔者自定义数据结构的基础类,并提供了基础的操作方法。
常规
整数
整数 Figure
支持大整数的表示及其运算。底层使用小整数和大整数切换表示。当数比较小时使用 int
表示,当数比较大时使用 BigInteger
表示。当数值发生变化时,会自动切换底层表示,这比直接使用大整数更有效率。
整数 Figure
支持的运算如下:
-
整数之间的加减乘除。其中,整数除法的结果会被精确表示为
有理数 Rational
。 -
求余、求整数商
-
乘方
-
整数大小比较、求最大最小值
-
相反数
-
最小公倍数、最大公约数
-
排列组合
有理数
有理数 Rational
支持分数的表示及其运算。底层用分数表示,也就是用两个 整数 Figure
分别表示分数的分子、分母。
有理数 Rational
支持的运算如下:
- 有理数之间的加减乘除。它们的运算结果可以被精确表示。
- 分数约分
- 有理数大小比较、求最大最小值
- 向上取整、向下取整
- 相反数、倒数
- 随机分数
- 有损转化为 double
有限小数
小数 Decimal
表示将有限小数按位存储的小数。
进制数
进制数 Radix
表示将进制数按位存储的任意进制的数。
进制数 FixedRadix
表示将进制数按位存储的任意进制的数,但是位数是固定的。
二进制数 Binary
表示将二进制数按位存储的二进制数。
复数
Complex
表示直角坐标表示的复数。
PolarComplex
表示极坐标表示的复数。
复数支持的运算如下:
- 直角坐标与极坐标之间的互相转化
- 复数之间的加减乘除
集合
集合 XXXDomain
支持的运算如下:
- 求并集、交集、减集、差集、是否包含
- 集合与数之间的加减乘除
离散函数
离散函数 XXXDiscrete
支持的运算如下:
- 离散函数之间的加减乘除
- 求 n 阶差分、n 距差分
- 卷积、自卷积
- 离散傅里叶变换
统计
XXXStatistics
用于支持统计学中,对一组数的求和、平均数、最大最小值、方差运算。
自研算法
大有理数转化为 double
此算法用于解决大整数相除,并将结果转化为 double 类型。
更多的信息,可见笔者的另一篇博客:
大整数相除防溢出算法:
https://blog.csdn.net/wangpaiblog/article/details/127219472
自创概念
数排
数排 Arrangement
表示一排有序号的数。
数排 Arrangement
支持的运算如下:
- 求正向交换次数
- 求逆向交换次数
- 求熵
编码
组合编码
有 n 个号码球,它们的编号分别为 1 ~ n。从这 n 个号码球中组合选 m 个号码,然后对这组号码进行编号。不同的组合对应不同的编号,编号的范围为 [1, C(n,m)]。
二进制编码
有 n 个号码球,它们的编号分别为 1 ~ n。从这 n 个号码球中组合选任意个号码,然后对这组号码进行编号。将这 n 个号码球看成是 n 位的二进制数进行编号。
概率
组合选概率
一共有 total 个球,valid 个有效,选 choice 个,中 winNum 个的概率及中奖情况的分布。
压缩
均匀压缩
将一些数据按比例压缩成另一个范围的数据。
核心模块 math-built-in-type
本模块是对 Java 内置类型数据的处理。
基础计算
- 乘方
- 阶乘
- 排列数、组合数
- 2 底对数、最近对幂值
统计
- 求和、平均数、最大最小值、方差、标准差
- 求平方和、绝对求和
- 求离散分布函数
排列组合操作
模拟排列组合的操作
矩阵
- 求并集、交集、减集、差集、是否包含
- 求矩阵逆置、转置
- 求矩阵之间的距离、平方距离
- 求矩阵之间对应元素的距离、对应元素的平方距离
- 求矩阵之间绝对值最小距离、绝对值最大距离
- 求矩阵之间自身绝对值最小距离、绝对值最大距离
- 求矩阵轴对称判断
二进制
- 将一个分数转化为二进制下的有限小数
压缩
- 均匀压缩:将一些数据按比例压缩成另一个范围的数据。
- 二值压缩:将一些数据压缩成只有两种取值的数据。
- 合并压缩:将一些数据分组,然后将同一组的数据压缩成一个值。
- 分区压缩:将一些数据分组,然后其统计分布函数。
编码
组合编码
有 n 个号码球,它们的编号分别为 1 ~ n。从这 n 个号码球中组合选 m 个号码,然后对这组号码进行编号。不同的组合对应不同的编号,编号的范围为 [1, C(n,m)]。
二进制编码
有 n 个号码球,它们的编号分别为 1 ~ n。从这 n 个号码球中组合选任意个号码,然后对这组号码进行编号。将这 n 个号码球看成是 n 位的二进制数进行编号。
拓展模块 math-expression
这是一种可以解析表达式的模块。它支持输入一个复杂的表达式,并解析其中的语法错误,然后提示用户在错误处加入修改,直到没有语法错误为止。如果没有语法错误,它会自动计算结果,然后将计算过程输出。支持的功能如下。
-
操作数支持多位运算。一个操作数可以是十位数或者更高位数的数
-
操作数支持小数点、负数,运算结果支持显示小数、分数
-
表达式可以含多个操作数、多个运算符,还可以带括号
-
对输入表达式提供实时自动语法检查与错误定位,并支持检查后的修改
源代码
已上传至 GitHub:https://github.com/wangpai-mathlab/mathlab-fx_java