1. Introduction
1.介绍
The SuanShu is a Java math library for numerical analysis, statistics, root finding, linear algebra, optimization, and lots more. One of the things it provides is functionality for both real and complex numbers.
SuanShu是一个Java数学库,用于数值分析、统计、寻根、线性代数、优化等。它提供的功能之一是实数和复数。
There’s an open-source version of the library, as well as a version that requires a license -with different forms of the license: academic, commercial, and contributor.
该库有一个开源版本,也有一个需要许可证的版本–有不同形式的许可证:学术、商业和贡献者。
Note that the examples below use the licensed version through the pom.xml. The open-source version is currently not available in a Maven repository; the licensed version requires a license server to be running. As a result, there aren’t any tests for this package in GitHub.
请注意,下面的例子是通过pom.xml使用许可版本。开源版本目前在Maven仓库中无法使用;授权版本需要运行授权服务器。因此,GitHub上没有这个包的任何测试。
2. Setup for SuanShu
2.SuanShu的设置
Let’s start with adding the Maven dependency to the pom.xml:
我们先在pom.xml中加入Maven的依赖。
<dependencies>
<dependency>
<groupId>com.numericalmethod</groupId>
<artifactId>suanshu</artifactId>
<version>4.0.0</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>nm-repo</id>
<name>Numerical Method's Maven Repository</name>
<url>http://repo.numericalmethod.com/maven/</url>
<layout>default</layout>
</repository>
</repositories>
3. Working With Vectors
3.使用载体
The SuanShu library provides classes for both dense vectors and sparse vectors. A dense vector is a vector where most elements have a non-zero value, as opposed to a sparse vector where most values have a zero value.
SuanShu库为密集向量和稀疏向量提供了类。密集向量是一个大多数元素都有非零值的向量,而稀疏向量则是大多数值都是零值。
The implementation of a dense vector simply uses a Java array of real/complex numbers while the implementation of a sparse vector uses a Java array of entries, where each entry has an index and a real/complex value.
密集向量的实现只是使用一个实数/复数的Java数组,而稀疏向量的实现则使用一个entries的Java数组,其中每个entry有一个索引和一个实数/复数值。
We can see how that would make a huge difference in storage when we have a large vector where most values are zero. Most mathematical libraries use an approach like this when they need to support vectors of large sizes.
我们可以看到,当我们有一个大部分数值为零的大向量时,这在存储方面会有很大的不同。大多数数学库在需要支持大尺寸的向量时都会使用这样的方法。
Let’s look at some of the basic vector operations.
让我们来看看一些基本的矢量操作。
3.1. Adding Vectors
3.1.添加矢量
Adding 2 vectors is pretty straightforward using the add() method:
使用add()方法将2个向量相加是非常直接的。
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);
}
The output we’ll see is:
我们将看到的输出是。
[6.000000, 6.000000, 6.000000, 6.000000, 6.000000]
We can also add the same numbers to all elements using the add(double) method.
我们也可以使用add(double)方法将相同的数字添加到所有元素中。
3.2. Scaling Vectors
3.2.缩放向量
Scaling a vector (i.e. multiplying by a constant) is also very easy:
缩放一个向量(即乘以一个常数)也非常容易。
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);
}
The output:
产出。
[2.000000, 4.000000, 6.000000, 8.000000, 10.000000]
3.3. Vector Inner Product
3.3.矢量内积
Calculating the inner product of 2 vectors requires a call to the innerProduct(Vector) method:
计算2个向量的内积需要调用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. Dealing With Errors
3.4.处理错误
The library verifies that the vectors we are operating on are compatible with the operation we are executing. For instance, adding a size-2 vector to a size-3 vector should not be possible. So the code below should result in an exception:
该库验证了我们所操作的向量与我们所执行的操作是兼容的。例如,将一个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);
}
And indeed it does – running this code results in:
而且确实如此–运行这段代码的结果是。
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 com.baeldung.suanshu.SuanShuMath.addingIncorrectVectors(SuanShuMath.java:21)
at com.baeldung.suanshu.SuanShuMath.main(SuanShuMath.java:8)
4. Working With Matrices
4.用矩阵工作
In addition to vectors, the library also provides support for matrix operations. Similar to vectors, matrices are supported in dense and sparse format, and for real and complex numbers.
除了向量,库还提供对矩阵操作的支持。与向量类似,矩阵支持密集和稀疏格式,以及实数和复数。
4.1. Adding Matrices
4.1.添加矩阵
Adding matrices is just as simple as working with vectors:
添加矩阵就像处理向量一样简单。
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. Multiplying Matrices
4.2.矩阵相乘
The math library can be used to multiply matrices:
数学库可以用来进行矩阵相乘。
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);
}
Multiplying a 2×3 matrix with a 3×2 matrix will result in a 2×2 matrix.
2×3矩阵与3×2矩阵相乘,将得到一个2×2矩阵。
And to prove the library does proper checks of the matrix sizes, let’s try to do a multiplication that should fail:
为了证明该库对矩阵大小做了适当的检查,让我们尝试做一个应该失败的乘法。
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);
}
Executing that will result in the following output.
执行该命令将导致以下输出。
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 com.baeldung.suanshu.SuanShuMath.multiplyIncorrectMatrices(SuanShuMath.java:98)
at com.baeldung.suanshu.SuanShuMath.main(SuanShuMath.java:22)
4.3. Calculating a Matrix Inverse
4.3.计算矩阵的逆运算
Calculating the inverse of a matrix can be a lengthy process to do manually but the SuanShu math library makes it easy:
计算矩阵的逆值可能是一个漫长的手工操作过程,但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);
}
We can verify this using the SuanShu library but multiplying the matrix with its inverse: the result should be the identity matrix. We can do this by adding the following to the method above:
我们可以使用SuanShu库来验证这一点,但要将矩阵与它的逆数相乘:结果应该是身份矩阵。我们可以通过在上面的方法中加入以下内容来实现这一点。
log.info("Verifying a matrix inverse: {}", m1.multiply(m2));
5. Solving Polynomials
5.求解多项式
One of the other areas the SuanShu provides support for is polynomials. It provides methods for evaluating a polynomial but also for finding its root (input values where the polynomial evaluates to 0).
SuanShu提供支持的其他领域之一是多项式。它提供了评估多项式的方法,但也提供了寻找其根(多项式评估为0的输入值)的方法。
5.1. Creating a Polynomial
5.1.创建一个多项式
A polynomial can be created by specifying its coefficients. So a polynomial like 3x2-5x+1 can be created with:
一个多项式可以通过指定其系数来创建。所以像3x2-5x+1这样的多项式可以通过以下方式创建。
public Polynomial createPolynomial() {
return new Polynomial(new double[]{3, -5, 1});
}
As we can see, we start with the coefficient for the highest degree first.
我们可以看到,我们首先从最高学位的系数开始。
5.2. Evaluating a Polynomial
5.2.评估多项式
The evaluate() method can be used to evaluate the polynomial. This can be done for real and complex inputs.
evaluate()方法可以用来评估多项式。这可以针对实数和复数输入进行。
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)));
}
The output we’ll see is:
我们将看到的输出是。
51.0
-13.000000+2.000000i
5.3. Finding a Polynomial’s Roots
5.3.寻找多项式的根
Finding a polynomial’s roots is made easy by the SuanShu math library. It provides well-known algorithms to determine the roots for polynomials of various degrees and based on the highest degree of the polynomial, the PolyRoot class chooses the best method:
通过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);
}
The output:
产出。
[-2.0, 1.0]
So 2 real roots were found for this sample polynomial: -2 and 1. Naturally, complex roots are supported as well.
所以这个多项式的样本有两个实数根。-当然,复数根也是支持的。
6. Conclusion
6.结论
This article is just a short introduction to the SuanShu math library.
这篇文章只是对SuanShu数学库的一个简短介绍。
As always, the full source code of the article is available over on GitHub.
一如既往,该文章的完整源代码可在GitHub上获得。