1. 简介
SuanShu是一个Java数学库,用于数值分析、统计、求根、线性代数、优化等,它提供的功能之一是实数和复数的功能。
该库有一个开源版本,还有一个需要许可证的版本-许可证有不同的形式:学术、商业和贡献者。
请注意,以下示例通过pom.xml使用许可版本的分支。开源版本目前在Maven仓库中不可用;许可版本需要运行许可服务器。因此,GitHub中没有针对此包的任何测试。
2. 设置SuanShu
让我们首先将Maven依赖添加到pom.xml:
<dependency>
<groupId>io.deephaven</groupId>
<artifactId>SuanShu</artifactId>
<version>0.1.0</version>
</dependency>
3. 使用向量
SuanShu库提供了密集向量和稀疏向量的类。密集向量是大多数元素都具有非零值的向量,而稀疏向量则是大多数元素都具有零值的向量。
密集向量的实现仅使用实数/复数的Java数组,而稀疏向量的实现使用条目的Java数组,其中每个条目都有一个索引和一个实数/复数值。
我们可以看到,当我们有一个大多数值为零的大向量时,这将对存储产生巨大的影响。大多数数学库在需要支持大尺寸向量时都使用这种方法。
让我们看一些基本的向量运算。
3.1 相加向量
使用add()方法相加两个向量非常简单:
public void addingVectors() throws Exception {
Vector v1 = new DenseVector(new double[] {1, 2, 3, 4, 5});
Vector v2 = new DenseVector(new double[] {5, 4, 3, 2, 1});
Vector v3 = v1.add(v2);
log.info("Adding vectors: {}", v3);
}
我们将看到的输出是:
[6.000000, 6.000000, 6.000000, 6.000000, 6.000000]
我们还可以使用add(double)方法将相同的数字相加到所有元素。
3.2 缩放向量
缩放向量(即乘以常数)也很容易:
public void scaleVector() throws Exception {
Vector v1 = new DenseVector(new double[]{1, 2, 3, 4, 5});
Vector v2 = v1.scaled(2.0);
log.info("Scaling a vector: {}", v2);
}
输出:
[2.000000, 4.000000, 6.000000, 8.000000, 10.000000]
3.3 向量内积
计算两个向量的内积需要调用innerProduct(Vector)方法:
public void innerProductVectors() throws Exception {
Vector v1 = new DenseVector(new double[]{1, 2, 3, 4, 5});
Vector v2 = new DenseVector(new double[]{5, 4, 3, 2, 1});
double inner = v1.innerProduct(v2);
log.info("Vector inner product: {}", inner);
}
3.4 处理错误
该库会验证我们正在操作的向量是否与我们正在执行的操作兼容。例如,将大小为2的向量添加到大小为3的向量是不可能实现的。因此,下面的代码应该会导致异常:
public void addingIncorrectVectors() throws Exception {
Vector v1 = new DenseVector(new double[] {1, 2, 3});
Vector v2 = new DenseVector(new double[] {5, 4});
Vector v3 = v1.add(v2);
}
事实确实如此-运行此代码的结果是:
Exception in thread "main" com.numericalmethod.suanshu.vector.doubles.IsVector$SizeMismatch: vectors do not have the same size: 3 and 2
at com.numericalmethod.suanshu.vector.doubles.IsVector.throwIfNotEqualSize(IsVector.java:101)
at com.numericalmethod.suanshu.vector.doubles.dense.DenseVector.add(DenseVector.java:174)
at cn.tuyucheng.taketoday.suanshu.SuanShuMath.addingIncorrectVectors(SuanShuMath.java:21)
at cn.tuyucheng.taketoday.suanshu.SuanShuMath.main(SuanShuMath.java:8)
4. 使用矩阵
除了向量之外,该库还提供对矩阵运算的支持。与向量类似,矩阵也支持密集和稀疏格式,以及实数和复数。
4.1 相加矩阵
相加矩阵就像处理向量一样简单:
public void addingMatrices() throws Exception {
Matrix m1 = new DenseMatrix(new double[][]{
{1, 2, 3},
{4, 5, 6}
});
Matrix m2 = new DenseMatrix(new double[][]{
{3, 2, 1},
{6, 5, 4}
});
Matrix m3 = m1.add(m2);
log.info("Adding matrices: {}", m3);
}
4.2 矩阵相乘
数学库可用于乘以矩阵:
public void multiplyMatrices() throws Exception {
Matrix m1 = new DenseMatrix(new double[][]{
{1, 2, 3},
{4, 5, 6}
});
Matrix m2 = new DenseMatrix(new double[][]{
{1, 4},
{2, 5},
{3, 6}
});
Matrix m3 = m1.multiply(m2);
log.info("Multiplying matrices: {}", m3);
}
将2×3矩阵与3×2矩阵相乘将得到2×2矩阵。
为了证明该库对矩阵大小进行了适当的检查,让我们尝试进行一次应该会失败的乘法:
public void multiplyIncorrectMatrices() throws Exception {
Matrix m1 = new DenseMatrix(new double[][]{
{1, 2, 3},
{4, 5, 6}
});
Matrix m2 = new DenseMatrix(new double[][]{
{3, 2, 1},
{6, 5, 4}
});
Matrix m3 = m1.multiply(m2);
}
执行该命令将产生以下输出。
Exception in thread "main" com.numericalmethod.suanshu.matrix.MatrixMismatchException:
matrix with 3 columns and matrix with 2 rows cannot multiply due to mis-matched dimension
at com.numericalmethod.suanshu.datastructure.DimensionCheck.throwIfIncompatible4Multiplication(DimensionCheck.java:164)
at com.numericalmethod.suanshu.matrix.doubles.matrixtype.dense.DenseMatrix.multiply(DenseMatrix.java:374)
at cn.tuyucheng.taketoday.suanshu.SuanShuMath.multiplyIncorrectMatrices(SuanShuMath.java:98)
at cn.tuyucheng.taketoday.suanshu.SuanShuMath.main(SuanShuMath.java:22)
4.3 计算矩阵逆
手动计算矩阵的逆可能是一个漫长的过程,但SuanShu数学库可以让它变得简单:
public void inverseMatrix() {
Matrix m1 = new DenseMatrix(new double[][]{
{1, 2},
{3, 4}
});
Inverse m2 = new Inverse(m1);
log.info("Inverting a matrix: {}", m2);
}
我们可以使用SuanShu库来验证这一点,但要将矩阵与其逆相乘:结果应该是单位矩阵,我们可以通过将以下内容添加到上述方法中来实现这一点:
log.info("Verifying a matrix inverse: {}", m1.multiply(m2));
5. 解多项式
SuanShu提供支持的另一个领域是多项式,它不仅提供求多项式的方法,还提供求根的方法(多项式求值为0的输入值)。
5.1 创建多项式
可以通过指定多项式的系数来创建多项式。因此,可以使用以下公式创建多项式,例如3x2 -5x + 1:
public Polynomial createPolynomial() {
return new Polynomial(new double[]{3, -5, 1});
}
我们可以看到,我们首先从最高次数的系数开始。
5.2 求多项式的值
可以使用valuate()方法来求多项式的值,这可以针对实数和复数输入进行。
public void evaluatePolynomial(Polynomial p) {
log.info("Evaluating a polynomial using a real number: {}", p.evaluate(5));
log.info("Evaluating a polynomial using a complex number: {}", p.evaluate(new Complex(1, 2)));
}
我们将看到的输出是:
51.0
-13.000000+2.000000i
5.3 求多项式的根
SuanShu数学库让查找多项式的根变得简单,它提供了众所周知的算法来确定不同次数的多项式的根,并且根据多项式的最高次数,PolyRoot类选择最佳方法:
public void solvePolynomial() {
Polynomial p = new Polynomial(new double[]{2, 2, -4});
PolyRootSolver solver = new PolyRoot();
List<? extends Number> roots = solver.solve(p);
log.info("Finding polynomial roots: {}", roots);
}
输出:
[-2.0, 1.0]
因此,对于这个示例多项式,我们发现了2个实根:-2和1。当然,也支持复根。
6. 总结
本文只是对SuanShu数学库进行简单的介绍。
Post Directory
