001 // --- BEGIN LICENSE BLOCK ---
002 /*
003 * Copyright (c) 2009-2011, Mikio L. Braun
004 * All rights reserved.
005 *
006 * Redistribution and use in source and binary forms, with or without
007 * modification, are permitted provided that the following conditions are
008 * met:
009 *
010 * * Redistributions of source code must retain the above copyright
011 * notice, this list of conditions and the following disclaimer.
012 *
013 * * Redistributions in binary form must reproduce the above
014 * copyright notice, this list of conditions and the following
015 * disclaimer in the documentation and/or other materials provided
016 * with the distribution.
017 *
018 * * Neither the name of the Technische Universit?t Berlin nor the
019 * names of its contributors may be used to endorse or promote
020 * products derived from this software without specific prior
021 * written permission.
022 *
023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
024 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
025 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
026 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
027 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
028 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
029 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
030 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
031 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
032 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
033 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
034 */
035 // --- END LICENSE BLOCK ---
036 package org.jblas.util;
037
038 import org.jblas.ComplexDouble;
039 import org.jblas.ComplexDoubleMatrix;
040 import org.jblas.NativeBlas;
041 import org.jblas.DoubleMatrix;
042
043 /**
044 * Run a few sanity checks on the installation to see whether
045 * everything runs as expected.
046 *
047 * @author Mikio L. Braun
048 */
049 public class SanityChecks {
050
051 public static int checksFailed;
052
053 public static void check(String message, boolean condition) {
054 System.out.print(message + "... ");
055 if (condition) {
056 System.out.println("ok");
057 } else {
058 System.out.println("failed");
059 checksFailed++;
060 }
061 }
062
063 /** Check whether vector addition works. This is pure Java code and should work. */
064 public static void checkVectorAddition() {
065 DoubleMatrix x = new DoubleMatrix(3, 1, 1.0, 2.0, 3.0);
066 DoubleMatrix y = new DoubleMatrix(3, 1, 4.0, 5.0, 6.0);
067 DoubleMatrix z = new DoubleMatrix(3, 1, 5.0, 7.0, 9.0);
068
069 check("checking vector addition", x.add(y).equals(z));
070 }
071
072 /** Check matrix multiplication. This is already ATLAS/BLAS code. */
073 public static void checkMatrixMultiplication() {
074
075 DoubleMatrix A = new DoubleMatrix(new double[][]{
076 {1.0, 2.0, 3.0},
077 {4.0, 5.0, 6.0},
078 {7.0, 8.0, 9.0}
079 });
080 DoubleMatrix E = new DoubleMatrix(new double[][]{
081 {0.0, 0.0, 1.0},
082 {0.0, 1.0, 0.0},
083 {1.0, 0.0, 0.0}
084 });
085 DoubleMatrix B = new DoubleMatrix(new double[][]{
086 {3.0, 2.0, 1.0},
087 {6.0, 5.0, 4.0},
088 {9.0, 8.0, 7.0}
089 });
090
091 check("checking matrix multiplication", A.mmul(E).equals(B));
092 }
093
094 /**
095 * Check whether error handling works. If it works, you should see an
096 * ok, otherwise, you might see the actual error message and then
097 * the program exits.
098 */
099 public static void checkXerbla() {
100 double[] x = new double[9];
101 System.out.println("Check whether we're catching XERBLA errors. If you see something like \"** On entry to DGEMM parameter number 4 had an illegal value\", it didn't work!");
102 try {
103 NativeBlas.dgemm('N', 'N', 3, -1, 3, 1.0, x, 0, 3, x, 0, 3, 0.0, x, 0, 3);
104 } catch (IllegalArgumentException e) {
105 check("checking XERBLA", e.getMessage().contains("XERBLA"));
106 return;
107 }
108 assert (false); // shouldn't happen
109 }
110
111 /**
112 * Compute eigenvalues. This is a routine not in ATLAS, but in the original
113 * LAPACK.
114 */
115 public static void checkEigenvalues() {
116 DoubleMatrix A = new DoubleMatrix(new double[][]{
117 {3.0, 2.0, 0.0},
118 {2.0, 3.0, 2.0},
119 {0.0, 2.0, 3.0}
120 });
121
122 DoubleMatrix E = new DoubleMatrix(3, 1);
123
124 NativeBlas.dsyev('N', 'U', 3, A.data, 0, 3, E.data, 0);
125 check("checking existence of dsyev...", true);
126 }
127
128 public static void checkSVD() {
129 double[][] data = new double[][]{
130 {1.0, 2.0, 3.0},
131 {4.0, 5.0, 6.0},
132 {7.0, 8.0, 9.0},
133 {-1.0, -2.0, -3.0}
134 };
135
136 DoubleMatrix A = new DoubleMatrix(data);
137
138 DoubleMatrix[] USV = org.jblas.Singular.sparseSVD(A);
139 System.out.println(USV[0].toString());
140 System.out.println(USV[1].toString());
141 System.out.println(USV[2].toString());
142
143 System.out.println(org.jblas.Singular.SVDValues(A));
144
145 /*ComplexDoubleMatrix[] AZB = org.jblas.Singular.sparseSVD(new ComplexDoubleMatrix(data));
146 System.out.println(AZB[0].toString());
147 System.out.println(AZB[1].toString());
148 System.out.println(AZB[2].toString());*/
149 check("checking existence of dgesvd...", true);
150 }
151
152 public static void checkGeneralizedEigenvalues() {
153 DoubleMatrix A = new DoubleMatrix(3, 3, 2.0, 1.0, 0.0, 1.0, 2.0, 1.0, 0.0, 1.0, 2.0);
154 DoubleMatrix B = new DoubleMatrix(3, 3, 4.0, 2.0, 1.0, 2.0, 4.0, 2.0, 1.0, 2.0, 4.0);
155
156 DoubleMatrix[] LA = org.jblas.Eigen.symmetricGeneralizedEigenvectors(A, B);
157
158 check("checkign existence of gsyevd (generalized eigenvalues)...", true);
159 }
160
161 public static void checkComplexReturnValues() {
162 double[] data = new double[] {
163 1.0, 2.0, 3.0, 4.0, 5.0, 6.0
164 };
165
166 ComplexDoubleMatrix A = new ComplexDoubleMatrix(data);
167
168 ComplexDouble z = A.dotu(A);
169
170 System.out.print("Checking complex return values... ");
171 System.out.println("(z = " + z.toString() + ")");
172 }
173
174 public static void main(String[] args) {
175 Logger.getLogger().setLevel(Logger.CONFIG);
176 for (String arg : args) {
177 if (arg.equals("--debug")) {
178 Logger.getLogger().setLevel(Logger.DEBUG);
179 }
180 }
181 checkVectorAddition();
182 checkMatrixMultiplication();
183 checkEigenvalues();
184 checkSVD();
185 checkComplexReturnValues();
186 checkXerbla();
187 printSummary();
188 }
189
190 private static void printSummary() {
191 if (checksFailed == 0) {
192 System.out.println("Sanity checks passed.");
193 } else {
194 System.out.println("Sainty checks FAILED!");
195 }
196 }
197 }