MatAPI.C

Go to the documentation of this file.
00001 /*!
00002    @file Matlab/MatAPI.C some basic wrappers for the Matlab API
00003 */
00004 
00005 // //////////////////////////////////////////////////////////////////// //
00006 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00007 // University of Southern California (USC) and the iLab at USC.         //
00008 // See http://iLab.usc.edu for information about this project.          //
00009 // //////////////////////////////////////////////////////////////////// //
00010 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00011 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00012 // in Visual Environments, and Applications'' by Christof Koch and      //
00013 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00014 // pending; application number 09/912,225 filed July 23, 2001; see      //
00015 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00016 // //////////////////////////////////////////////////////////////////// //
00017 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00018 //                                                                      //
00019 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00020 // redistribute it and/or modify it under the terms of the GNU General  //
00021 // Public License as published by the Free Software Foundation; either  //
00022 // version 2 of the License, or (at your option) any later version.     //
00023 //                                                                      //
00024 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00025 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00026 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00027 // PURPOSE.  See the GNU General Public License for more details.       //
00028 //                                                                      //
00029 // You should have received a copy of the GNU General Public License    //
00030 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00031 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00032 // Boston, MA 02111-1307 USA.                                           //
00033 // //////////////////////////////////////////////////////////////////// //
00034 //
00035 // Primary maintainer for this file: Manu Viswanathan <mviswana at usc dot edu>
00036 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Matlab/MatAPI.C $
00037 // $Id: MatAPI.C 10794 2009-02-08 06:21:09Z itti $
00038 //
00039 
00040 //------------------------------ HEADERS --------------------------------
00041 
00042 // Matlab API header
00043 #include "Matlab/MatAPI.H"
00044 
00045 // INVT headers
00046 
00047 // Standard C++ headers
00048 #include <sstream>
00049 #include <algorithm>
00050 #include <iterator>
00051 
00052 //----------------------- NAMESPACE DEFINITION --------------------------
00053 
00054 // Encapsulate this API within its own namespace
00055 namespace Matlab {
00056 
00057 //--------------------------- MATLAB ARRAYS -----------------------------
00058 
00059 // Matlab stores matrices internally in flat 1-dimensional arrays using
00060 // column major ordering. Thus, to copy an entire row into an mxArray, we
00061 // start off at the appropriate offset from the start of the internal
00062 // data array and increment by the number of rows.
00063 //
00064 // Here is an illustrative example: let us say we want to append rows to
00065 // a 4x3 matrix. The first row will be in array indices 0, 4, 8; the
00066 // next row will occupy indices 1, 5, 9; and so on.
00067 //
00068 // The Matrix::mx_data_ptr inner class implements an iterator (for use
00069 // with STL algorithms) that starts off pointing at the first array
00070 // element of the "current" row in the mxArray, i.e., the row number the
00071 // push_back() function will fill, and then increments this pointer by
00072 // the number of rows in the matrix to get at the array element that will
00073 // store the next value of the matrix's row.
00074 Matrix::mx_data_ptr::mx_data_ptr(const Matrix& M)
00075    : p(mxGetPr(M.mat_array) + M.current_row), n(M.num_rows)
00076 {}
00077 
00078 // Create an mxn matrix of real numbers with all elements initialized to
00079 // zero.
00080 Matrix::Matrix(int m, int n)
00081    : num_rows(m), num_cols(n),
00082      mat_array(mxCreateDoubleMatrix(m, n, mxREAL)),
00083      current_row(0),
00084      ref_count(1)
00085 {
00086    if (! mat_array)
00087       throw std::runtime_error("unable to create matrix") ;
00088 }
00089 
00090 // Wrap a preexisting mxArray pointer into a Matrix object. This
00091 // pointer must actually reference an already initialized mxArray (i.e.,
00092 // not an empty matrix).
00093 //
00094 // WARNING: Once the pointer is handed over to an instance of this class,
00095 // it should not be used directly thereafter (and especially not deleted
00096 // or destroyed with the mxDestroyArray() function).
00097 Matrix::Matrix(mxArray* A)
00098    : num_rows(mxGetM(A)), num_cols(mxGetN(A)),
00099      mat_array(A),
00100      current_row(num_rows), // cannot modify matrix!
00101      ref_count(1)
00102 {}
00103 
00104 // Object copy
00105 //
00106 // WARNING: Only meant for use with temporaries (i.e., function
00107 // parameters and return values). Any use more sophisticated than this
00108 // will mess up the ref-counting. See ref-counting notes in comment
00109 // preceding class definition.
00110 Matrix::Matrix(const Matrix& M)
00111    : num_rows(M.num_rows), num_cols(M.num_cols),
00112      mat_array(M.mat_array),
00113      current_row(M.current_row),
00114      ref_count(M.ref_count + 1)
00115 {}
00116 
00117 // Clean-up
00118 Matrix::~Matrix()
00119 {
00120    if (--ref_count == 0)
00121       mxDestroyArray(mat_array) ;
00122 }
00123 
00124 // Append a given row of numbers to the matrix
00125 void Matrix::push_back(const std::vector<double>& row)
00126 {
00127    if (row.size() != num_cols)
00128       throw std::runtime_error("cannot append row of different size") ;
00129    if (current_row >= num_rows)
00130       throw std::runtime_error("cannot append any more rows") ;
00131 
00132    std::copy(row.begin(), row.end(), mx_data_ptr(*this)) ;
00133    ++current_row ;
00134 }
00135 
00136 //--------------------------- MATLAB ENGINE -----------------------------
00137 
00138 // Matlab engine initialization and setup for Netlab toolbox
00139 Engine::Engine(const std::string& netlab_path)
00140    : mat_engine(engOpen("matlab -nosplash -nojvm"))
00141 {
00142    if (! mat_engine)
00143       throw std::runtime_error("unable to start Matlab engine") ;
00144 
00145    exec("addpath '" + netlab_path + "'") ;
00146 }
00147 
00148 // Getting and sending matrices from/to Matlab engine
00149 Matrix Engine::get(const std::string& var_name)
00150 {
00151    mxArray* M = engGetVariable(mat_engine, var_name.c_str()) ;
00152    if (! M)
00153       throw std::runtime_error("unable to retrieve variable "
00154                                + var_name + " from Matlab engine") ;
00155    return M ;
00156 }
00157 
00158 void Engine::put(const std::string& var_name, const Matrix& M)
00159 {
00160    if (engPutVariable(mat_engine, var_name.c_str(), M))
00161       throw std::runtime_error("unable to send variable " + var_name +
00162                                " to Matlab engine") ;
00163 }
00164 
00165 // Getting the Matlab engine to do our bidding
00166 void Engine::exec(const std::string& cmd)
00167 {
00168    if (engEvalString(mat_engine, cmd.c_str()))
00169       throw std::runtime_error("Matlab engine could not eval: " + cmd) ;
00170 }
00171 
00172 // Shutting down the Matlab engine
00173 Engine::~Engine()
00174 {
00175    engClose(mat_engine) ;
00176 }
00177 
00178 //---------------------------- MATLAB FILE ------------------------------
00179 
00180 // Initialization
00181 File::File(const std::string& file_name, const std::string& mode)
00182    : mat_file(matOpen(file_name.c_str(), mode.c_str()))
00183 {
00184    if (! mat_file)
00185       throw std::runtime_error("unable to open " + file_name) ;
00186 }
00187 
00188 // Reading data from the .mat file
00189 Matrix File::get(const std::string& var_name)
00190 {
00191    mxArray* M = matGetVariable(mat_file, var_name.c_str()) ;
00192    if (! M)
00193       throw std::runtime_error("no variable named " + var_name) ;
00194    return M ;
00195 }
00196 
00197 // Writing data to the .mat file
00198 void File::put(const std::string& var_name, const Matrix& matrix)
00199 {
00200    matPutVariable(mat_file, var_name.c_str(), matrix) ;
00201 }
00202 
00203 // Clean-up
00204 File::~File()
00205 {
00206    matClose(mat_file) ;
00207 }
00208 
00209 // Output operator for writing textons to a File instance
00210 File& operator<<(File& f, const FileData& d)
00211 {
00212    f.put(d.first, d.second) ;
00213    return f ;
00214 }
00215 
00216 //-----------------------------------------------------------------------
00217 
00218 } // end of namespace encapsulating this file
00219 
00220 /* So things look consistent in everyone's emacs... */
00221 /* Local Variables: */
00222 /* indent-tabs-mode: nil */
00223 /* End: */
Generated on Sun May 8 08:40:59 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3