| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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.apache.s4.util; |
| |
| import java.util.Random; |
| |
| import org.ejml.data.D1Matrix64F; |
| import org.ejml.data.DenseMatrix64F; |
| |
| /** |
| * Extensions to the EJML library. |
| * |
| * @author Leo Neumeyer |
| */ |
| public class MatrixOps { |
| |
| /** |
| * <p> |
| * Performs an in-place element by element natural logarithm operation.<br> |
| * <br> |
| * a<sub>ij</sub> = log(a<sub>ij</sub>) |
| * </p> |
| * |
| * @param a |
| * The matrix on which we perform the log. Modified. |
| */ |
| public static void elementLog(D1Matrix64F a) { |
| final int size = a.getNumElements(); |
| |
| for (int i = 0; i < size; i++) { |
| a.set(i, Math.log(a.get(i))); |
| } |
| } |
| |
| /** |
| * <p> |
| * Performs an element by element natural logarithm operation.<br> |
| * <br> |
| * b<sub>ij</sub> = log(a<sub>ij</sub>) |
| * </p> |
| * |
| * @param a |
| * The matrix on which we perform the log. Not Modified. |
| * @param b |
| * Where the results of the operation are stored. Modified. |
| */ |
| public static void elementLog(D1Matrix64F a, D1Matrix64F b) { |
| if (a.numRows != b.numRows || a.numCols != b.numCols) |
| throw new IllegalArgumentException( |
| "Matrices must have the same shape"); |
| |
| final int size = a.getNumElements(); |
| |
| for (int i = 0; i < size; i++) { |
| b.set(i, Math.log(a.get(i))); |
| } |
| } |
| |
| /** |
| * <p> |
| * Performs an in-place element by element exponential function.<br> |
| * <br> |
| * a<sub>ij</sub> = exp(a<sub>ij</sub>) |
| * </p> |
| * |
| * @param a |
| * The matrix on which we perform the exponentiation. Modified. |
| */ |
| public static void elementExp(D1Matrix64F a) { |
| final int size = a.getNumElements(); |
| |
| for (int i = 0; i < size; i++) { |
| a.set(i, Math.exp(a.get(i))); |
| } |
| } |
| |
| /** |
| * <p> |
| * Performs an element by element natural exponential function.<br> |
| * <br> |
| * b<sub>ij</sub> = exp(a<sub>ij</sub>) |
| * </p> |
| * |
| * @param a |
| * The matrix on which we perform the exponentiation. Not |
| * Modified. |
| * @param b |
| * Where the results of the operation are stored. Modified. |
| */ |
| public static void elementExp(D1Matrix64F a, D1Matrix64F b) { |
| if (a.numRows != b.numRows || a.numCols != b.numCols) |
| throw new IllegalArgumentException( |
| "Matrices must have the same shape"); |
| |
| final int size = a.getNumElements(); |
| |
| for (int i = 0; i < size; i++) { |
| b.set(i, Math.exp(a.get(i))); |
| } |
| } |
| |
| /** |
| * <p> |
| * Performs an in-place element by element square operation.<br> |
| * <br> |
| * a<sub>ij</sub> = a<sub>ij</sub>^2 |
| * </p> |
| * |
| * @param a |
| * The matrix on which we perform the square. Modified. |
| */ |
| public static void elementSquare(D1Matrix64F a) { |
| final int size = a.getNumElements(); |
| |
| for (int i = 0; i < size; i++) { |
| a.set(i, a.get(i) * a.get(i)); |
| } |
| } |
| |
| /** |
| * <p> |
| * Performs an element by element square.<br> |
| * <br> |
| * b<sub>ij</sub> = a<sub>ij</sub>^2 |
| * </p> |
| * |
| * @param a |
| * The matrix on which we perform the square. Not Modified. |
| * @param b |
| * Where the results of the operation are stored. Modified. |
| */ |
| public static void elementSquare(D1Matrix64F a, D1Matrix64F b) { |
| if (a.numRows != b.numRows || a.numCols != b.numCols) |
| throw new IllegalArgumentException( |
| "Matrices must have the same shape"); |
| |
| final int size = a.getNumElements(); |
| |
| for (int i = 0; i < size; i++) { |
| b.set(i, a.get(i) * a.get(i)); |
| } |
| } |
| |
| /** |
| * <p> |
| * Performs an in-place element by element square root operation.<br> |
| * <br> |
| * a<sub>ij</sub> = sqrt(a<sub>ij</sub>) |
| * </p> |
| * |
| * @param a |
| * The matrix on which we perform the square root. Modified. |
| */ |
| public static void elementSquareRoot(D1Matrix64F a) { |
| final int size = a.getNumElements(); |
| |
| for (int i = 0; i < size; i++) { |
| a.set(i, Math.sqrt(a.get(i))); |
| } |
| } |
| |
| /** |
| * <p> |
| * Performs an element by element square root.<br> |
| * <br> |
| * b<sub>ij</sub> = sqrt(<sub>ij</sub>) |
| * </p> |
| * |
| * @param a |
| * The matrix on which we perform the square root. Not Modified. |
| * @param b |
| * Where the results of the operation are stored. Modified. |
| */ |
| public static void elementSquareRoot(D1Matrix64F a, D1Matrix64F b) { |
| if (a.numRows != b.numRows || a.numCols != b.numCols) |
| throw new IllegalArgumentException( |
| "Matrices must have the same shape"); |
| |
| final int size = a.getNumElements(); |
| |
| for (int i = 0; i < size; i++) { |
| b.set(i, Math.sqrt(a.get(i))); |
| } |
| } |
| |
| /** |
| * <p> |
| * Set a floor value for the matrix elements.<br> |
| * |
| * @param floor |
| * The minimum element value. |
| * @param a |
| * The input matrix. Not Modified. |
| * @param b |
| * Matrix whose elements with values less than floor are set to |
| * floor. Modified. |
| */ |
| public static void elementFloor(double floor, D1Matrix64F a, D1Matrix64F b) { |
| if (a.numRows != b.numRows || a.numCols != b.numCols) |
| throw new IllegalArgumentException( |
| "Matrices must have the same shape"); |
| |
| final int size = a.getNumElements(); |
| |
| for (int i = 0; i < size; i++) { |
| if (a.get(i) < floor) |
| b.set(i, floor); |
| else |
| b.set(i, a.get(i)); |
| } |
| } |
| |
| /** Convert an array of doubles to a matrix. A new matrix is created. */ |
| public static D1Matrix64F doubleArrayToMatrix(double[] data) { |
| |
| DenseMatrix64F tmp = new DenseMatrix64F(data.length, 1); |
| for (int i = 0; i < data.length; i++) { |
| tmp.set(i, data[i]); |
| } |
| return tmp; |
| } |
| |
| /** Convert an array of doubles to a matrix passed as a parameter. */ |
| public static D1Matrix64F doubleArrayToMatrix(double[] data, D1Matrix64F mat) { |
| |
| for (int i = 0; i < data.length; i++) { |
| mat.set(i, data[i]); |
| } |
| return mat; |
| } |
| |
| /** Convert an array of floats to a matrix. A new matrix is created. */ |
| public static D1Matrix64F floatArrayToMatrix(float[] data) { |
| |
| DenseMatrix64F tmp = new DenseMatrix64F(data.length, 1); |
| for (int i = 0; i < data.length; i++) { |
| tmp.set(i, data[i]); |
| } |
| return tmp; |
| } |
| |
| /** Convert an array of doubles to a matrix passed as a parameter. */ |
| public static D1Matrix64F floatArrayToMatrix(float[] data, D1Matrix64F mat) { |
| |
| for (int i = 0; i < data.length; i++) { |
| mat.set(i, data[i]); |
| } |
| return mat; |
| } |
| |
| /** |
| * Create a random vector using the mean and variance of a Gaussian |
| * distribution. |
| */ |
| public static D1Matrix64F createRandom(long seed, D1Matrix64F mean, D1Matrix64F variance) { |
| if (mean.numRows != variance.numRows || mean.numCols != variance.numCols) |
| throw new IllegalArgumentException( |
| "Matrices must have the same shape"); |
| |
| final int size = mean.getNumElements(); |
| DenseMatrix64F mat = new DenseMatrix64F(size, 1); |
| Random random = new Random(seed); |
| |
| for (int i = 0; i < size; i++) { |
| mat.set(i, mean.get(i) + random.nextGaussian() * Math.sqrt(variance.get(i))); |
| } |
| |
| return mat; |
| } |
| } |