/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.math.matrix;
import org.apache.commons.lang.NotImplementedException;
import org.apache.commons.lang.Validate;
import cern.colt.matrix.DoubleFactory1D;
import cern.colt.matrix.DoubleFactory2D;
import cern.colt.matrix.linalg.Algebra;
/**
* Provides matrix algebra by using the <a href = "http://acs.lbl.gov/software/colt/api/cern/colt/matrix/linalg/Algebra.html">Colt matrix algebra library</a>.
*/
public class ColtMatrixAlgebra extends MatrixAlgebra {
private static final Algebra ALGEBRA = new Algebra();
/**
* {@inheritDoc}
*/
@Override
public double getCondition(final Matrix<?> m) {
Validate.notNull(m, "m");
if (m instanceof DoubleMatrix2D) {
return ALGEBRA.cond(DoubleFactory2D.dense.make(((DoubleMatrix2D) m).getData()));
}
throw new IllegalArgumentException("Can only find condition of DoubleMatrix2D; have " + m.getClass());
}
/**
* {@inheritDoc}
*/
@Override
public double getDeterminant(final Matrix<?> m) {
Validate.notNull(m, "m");
if (m instanceof DoubleMatrix2D) {
return ALGEBRA.det(DoubleFactory2D.dense.make(((DoubleMatrix2D) m).getData()));
}
throw new IllegalArgumentException("Can only find determinant of DoubleMatrix2D; have " + m.getClass());
}
/**
* {@inheritDoc}
*/
@Override
public DoubleMatrix2D getInverse(final Matrix<?> m) {
Validate.notNull(m, "m");
if (m instanceof DoubleMatrix2D) {
return new DoubleMatrix2D(ALGEBRA.inverse(DoubleFactory2D.dense.make(((DoubleMatrix2D) m).getData())).toArray());
}
throw new IllegalArgumentException("Can only find inverse of DoubleMatrix2D; have " + m.getClass());
}
/**
* {@inheritDoc}
*/
@Override
public double getInnerProduct(final Matrix<?> m1, final Matrix<?> m2) {
Validate.notNull(m1, "m1");
Validate.notNull(m2, "m2");
if (m1 instanceof DoubleMatrix1D && m2 instanceof DoubleMatrix1D) {
return ALGEBRA.mult(DoubleFactory1D.dense.make(((DoubleMatrix1D) m1).getData()), DoubleFactory1D.dense.make(((DoubleMatrix1D) m2).getData()));
}
throw new IllegalArgumentException("Cannot find the inner product of a " + m1.getClass() + " and " + m2.getClass());
}
/**
* {@inheritDoc}
* The following combinations of input matrices m1 and m2 are allowed:
* <ul>
* <li> m1 = 2-D matrix, m2 = 2-D matrix, returns $\mathbf{C} = \mathbf{AB}$
* <li> m1 = 2-D matrix, m2 = 1-D matrix, returns $\mathbf{C} = \mathbf{A}b$
* </ul>
*/
@Override
public Matrix<?> multiply(final Matrix<?> m1, final Matrix<?> m2) {
Validate.notNull(m1, "m1");
Validate.notNull(m2, "m2");
if (m1 instanceof DoubleMatrix1D) {
return new OGMatrixAlgebra().multiply(m1, m2);
}
if (m1 instanceof DoubleMatrix2D) {
final DoubleMatrix2D x = (DoubleMatrix2D) m1;
if (m2 instanceof DoubleMatrix1D) {
return new DoubleMatrix1D(ALGEBRA.mult(DoubleFactory2D.dense.make(x.getData()), DoubleFactory1D.dense.make(((DoubleMatrix1D) m2).getData())).toArray());
} else if (m2 instanceof DoubleMatrix2D) {
return new DoubleMatrix2D(ALGEBRA.mult(DoubleFactory2D.dense.make(x.getData()), DoubleFactory2D.dense.make(((DoubleMatrix2D) m2).getData())).toArray());
}
throw new IllegalArgumentException("Can only have 1D or 2D matrix as second argument");
}
throw new IllegalArgumentException("Can only multiply 2D and 1D matrices");
}
/**
* {@inheritDoc}
*/
@Override
public DoubleMatrix2D getOuterProduct(final Matrix<?> m1, final Matrix<?> m2) {
Validate.notNull(m1, "m1");
Validate.notNull(m2, "m2");
if (m1 instanceof DoubleMatrix1D && m2 instanceof DoubleMatrix1D) {
final cern.colt.matrix.DoubleMatrix2D x = DoubleFactory2D.dense.make(m1.getNumberOfElements(), m2.getNumberOfElements());
ALGEBRA.multOuter(DoubleFactory1D.dense.make(((DoubleMatrix1D) m1).getData()), DoubleFactory1D.dense.make(((DoubleMatrix1D) m2).getData()), x);
return new DoubleMatrix2D(x.toArray());
}
throw new IllegalArgumentException("Cannot find the outer product of a " + m1.getClass() + " and " + m2.getClass());
}
/**
* {@inheritDoc}
*/
@Override
public double getNorm1(final Matrix<?> m) {
Validate.notNull(m, "m");
if (m instanceof DoubleMatrix1D) {
return ALGEBRA.norm1(DoubleFactory1D.dense.make(((DoubleMatrix1D) m).getData()));
} else if (m instanceof DoubleMatrix2D) {
return ALGEBRA.norm1(DoubleFactory2D.dense.make(((DoubleMatrix2D) m).getData()));
}
throw new IllegalArgumentException("Can only find norm1 of DoubleMatrix1D or DoubleMatrix2D; have " + m.getClass());
}
/**
* {@inheritDoc}
*/
@Override
public double getNorm2(final Matrix<?> m) {
Validate.notNull(m, "m");
if (m instanceof DoubleMatrix1D) {
return Math.sqrt(ALGEBRA.norm2(DoubleFactory1D.dense.make(((DoubleMatrix1D) m).getData())));
} else if (m instanceof DoubleMatrix2D) {
return ALGEBRA.norm2(DoubleFactory2D.dense.make(((DoubleMatrix2D) m).getData()));
}
throw new IllegalArgumentException("Can only find norm2 of DoubleMatrix1D or DoubleMatrix2D; have " + m.getClass());
}
/**
* {@inheritDoc}
*/
@Override
public double getNormInfinity(final Matrix<?> m) {
Validate.notNull(m, "m");
if (m instanceof DoubleMatrix1D) {
return ALGEBRA.normInfinity(DoubleFactory1D.dense.make(((DoubleMatrix1D) m).getData()));
} else if (m instanceof DoubleMatrix2D) {
return ALGEBRA.normInfinity(DoubleFactory2D.dense.make(((DoubleMatrix2D) m).getData()));
}
throw new IllegalArgumentException("Can only find normInfinity of DoubleMatrix1D or DoubleMatrix2D; have " + m.getClass());
}
/**
* {@inheritDoc}
*/
@Override
public DoubleMatrix2D getPower(final Matrix<?> m, final int p) {
Validate.notNull(m, "m");
if (m instanceof DoubleMatrix2D) {
return new DoubleMatrix2D(ALGEBRA.pow(DoubleFactory2D.dense.make(((DoubleMatrix2D) m).getData()), p).toArray());
}
throw new IllegalArgumentException("Can only find transpose of DoubleMatrix2D; have " + m.getClass());
}
/**
* {@inheritDoc}
* @throws NotImplementedException
*/
@Override
public DoubleMatrix2D getPower(final Matrix<?> m, final double p) {
throw new NotImplementedException();
}
/**
* {@inheritDoc}
*/
@Override
public double getTrace(final Matrix<?> m) {
Validate.notNull(m, "m");
if (m instanceof DoubleMatrix2D) {
return ALGEBRA.trace(DoubleFactory2D.dense.make(((DoubleMatrix2D) m).getData()));
}
throw new IllegalArgumentException("Can only find trace of DoubleMatrix2D; have " + m.getClass());
}
/**
* {@inheritDoc}
*/
@Override
public DoubleMatrix2D getTranspose(final Matrix<?> m) {
Validate.notNull(m, "m");
if (m instanceof DoubleMatrix2D) {
return new DoubleMatrix2D(ALGEBRA.transpose(DoubleFactory2D.dense.make(((DoubleMatrix2D) m).getData())).toArray());
}
throw new IllegalArgumentException("Can only find transpose of DoubleMatrix2D; have " + m.getClass());
}
}