Package edu.ucla.sspace.matrix.factorization

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

/*
* 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 Octave implementation of the SVD.
*
* @author Keith Stevens
*/
public class SingularValueDecompositionOctave extends AbstractSvd
        implements SingularValueDecomposition, java.io.Serializable {

    private static final long serialVersionUID = 1L;


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

    public void factorize(SparseMatrix matrix, int dimensions) {
        try {
            File mFile = File.createTempFile("octave-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 octave file for executing
            File octaveFile = File.createTempFile("octave-svds",".m");
            File uOutput = File.createTempFile("octave-svds-U",".dat");
            File sOutput = File.createTempFile("octave-svds-S",".dat");
            File vOutput = File.createTempFile("octave-svds-V",".dat");
            octaveFile.deleteOnExit();
            uOutput.deleteOnExit();
            sOutput.deleteOnExit();
            vOutput.deleteOnExit();

            // Print the customized Octave program to a file.
            PrintWriter pw = new PrintWriter(octaveFile);
            pw.printf(
                "Z = load('%s','-ascii');\n" +
                "A = spconvert(Z);\n" +
                "clear Z;\n" +
                "[U, S, V] = svds(A, %d);\n" +
                "save(\"-ascii\", \"%s\", \"U\");\n" +
                "save(\"-ascii\", \"%s\", \"S\");\n" +
                "save(\"-ascii\", \"%s\", \"V\");\n" +
                "fprintf('Octave Finished\\n');\n",
                matrix.getAbsolutePath(), dimensions, uOutput.getAbsolutePath(),
                sOutput.getAbsolutePath(), vOutput.getAbsolutePath());
            pw.close();
           
            // build a command line where octave executes the previously
            // constructed file
            String commandLine = "octave " + octaveFile.getAbsolutePath();
            LOG.fine(commandLine);
            Process octave = Runtime.getRuntime().exec(commandLine);

            BufferedReader br = new BufferedReader(
                new InputStreamReader(octave.getInputStream()));
            BufferedReader stderr = new BufferedReader(
                new InputStreamReader(octave.getErrorStream()));

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

            // If Octave 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);
                scaledClassFeatures = 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;
            }
            else {
                StringBuilder sb = new StringBuilder();
                for (String line = null; (line = stderr.readLine()) != null; ) {
                    sb.append(line).append("\n");
                }
                // warning or error?
                LOG.warning("Octave exited with error status.  " +
                                   "stderr:\n" + sb.toString());
            }
        } catch (IOException ioe) {
            LOG.log(Level.SEVERE, "Octave svds", ioe);
        } catch (InterruptedException ie) {
            LOG.log(Level.SEVERE, "Octave svds", ie);
        }
    }

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

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

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.