File: TestRandomMatrices_DSCC.java

package info (click to toggle)
libejml-java 0.41%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, trixie
  • size: 7,376 kB
  • sloc: java: 82,734; python: 81; makefile: 22
file content (175 lines) | stat: -rw-r--r-- 6,103 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/*
 * Copyright (c) 2020, Peter Abeles. All Rights Reserved.
 *
 * This file is part of Efficient Java Matrix Library (EJML).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.ejml.sparse.csc;

import org.ejml.UtilEjml;
import org.ejml.data.DMatrixSparseCSC;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.util.Random;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.*;

/**
 * @author Peter Abeles
 */
@SuppressWarnings("UnusedMethod")
public class TestRandomMatrices_DSCC {
    Random rand = new Random(324);

    @Test
    void uniform() {
        int numRows = 6;
        int numCols = 7;

        DMatrixSparseCSC a = RandomMatrices_DSCC.rectangle(numRows, numCols, 10, -1, 1, rand);

        assertEquals(numRows, a.numRows);
        assertEquals(numCols, a.numCols);
        assertEquals(10, a.nz_length);
        assertTrue(CommonOps_DSCC.checkStructure(a));

        int count = 0;
        for (int row = 0; row < numRows; row++) {
            for (int col = 0; col < numCols; col++) {
                double value = a.get(row, col);

                if (value == 0)
                    continue;
                if (value > 1 || value < -1)
                    fail("Out of expected range");
                count++;
            }
        }

        assertEquals(10, count);
        assertTrue(CommonOps_DSCC.checkSortedFlag(a));
    }

    /**
     * There was a bug where the rows and columns multiplied together caused an overflow
     */
    @Test
    void rectangle_large() {
        assertThrows(IllegalArgumentException.class, () ->
                RandomMatrices_DSCC.rectangle(1_000_000, 1_000_000, 10, -1, 1, rand));
    }

    private static Stream<Arguments> randomMatrixDimensions() {
        int[] rowCounts = {1, 10, 15, 100, 1000};
        int[] colCounts = {1, 10, 15, 100, 1000};
        double[] densities = {1, 0.8, 0.2, 0.01};

        Stream.Builder<Arguments> streamBuilder = Stream.builder();

        for (int rowCount : rowCounts) {
            for (int colCount : colCounts) {
                for (double density : densities) {
                    streamBuilder.accept(Arguments.of(rowCount, colCount, (int)Math.round(density*rowCount)));
                }
            }
        }

        return streamBuilder.build();
    }

    @ParameterizedTest
    @MethodSource("randomMatrixDimensions")
    void generateUniform( int numRows, int numCols, int entriesPerColumn ) {
        DMatrixSparseCSC a = RandomMatrices_DSCC.generateUniform(numRows, numCols, entriesPerColumn, -1, 1, rand);

        assertEquals(entriesPerColumn*numCols, a.nz_length);
        assertTrue(CommonOps_DSCC.checkStructure(a));
    }

    @Test
    void createLowerTriangular() {
        DMatrixSparseCSC L;
        for (int trial = 0; trial < 20; trial++) {
            for (int length : new int[]{0, 2, 6, 12, 20}) {
                L = RandomMatrices_DSCC.triangleLower(6, 0, length, -1, 1, rand);

                assertEquals(Math.max(6, length), L.nz_length);
                assertTrue(CommonOps_DSCC.checkStructure(L));
                assertTrue(MatrixFeatures_DSCC.isLowerTriangle(L, 0, 0.0));

                L = RandomMatrices_DSCC.triangleLower(6, 1, length, -1, 1, rand);
                assertEquals(Math.max(5, length), L.nz_length);
                assertTrue(CommonOps_DSCC.checkStructure(L));
                assertTrue(MatrixFeatures_DSCC.isLowerTriangle(L, 1, 0.0));

                assertFalse(CommonOps_DSCC.checkDuplicateElements(L));
            }
        }
    }

    @Test
    void symmetric() {
        for (int N = 1; N <= 10; N++) {
            for (int mc = 0; mc < 30; mc++) {
                int nz = (int)(N*N*0.5*(rand.nextDouble()*0.5 + 0.1) + 0.5);
                nz = Math.max(1, nz);
                DMatrixSparseCSC A = RandomMatrices_DSCC.symmetric(N, nz, -1, 1, rand);

                assertTrue(CommonOps_DSCC.checkStructure(A));

                // Sanity check to see if it's obeying the requested number of non-zero elements
                assertTrue(A.nz_length >= nz && A.nz_length <= 2*nz);

                // Check the matrix properties
                assertTrue(MatrixFeatures_DSCC.isSymmetric(A, UtilEjml.TEST_F64));
            }
        }
    }

    /**
     * There was a bug where the rows and columns multiplied together caused an overflow
     */
    @Test
    void symmetric_large() {
        assertThrows(IllegalArgumentException.class, () ->
                RandomMatrices_DSCC.symmetric(1_000_000, 10, -1, 1, rand));
    }

    @Test
    void symmetricPosDef() {
        double probabilityZero = 0.25;

        for (int N = 1; N <= 10; N++) {
            for (int mc = 0; mc < 30; mc++) {
                DMatrixSparseCSC A = RandomMatrices_DSCC.symmetricPosDef(N, probabilityZero, rand);

                assertTrue(CommonOps_DSCC.checkStructure(A));

                // The upper limit is  bit fuzzy. This really just checks to see if it's exceeded by an extreme amount
                assertTrue(A.nz_length <= (int)Math.ceil(N*N*(1.0 - probabilityZero)) + N);

                // Extremely crude check to see if the size is above a lower limit. In theory it could be full of
                // zeros and that would still be valid.
                assertTrue(A.nz_length >= N*N*(probabilityZero/5.0));

                assertTrue(MatrixFeatures_DSCC.isPositiveDefinite(A));
            }
        }
    }
}