1

我在java中编写了这种用于LDL^T分解的方法(它将对称对称矩阵“A”分解为3个矩阵,其中“L”是对角线为1的下三角矩阵,“D”是具有正项的对角矩阵和“L^T”是L)的转置矩阵。想知道是否可以在同一方法中返回 L 和 D 矩阵,如果不是,我该如何拆分此方法。遵循我教科书中的算法(Faires and Douglas 第 9 版第 417 页的数值分析),我的代码仍然有一些我必须弄清楚的逻辑缺陷。所以我的问题是/是我可以在同一方法中返回两种不同类型的数组吗( L[][] 和 D[] 在同一时间所以 D 只返回对角线元素作为一个数组和 L 返回整个矩阵)和/或如何拆分此方法。

public static double[][] Lfactor(double[][] A) {
    if (!isSquare(A)) {
        throw new RuntimeException("Matrix is not square");
    }
    if (!isSymmetric(A)) {
        throw new RuntimeException("Matrix is not symmetric");
    }
    int N = A.length;
    double[][] L = new double[N][N];
    double[] V = new double[N];
    double[] D = new double[N];
    for(int i=1; i <= N; i++ ){
        for(int j=1; j<=i-1;j++){
            V[j]= L[i][j]*D[j];
            double Sum1 = 0.0;
             Sum1+= L[i][j] * V[j];
             D[i] = A[i][i] - Sum1;
        for( j=i+1; j<=N;j++){
            for(int k = 1; k<=i-1; k++){
            double Sum2 = 0.0;
            Sum2 += L[j][k]*V[k];
            L[j][i]= (A[j][i] - Sum2)/D[i];
                    }
        }
    }
}
    return L;}
4

6 回答 6

0

适当的编程语言具有 Tuple 类型,非常适合这种用途。但Java没有。因此,您可以像这样模拟自己的 Pair (通常称为两个元组):

public static class Tuple<T, U> {
  public final T _1;
  public final U _2;
  public Tuple(T arg1, U arg2) {
    super();
    this._1 = arg1;
    this._2 = arg2;
  }
}

并将其用作返回值。

于 2015-01-11T11:29:36.303 回答
0

您可以将代码放在 Result 类中。

class LFactor {
    public final double[] L[], V, D;

    public LFactor(double[][] A) {
        if (!isSquare(A)) {
            throw new RuntimeException("Matrix is not square");
        }
        if (!isSymmetric(A)) {
            throw new RuntimeException("Matrix is not symmetric");
        }
        int N = A.length;
        L = new double[N][N];
        V = new double[N];
        D = new double[N];
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= i - 1; j++) {
                V[j] = L[i][j] * D[j];
                double Sum1 = 0.0;
                Sum1 += L[i][j] * V[j];
                D[i] = A[i][i] - Sum1;
                for (j = i + 1; j <= N; j++) {
                    for (int k = 1; k <= i - 1; k++) {
                        double Sum2 = 0.0;
                        Sum2 += L[j][k] * V[k];
                        L[j][i] = (A[j][i] - Sum2) / D[i];
                    }
                }
            }
        }
    }
}

顺便提一句

double Sum1 = 0.0;
Sum1 += L[i][j] * V[j];
D[i] = A[i][i] - Sum1;

是相同的

D[i] = A[i][i] - L[i][j] * V[j];

这是你的意图吗?

如果您使用,您的循环也可能会更简单

for (int i = 0; i < N; i++) {

因为这是索引的范围。

于 2015-01-11T11:32:26.777 回答
0

您可以创建一个包含 L 和 D 矩阵作为类成员的类,然后返回该类的一个实例。

使用这种方法,您可以将该算法作为方法合并到类中,并提供单独的方法来检索 L、D 和转置的 L 矩阵。

例如,一个类如下:

public class LDLT
{
    private double[][] l;
    private double[][] d;

    public void calculate(double[][] a)
    {
        // calculate, and store in l and d...
    }

    public double[][] getL()
    {
        return l;
    }

    public double[][] getD()
    {
        return d;
    }

    public double[][] getTransposedL()
    {
        // calculate and transpose the l matrix...
    }
}
于 2015-01-11T11:20:51.387 回答
0

您只能在方法中返回一个变量。有几种方法可以获取这两个值,但我这样做的方法是创建一个名为 LDArray 之类的新类,该类将包含两个数组 L 和 D,以及两者的 getter/setter数组。这样,您可以简单地更改您的方法以返回 LDArray 并将两个数组发布到一个对象中。

于 2015-01-11T11:21:54.873 回答
0

您可以返回一个 s 数组Object,其中包含Land D,尽管@Alan 的建议更安全。

于 2015-01-11T11:22:48.623 回答
0

不用多想,只需创建一个类(可能是内部类),将其命名为 DecompositionResults,并为其提供两个公共成员:D 和 L。然后将计算矩阵分配给该类的新对象并返回它。

或者,由于 L 在概念上是二维的,而 D 是一维的,因此只需返回一个大小为 N+1 x N 的二维数组,其中最后/第一行是 D。

于 2015-01-11T11:26:47.467 回答