package svd;
import org.bridj.Pointer;
import cern.colt.matrix.tdouble.impl.SparseCCDoubleMatrix2D;
import cern.colt.matrix.tdouble.impl.SparseDoubleMatrix2D;
public class SVDWrapper {
public static SVDResults denseSVD(double[][] matrix, int dimensions)
{
Pointer<dmat> pDA = SvdLibrary.svdNewDMat(2,3);
dmat DA = pDA.get();
Pointer<Double>[] rows = DA.value().getPointersAtOffset(0, (int) DA.rows(), Double.class);
for(int i=0; i < matrix.length; i++)
rows[i].setDoubles(matrix[i]);
Pointer<smat> A = SvdLibrary.svdConvertDtoS(pDA);
SvdLibrary.svdFreeDMat(pDA);
Pointer<svdrec> pREC = SvdLibrary.svdLAS2A(A, dimensions);
SvdLibrary.svdFreeSMat(A);
SVDResults results = buildSVDResults(pREC);
SvdLibrary.svdFreeSVDRec(pREC);
return results;
}
private static SVDResults buildSVDResults(Pointer<svdrec> pREC) {
svdrec rec = pREC.get();
SVDResults results = new SVDResults();
results.Ut = convertMatrix(rec.Ut().get());
results.S = rec.S().getDoubles(rec.d());
results.Vt = convertMatrix(rec.Vt().get());
return results;
}
private static double[][] convertMatrix(dmat input) {
double[][] output = new double[(int) input.rows()][(int) input.cols()];
for(long i=0; i< input.rows(); i++)
{
Pointer<Double> row = input.value().getPointersAtOffset(0, (int) input.rows(), Double.class)[(int) i];
for(long j=0; j < input.cols(); j++)
output[(int) i][(int) j] = row.getDoubleAtIndex(j);
}
return output;
}
public static SVDResults sparseSVD(SparseDoubleMatrix2D matrix, int dimensions) {
Pointer<smat> pSA = buildSparseMatrix2(matrix);
Pointer<svdrec> pREC = SvdLibrary.svdLAS2A(pSA, dimensions);
SvdLibrary.svdFreeSMat(pSA);
SVDResults results = buildSVDResults(pREC);
SvdLibrary.svdFreeSVDRec(pREC);
return results;
}
public static Pointer<smat> buildSparseMatrix(SparseDoubleMatrix2D matrix) {
Pointer<smat> pSA = SvdLibrary.svdNewSMat(matrix.rows(), matrix.columns(), matrix.elements().size());
for(int j=0, n=0; j < matrix.columns(); j++){
pSA.get().pointr().setCLongAtIndex(j, n);
for(int i=0; i < matrix.rows(); i++) {
if(matrix.get(i, j) != 0) {
pSA.get().rowind().setCLongAtIndex(n, i);
pSA.get().value().setDoubleAtIndex(n, matrix.get(i,j));
n++;
}
}
}
pSA.get().pointr().setCLongAtIndex(pSA.get().cols(), pSA.get().vals());
return pSA;
}
public static Pointer<smat> buildSparseMatrix2(SparseDoubleMatrix2D matrix) {
Pointer<smat> pSA = SvdLibrary.svdNewSMat(matrix.rows(), matrix.columns(), matrix.elements().size());
SparseCCDoubleMatrix2D cc_matrix = matrix.getColumnCompressed(true);
pSA.get().pointr().setCLongs(cc_matrix.getColumnPointers());
pSA.get().rowind().setCLongs(cc_matrix.getRowIndexes());
pSA.get().value().setDoubles(cc_matrix.getValues());
return pSA;
}
}