Package edu.ucla.sspace.matrix.factorization

Source Code of edu.ucla.sspace.matrix.factorization.SingularValueDecompositionMatlab

/*
* Copyright (c) 2011, Lawrence Livermore National Security, LLC. Produced at
* the Lawrence Livermore National Laboratory. Written by Keith Stevens,
* kstevens@cs.ucla.edu OCEC-10-073 All rights reserved.
*
* This file is part of the S-Space package and is covered under the terms and
* conditions therein.
*
* The S-Space package is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation and distributed hereunder to you.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND NO REPRESENTATIONS OR WARRANTIES,
* EXPRESS OR IMPLIED ARE MADE.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, WE MAKE
* NO REPRESENTATIONS OR WARRANTIES OF MERCHANT- ABILITY OR FITNESS FOR ANY
* PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE OR DOCUMENTATION
* WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER
* RIGHTS.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package edu.ucla.sspace.matrix.factorization;

import edu.ucla.sspace.matrix.Matrix;
import edu.ucla.sspace.matrix.Matrix.Type;
import edu.ucla.sspace.matrix.MatrixBuilder;
import edu.ucla.sspace.matrix.MatrixFile;
import edu.ucla.sspace.matrix.MatrixIO;
import edu.ucla.sspace.matrix.MatrixIO.Format;
import edu.ucla.sspace.matrix.SparseMatrix;
import edu.ucla.sspace.matrix.MatlabSparseMatrixBuilder;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.IOError;
import java.io.IOException;
import java.io.PrintWriter;

import java.util.logging.Logger;
import java.util.logging.Level;


/**
* A wrapper around the Matlab implementation of the SVD.
*
* @author Keith Stevens
*/
public class SingularValueDecompositionMatlab extends AbstractSvd
        implements SingularValueDecomposition, java.io.Serializable {

    private static final long serialVersionUID = 1L;

    private static final Logger LOG =
        Logger.getLogger(SingularValueDecompositionMatlab.class.getName());

    public void factorize(SparseMatrix matrix, int dimensions) {
        try {
            File mFile = File.createTempFile("matlab-input", ".dat");
            MatrixIO.writeMatrix(matrix, mFile, Format.MATLAB_SPARSE);
            factorize(new MatrixFile(mFile, Format.MATLAB_SPARSE), dimensions);
        } catch (IOException ioe) {
            LOG.log(Level.SEVERE, "Converting to matlab file", ioe);
        }
    }

    public void factorize(MatrixFile mfile, int dimensions) {
        File matrix;

        try {
            if (mfile.getFormat() == Format.MATLAB_SPARSE)
                matrix = mfile.getFile();
            else
                matrix = MatrixIO.convertFormat(mfile.getFile(),
                                                mfile.getFormat(),
                                                Format.MATLAB_SPARSE);

            // create the matlab file for executing
            File uOutput = File.createTempFile("matlab-svds-U",".dat");
            File sOutput = File.createTempFile("matlab-svds-S",".dat");
            File vOutput = File.createTempFile("matlab-svds-V",".dat");
            LOG.fine("writing Matlab output to files:\n" +
                     "  " + uOutput + "\n" +
                     "  " + sOutput + "\n" +
                     "  " + vOutput + "\n");

            uOutput.deleteOnExit();
            sOutput.deleteOnExit();
            vOutput.deleteOnExit();

            String commandLine = "matlab -nodisplay -nosplash -nojvm";
            LOG.fine(commandLine);
            Process matlab = Runtime.getRuntime().exec(commandLine);
           
            // capture the input so we know then Matlab is finished
            BufferedReader br = new BufferedReader(
                new InputStreamReader(matlab.getInputStream()));

            // pipe Matlab the program to execute
            PrintWriter pw = new PrintWriter(matlab.getOutputStream());
            pw.println(
                "Z = load('" + matrix.getAbsolutePath() + "','-ascii');\n" +
                "A = spconvert(Z);\n" +
                "% Remove the raw data file to save space\n" +
                "clear Z;\n" +
                "[U, S, V] = svds(A, " + dimensions + " );\n" +
                "save " + uOutput.getAbsolutePath() + " U -ASCII\n" +
                "save " + sOutput.getAbsolutePath() + " S -ASCII\n" +
                "save " + vOutput.getAbsolutePath() + " V -ASCII\n" +
                "fprintf('Matlab Finished\\n');");
            pw.close();

            // capture the output
            StringBuilder output = new StringBuilder("Matlab svds output:\n");
            for (String line = null; (line = br.readLine()) != null; ) {
                output.append(line).append("\n");
                if (line.equals("Matlab Finished")) {
                    matlab.destroy();
                }
            }
            LOG.fine(output.toString());
           
            int exitStatus = matlab.waitFor();
            LOG.fine("Matlab svds exit status: " + exitStatus);

            // If Matlab was successful in generating the files, return them.
            if (exitStatus == 0) {
                // load U in memory, since that is what most algorithms will be
                // using (i.e. it is the word space)
                U = MatrixIO.readMatrix(uOutput, Format.DENSE_TEXT,
                                                  Type.DENSE_IN_MEMORY);
                scaledDataClasses = false;

                // Sigma only has n values for an n^2 matrix, so make it sparse
                Matrix S = MatrixIO.readMatrix(sOutput, Format.DENSE_TEXT,
                                               Type.SPARSE_ON_DISK);
                singularValues = new double[dimensions];
                for (int s = 0; s < dimensions; ++s)
                    singularValues[s] = S.get(s, s);

                // Octave does not transpose V, so transpose it
                V = MatrixIO.readMatrix(vOutput, Format.DENSE_TEXT,
                                        Type.DENSE_ON_DISK, true);
                scaledDataClasses = false;
            }
        } catch (IOException ioe) {
            LOG.log(Level.SEVERE, "Matlab svds", ioe);
        } catch (InterruptedException ie) {
            LOG.log(Level.SEVERE, "Matlab svds", ie);
        }
    }

    /**
     * {@inheritDoc}
     */
    public MatrixBuilder getBuilder() {
        return new MatlabSparseMatrixBuilder();
    }
}
TOP

Related Classes of edu.ucla.sspace.matrix.factorization.SingularValueDecompositionMatlab

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.