Java中大型稀疏矩阵的Cholesky分解

时间:2015-04-13 11:46:15

标签: java matrix linear-algebra colt matrix-factorization

我想在Java中对大型稀疏矩阵进行Cholesky分解。目前我正在使用Parallel Colt库类SparseDoubleCholeskyDecomposition,但它比使用my code I wrote in C for dense matrices which I use in java with JNI要慢得多。

例如对于具有非零密度0.25%的5570x5570矩阵,使用SparseDoubleCholeskyDecomposition需要 26.6秒因子,并且使用密集存储的同一矩阵的我自己的代码只需 1.12秒< / strong>即可。但是,如果我将密度设置为0.025%,那么colt库只需0.13秒。

我还使用compressed row storage和OpenMP在C中编写了自己的稀疏矩阵Cholesky分解,它比SparseDoubleCholeskyDecomposition快得多,但仍然比使用密集存储的算法慢。我可以进一步优化它,但无论如何Cholesky因子是密集的,所以它既不能解决速度也不能解决存储问题。

但是我希望时间在几毫秒内,我最终需要扩展到超过10000x10000矩阵,所以即使我自己的密集矩阵密集代码也会变得太慢并且使用太多内存。

I have reason to believe the Cholesky decomposition of sparse matrices can be done much faster and use less memory。也许我需要better Java BLAS library?是否有一个Java库可以有效地对稀疏矩阵进行Cholesky分解?也许我没有最佳地使用Parallel Colt?

import cern.colt.matrix.tdouble.algo.decomposition.SparseDoubleCholeskyDecomposition;
import cern.colt.matrix.tdouble.impl.*;
import java.util.Random;

public class Cholesky {
    static SparseRCDoubleMatrix2D create_sparse(double[] a, int n, double r) {
        SparseRCDoubleMatrix2D result = new SparseRCDoubleMatrix2D(n, n);
        Random rand = new Random();
        for(int i=0; i<n; i++) {
            for(int j=i; j<n; j++) {
                double c = rand.nextDouble();
                double element = c<r ? rand.nextDouble() : 0;
                a[i*n+j] = element;
                a[j*n+i] = element;
                if (element != 0) {
                    result.setQuick(i, j, element);
                    result.setQuick(j, i, element);
                }
            }
        }
        for(int i=0; i<n; i++) {
            a[i * n + i] += n;
            result.setQuick(i,i, result.getQuick(i,i) + n);
        }
        return result;
    }

    public static void main(String[] args) {
        int n = 5570;
        //int n = 2048;
        double[] a = new double[n*n];
        SparseRCDoubleMatrix2D sparseMatrix = create_sparse(a, n, 0.0025);

        long startTime, endTime, duration;

        startTime = System.nanoTime();
        SparseDoubleCholeskyDecomposition sparseDoubleCholeskyDecomposition = new SparseDoubleCholeskyDecomposition(sparseMatrix, 0);
        endTime = System.nanoTime();
        duration = (endTime - startTime);
        System.out.printf("colt time construct %.2f s\n", 1E-9*duration);
    }
}

0 个答案:

没有答案