SuanShu简介

2025/03/27

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数学库进行简单的介绍。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章