Representing a 100K X 100K matrix in Java

后端 未结 9 1992
名媛妹妹
名媛妹妹 2020-12-30 13:45

How can I store a 100K X 100K matrix in Java?

I can\'t do that with a normal array declaration as it is throwing a java.lang.OutofMemoryError.

相关标签:
9条回答
  • 2020-12-30 14:13

    Well, I'd suggest that you increase the memory in your jvm but you've going to need a lot of memory, as you're talking about 10 billion items. It's (barely) possible with lots of memory or a clustered jvm, but that's probably the wrong answer.

    • You're getting the outOfmemory because if you declare int[1000], the memory is allocated immediately (additionally doubles take up more space than ints-an int representation will also save you space). Maybe you can substitute a more efficient implementation of your array (if you have many empty entries lookup "sparse matrix" representations).

    • You could store pieces in an outside system, like memcached or memory-mapped buffers.

    There are lots of good suggestions here, maybe if you posted a more detailed description of the problem you're trying to solve people could be more specific.

    0 讨论(0)
  • 2020-12-30 14:14

    You should try an "external" package to handle matrices, I never did that though, maybe something like jama.

    0 讨论(0)
  • 2020-12-30 14:19

    Sounds like you need a sparse matrix. Others have already suggested good 3rd party implementations that may suite your needs...

    Depending on your applications, you could get away without a third-party matrix library by just using a Map as a backing-store for your matrix data. Kind of...

    public class SparseMatrix<T> {
        private T defaultValue;
        private int m;
        private int n;
        private Map<Integer, T> data = new TreeMap<Integer, T>();
        /// create a new matrix with m rows and n columns
        public SparseMatrix(int m, int n, T defaultValue) {
            this.m = m;
            this.n = n;
            this.defaultValue = defaultValue;
        }
        /// set value at [i,j] (row, col)
        public void setValueAt(int i, int j, T value) {
            if (i >= m || j >= n || i < 0 || j < 0) 
                throw new IllegalArgumentException(
                        "index (" + i + ", " +j +") out of bounds");        
            data.put(i * n + j, value);
        }
        /// retrieve value at [i,j] (row, col)
        public T getValueAt(int i, int j) {
            if (i >= m || j >= n || i < 0 || j < 0) 
                throw new IllegalArgumentException(
                        "index (" + i + ", " +j +") out of bounds");
            T value = data.get(i * n + j);
            return value != null ? value : defaultValue;
        }
    }
    

    A simple test-case illustrating the SparseMatrix' use would be:

    public class SparseMatrixTest extends TestCase {
        public void testMatrix() {
            SparseMatrix<Float> matrix = 
                new SparseMatrix<Float>(100000, 100000, 0.0F);
            matrix.setValueAt(1000, 1001, 42.0F);
            assertTrue(matrix.getValueAt(1000,1001) == 42.0);
            assertTrue(matrix.getValueAt(1001,1000) == 0.0);        
        }   
    }
    

    This is not the most efficient way of doing it because every non-default entry in the matrix is stored as an Object. Depending on the number of actual values you are expecting, the simplicity of this approach might trump integrating a 3rd-party solution (and possibly dealing with its License - again, depending on your situation).

    Adding matrix-operations like multiplication to the above SparseMatrix implementation should be straight-forward (and is left as an exercise for the reader ;-)

    0 讨论(0)
提交回复
热议问题