/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.math.linearalgebra;
import org.apache.commons.lang.Validate;
import cern.colt.matrix.linalg.SingularValueDecomposition;
import com.opengamma.analytics.math.matrix.DoubleMatrix1D;
import com.opengamma.analytics.math.matrix.DoubleMatrix2D;
import com.opengamma.analytics.math.matrix.DoubleMatrixUtils;
import com.opengamma.analytics.math.util.wrapper.ColtMathWrapper;
/**
* Wrapper for results of the Colt implementation of singular value decomposition {@link SVDecompositionColt}).
*/
public class SVDecompositionColtResult implements SVDecompositionResult {
private final double _condition;
private final double _norm;
private final int _rank;
private final DoubleMatrix2D _s;
private final double[] _singularValues;
private final DoubleMatrix2D _u;
private final DoubleMatrix2D _v;
private final DoubleMatrix2D _uTranspose;
private final DoubleMatrix2D _vTranspose;
/**
* @param svd The result of the SV decomposition, not null
*/
public SVDecompositionColtResult(final SingularValueDecomposition svd) {
Validate.notNull(svd);
_condition = svd.cond();
_norm = svd.norm2();
_rank = svd.rank();
_s = ColtMathWrapper.wrap(svd.getS());
_u = ColtMathWrapper.wrap(svd.getU());
_uTranspose = DoubleMatrixUtils.getTranspose(_u);
_v = ColtMathWrapper.wrap(svd.getV());
_vTranspose = DoubleMatrixUtils.getTranspose(_v);
_singularValues = svd.getSingularValues();
}
/**
* {@inheritDoc}
*/
@Override
public double getConditionNumber() {
return _condition;
}
/**
* {@inheritDoc}
*/
@Override
public double getNorm() {
return _norm;
}
/**
* {@inheritDoc}
*/
@Override
public int getRank() {
return _rank;
}
/**
* {@inheritDoc}
*/
@Override
public DoubleMatrix2D getS() {
return _s;
}
/**
* {@inheritDoc}
*/
@Override
public double[] getSingularValues() {
return _singularValues;
}
/**
* {@inheritDoc}
*/
@Override
public DoubleMatrix2D getU() {
return _u;
}
/**
* {@inheritDoc}
*/
@Override
public DoubleMatrix2D getUT() {
return _uTranspose;
}
/**
* {@inheritDoc}
*/
@Override
public DoubleMatrix2D getV() {
return _v;
}
/**
* {@inheritDoc}
*/
@Override
public DoubleMatrix2D getVT() {
return _vTranspose;
}
/**
* {@inheritDoc}
*/
@Override
public DoubleMatrix1D solve(final DoubleMatrix1D b) {
Validate.notNull(b);
return new DoubleMatrix1D(solve(b.getData()));
}
/**
* {@inheritDoc}
*/
@Override
public double[] solve(final double[] b) {
Validate.notNull(b);
final double[][] u = _u.getData();
final double[][] v = _v.getData();
final double[] w = _singularValues;
final int m = u.length;
final int n = u[0].length;
int i, j;
final double[] temp = new double[n];
double sum;
for (j = 0; j < n; j++) {
sum = 0.0;
// TODO change this to some threshold
if (w[j] > 0.0) {
for (i = 0; i < m; i++) {
sum += u[i][j] * b[i];
}
sum /= w[j];
}
temp[j] = sum;
}
final double[] res = new double[n];
for (i = 0; i < n; i++) {
sum = 0.0;
for (j = 0; j < n; j++) {
sum += v[i][j] * temp[j];
}
res[i] = sum;
}
return res;
}
/**
* {@inheritDoc}
*/
@Override
public DoubleMatrix2D solve(final com.opengamma.analytics.math.matrix.DoubleMatrix2D b) {
Validate.notNull(b);
final DoubleMatrix2D bt = DoubleMatrixUtils.getTranspose(b);
final double[][] data = bt.getData();
final int n = data.length;
final double[][] res = new double[n][];
for (int i = 0; i < n; i++) {
res[i] = solve(data[i]);
}
final DoubleMatrix2D xTranspose = new DoubleMatrix2D(res);
return DoubleMatrixUtils.getTranspose(xTranspose);
}
}