/*
* Copyright (C) 2008-2015 by Holger Arndt
*
* This file is part of the Universal Java Matrix Package (UJMP).
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership and licensing.
*
* UJMP is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* UJMP is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with UJMP; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
package org.ujmp.vecmath;
import javax.vecmath.GMatrix;
import javax.vecmath.GVector;
import org.ujmp.core.Matrix;
import org.ujmp.core.calculation.Calculation.Ret;
import org.ujmp.core.doublematrix.DenseDoubleMatrix2D;
import org.ujmp.core.doublematrix.stub.AbstractDenseDoubleMatrix2D;
import org.ujmp.core.interfaces.Wrapper;
import org.ujmp.core.mapmatrix.MapMatrix;
import org.ujmp.core.util.MathUtil;
public class VecMathDenseDoubleMatrix2D extends AbstractDenseDoubleMatrix2D implements Wrapper<GMatrix> {
private static final long serialVersionUID = 3792684800581150214L;
public static final VecMathDenseDoubleMatrix2DFactory Factory = new VecMathDenseDoubleMatrix2DFactory();
private final GMatrix matrix;
public VecMathDenseDoubleMatrix2D(GMatrix m) {
super(m.getNumRow(), m.getNumCol());
this.matrix = m;
}
public VecMathDenseDoubleMatrix2D(int rows, int columns) {
super(rows, columns);
this.matrix = new GMatrix(rows, columns);
// matrix is not empty by default!
for (int r = 0; r < rows; r++) {
for (int c = 0; c < columns; c++) {
setDouble(0.0, r, c);
}
}
}
public VecMathDenseDoubleMatrix2D(Matrix source) {
this(MathUtil.longToInt(source.getRowCount()), MathUtil.longToInt(source.getColumnCount()));
for (long[] c : source.availableCoordinates()) {
setAsDouble(source.getAsDouble(c), c);
}
if (source.getMetaData() != null) {
setMetaData(source.getMetaData().clone());
}
}
public double getDouble(long row, long column) {
return matrix.getElement((int) row, (int) column);
}
public double getDouble(int row, int column) {
return matrix.getElement(row, column);
}
public void setDouble(double value, long row, long column) {
matrix.setElement((int) row, (int) column, value);
}
public void setDouble(double value, int row, int column) {
matrix.setElement(row, column, value);
}
public GMatrix getWrappedObject() {
return matrix;
}
public VecMathDenseDoubleMatrix2D transpose() {
GMatrix m = (GMatrix) matrix.clone();
m.transpose();
return new VecMathDenseDoubleMatrix2D(m);
}
public Matrix plus(Matrix m) {
if (m instanceof VecMathDenseDoubleMatrix2D) {
GMatrix result = (GMatrix) matrix.clone();
result.add(((VecMathDenseDoubleMatrix2D) m).matrix);
Matrix ret = new VecMathDenseDoubleMatrix2D(result);
MapMatrix<String, Object> a = getMetaData();
if (a != null) {
ret.setMetaData(a.clone());
}
return ret;
} else {
return super.plus(m);
}
}
public Matrix minus(Matrix m) {
if (m instanceof VecMathDenseDoubleMatrix2D) {
GMatrix result = (GMatrix) matrix.clone();
result.sub(((VecMathDenseDoubleMatrix2D) m).matrix);
Matrix ret = new VecMathDenseDoubleMatrix2D(result);
MapMatrix<String, Object> a = getMetaData();
if (a != null) {
ret.setMetaData(a.clone());
}
return ret;
} else {
return super.minus(m);
}
}
public Matrix mtimes(Matrix m) {
if (m instanceof VecMathDenseDoubleMatrix2D) {
GMatrix result = new GMatrix(matrix.getNumRow(), (int) m.getColumnCount());
result.mul(matrix, ((VecMathDenseDoubleMatrix2D) m).matrix);
Matrix ret = new VecMathDenseDoubleMatrix2D(result);
MapMatrix<String, Object> a = getMetaData();
if (a != null) {
ret.setMetaData(a.clone());
}
return ret;
} else {
return super.mtimes(m);
}
}
public DenseDoubleMatrix2D inv() {
GMatrix m = (GMatrix) matrix.clone();
m.invert();
return new VecMathDenseDoubleMatrix2D(m);
}
// in S all entries on the diagonal are 1
public Matrix[] svd() {
GMatrix m = (GMatrix) matrix.clone();
int nrows = (int) getRowCount();
int ncols = (int) getColumnCount();
GMatrix u = new GMatrix(nrows, nrows);
GMatrix s = new GMatrix(nrows, ncols);
GMatrix v = new GMatrix(ncols, ncols);
m.SVD(u, s, v);
Matrix U = new VecMathDenseDoubleMatrix2D(u);
Matrix S = new VecMathDenseDoubleMatrix2D(s);
Matrix V = new VecMathDenseDoubleMatrix2D(v);
return new Matrix[] { U, S, V };
}
// non-singular matrices only
public Matrix[] lu() {
if (isSquare()) {
GMatrix m = (GMatrix) matrix.clone();
GMatrix lu = (GMatrix) matrix.clone();
GVector piv = new GVector(matrix.getNumCol());
m.LUD(lu, piv);
Matrix l = new VecMathDenseDoubleMatrix2D(lu).tril(Ret.NEW, 0);
for (int i = (int) l.getRowCount() - 1; i != -1; i--) {
l.setAsDouble(1, i, i);
}
Matrix u = new VecMathDenseDoubleMatrix2D(lu).triu(Ret.NEW, 0);
VecMathDenseDoubleMatrix2D p = new VecMathDenseDoubleMatrix2D(MathUtil.longToInt(getRowCount()),
MathUtil.longToInt(getColumnCount()));
for (int i = piv.getSize() - 1; i != -1; i--) {
p.setDouble(1, i, (int) piv.getElement(i));
}
return new Matrix[] { l, u, p };
} else {
throw new RuntimeException("only allowed for square matrices");
}
}
public VecMathDenseDoubleMatrix2DFactory getFactory() {
return Factory;
}
}