MatAPI.H

Go to the documentation of this file.
00001 /*!
00002    @file Matlab/MatAPI.H 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.H $
00037 // $Id: MatAPI.H 10794 2009-02-08 06:21:09Z itti $
00038 //
00039 
00040 #ifndef MATLAB_MATAPI_H_DEFINED
00041 #define MATLAB_MATAPI_H_DEFINED
00042 
00043 //------------------------------ HEADERS --------------------------------
00044 
00045 // INVT headers
00046 #include "Image/Image.H"
00047 
00048 // Matlab headers
00049 #ifdef MATLAB_LIBS_AVAILABLE // should be made available by configure system
00050 
00051 #include <engine.h>
00052 #include <mat.h>
00053 
00054 #else // use dummies to NOP out Matlab types and functions
00055 
00056 // Use dummies for various Matlab types and functions. Otherwise, builds
00057 // will break!
00058 //
00059 // DEVNOTE: Although this module and others dependent on it will build
00060 // okay with these dummies, runtime errors will prevent any dependent
00061 // programs from executing smoothly. thus, it may be a good idea to check
00062 // the MATLAB_LIBS_AVAILABLE preprocessor symbol in those modules as well
00063 // and do something appropriate in case the Matlab headers and libraries
00064 // are not available (e.g., have main() print a message stating that it
00065 // needs this API rather than allow it to blithely proceed and then
00066 // crash shortly thereafter with some inscrutable complaint about null
00067 // pointers or some such thing).
00068 #define mxREAL 0
00069 
00070 typedef double mxArray ;
00071 typedef double Engine ;
00072 typedef double MATFile ;
00073 
00074 inline mxArray* mxCreateDoubleMatrix(int, int, int) {return 0 ;}
00075 inline void     mxDestroyArray(mxArray*) {}
00076 inline double*  mxGetPr(mxArray*) {return 0;}
00077 inline unsigned mxGetM(mxArray*)  {return 0;}
00078 inline unsigned mxGetN(mxArray*)  {return 0;}
00079 
00080 inline Engine*  engOpen(const char*) {return 0 ;}
00081 inline mxArray* engGetVariable(Engine*, const char*) {return 0 ;}
00082 inline int  engPutVariable(Engine*, const char*, const mxArray*) {return 1 ;}
00083 inline int  engEvalString(Engine*, const char*) {return 1 ;}
00084 inline void engClose(Engine*) {}
00085 
00086 inline MATFile* matOpen(const char*, const char*) {return 0 ;}
00087 inline mxArray* matGetVariable(MATFile*, const char*) {return 0 ;}
00088 inline void matPutVariable(MATFile*, const char*, const mxArray*) {}
00089 inline void matClose(MATFile*) {}
00090 
00091 #endif // MATLAB_LIBS_AVAILABLE
00092 
00093 // Standard C++ headers
00094 #include <stdexcept>
00095 #include <vector>
00096 #include <iterator>
00097 #include <utility>
00098 
00099 //----------------------- NAMESPACE DEFINITION --------------------------
00100 
00101 // Encapsulate this API within its own namespace
00102 namespace Matlab {
00103 
00104 //--------------------------- MATLAB ARRAYS -----------------------------
00105 
00106 // Quick helper to encapsulate the necessary portions of the Matlab
00107 // mxArray API.
00108 //
00109 // DEVNOTE: REFERENCE COUNTING HACK
00110 //
00111 // This class implements a VERY BAD reference counting mechanism. It is
00112 // only meant to be used for taking care of copying of temporaries, e.g.,
00113 // when passing parameters to functions or getting back return values.
00114 // Taking advantage of this mechanism for anything more sophisticated can
00115 // only lead to trouble... To help prevent some of the pathologies
00116 // associated with this hacked up ref-counting, assignment and creation
00117 // of MatArrays on the heap are disabled.
00118 //
00119 // We could (and probably should) have used nub::ref_counted over here.
00120 // But it seemed a bit heavy-duty. But more importantly, the author was
00121 // unable to quickly locate documentation with a tutorial nature that
00122 // could have helped figure out how to use it in less than ten minutes.
00123 // Thus this monstrosity. When time permits, this class should be
00124 // revamped and made more generally useful (to ease interfacing with
00125 // Matlab from inside of C++).
00126 class Matrix {
00127    unsigned int num_rows, num_cols ;
00128    mxArray* mat_array;
00129    unsigned int current_row ;
00130    int ref_count ; // WARNING: MAJOR HACK! SEE COMMENT ABOVE.
00131 
00132    // Disable assignment and creation on the heap as they can be
00133    // hazardous to the hackish reference counting mechanism implemented
00134    // herein.
00135    Matrix& operator=(const Matrix&) ;
00136    void* operator new(size_t) ;
00137 
00138    // Quick-and-dirty output iterator for accessing mxArray in
00139    // column-major order (that's how Matlab arrays are stored).
00140    class mx_data_ptr {
00141       mutable double* p ; // current element being pointed to
00142       int n ; // increment value for p (equals num_rows in matrix)
00143    public :
00144       mx_data_ptr(const Matrix&) ;
00145       mx_data_ptr& operator++() throw() {
00146          p += n ; return *this ;
00147       }
00148       const mx_data_ptr& operator++() const throw() {
00149          p += n ; return *this ;
00150       }
00151       mx_data_ptr operator++(int) throw() { // post-increment
00152          mx_data_ptr prev(*this) ; ++*this ; return prev ;
00153       }
00154       const mx_data_ptr operator++(int) const throw() {
00155          mx_data_ptr prev(*this) ; ++*this ; return prev ;
00156       }
00157       double& operator*() throw() {return *p ;}
00158       const double& operator*() const throw() {return *p ;}
00159 
00160       // Need to define these types for STL compatibility
00161       typedef std::output_iterator_tag iterator_category ;
00162       typedef double value_type ;
00163       typedef int difference_type ;
00164       typedef double* pointer ;
00165       typedef double& reference ;
00166    } ; // end of inner class mx_data_ptr
00167 
00168 public :
00169    Matrix(int m, int n) ;
00170    Matrix(mxArray* M) ;
00171    template<typename T> Matrix(const Image<T>&) ;
00172    Matrix(const Matrix& M) ; // copy okay, but see ref counting notes above
00173    ~Matrix() ;
00174 
00175    void push_back(const std::vector<double>& row) ;
00176 
00177    operator const mxArray*() const {return mat_array ;} // conversion operator
00178    template<typename T> Image<T> to_image() const ; // explicit "conv.op"
00179 } ;
00180 
00181 // Initialize an mxArray using an Image<T>
00182 template<typename T>
00183 Matrix::Matrix(const Image<T>& I)
00184    : num_rows(I.getHeight()), num_cols(I.getWidth()),
00185      mat_array(mxCreateDoubleMatrix(num_rows, num_cols, mxREAL)),
00186      current_row(num_rows), // cannot modify this particular matrix!
00187      ref_count(1)
00188 {
00189    if (! mat_array)
00190       throw std::runtime_error("unable to create matrix") ;
00191 
00192    double* p = mxGetPr(mat_array) ;
00193    for (uint x = 0; x < num_cols; ++x)
00194       for (uint y = 0; y < num_rows; ++y, ++p)
00195          *p = I.getVal(x, y) ; // column major order
00196 }
00197 
00198 // Convert an mxArray to an Image<T>
00199 template<typename T>
00200 Image<T> Matrix::to_image() const
00201 {
00202    Image<T> I(num_cols, num_rows, NO_INIT) ;
00203 
00204    const double* p = mxGetPr(mat_array) ;
00205    for (uint x = 0; x < num_cols; ++x)
00206       for (uint y = 0; y < num_rows; ++y, ++p)
00207           I.setVal(x, y, static_cast<T>(*p)) ; // column major order
00208 
00209    return I ;
00210 }
00211 
00212 //--------------------------- MATLAB ENGINE -----------------------------
00213 
00214 // Renninger-Malik used the Netlab toolbox's K-means implementation to
00215 // compute the universal textons of the training set. We do the same
00216 // thing. But rather than fire up Matlab separately and hand it the
00217 // training textons via a .mat file, we simply start the Matlab engine
00218 // from inside of C++ and pass it the training textons matrix directly.
00219 // Once the K-means is done, we obtain the universal textons matrix from
00220 // the engine before shutting it down.
00221 //
00222 // The following class provides a quick wrapper around the Matlab engine
00223 // API.
00224 typedef Engine MatEngine ;
00225 class Engine {
00226    MatEngine* mat_engine ;
00227 public :
00228    Engine(const std::string& netlab_path) ;
00229    Matrix get(const std::string& variable_name) ;
00230    void put(const std::string& variable_name, const Matrix&) ;
00231    void exec(const std::string& command) ;
00232    ~Engine() ;
00233 } ;
00234 
00235 //---------------------------- MATLAB FILE ------------------------------
00236 
00237 // The following class encapsulates a small portion of the Matlab file
00238 // API to help with the task of writing the training set's universal
00239 // textons to a .mat file.
00240 class File {
00241    MATFile* mat_file ;
00242 public :
00243    File(const std::string& file_name, const std::string& open_mode) ;
00244    Matrix get(const std::string& variable_name) ;
00245    void put(const std::string& variable_name, const Matrix& matrix) ;
00246    ~File() ;
00247 } ;
00248 
00249 // To put some data into a Matlab file, we need a variable name and an
00250 // mxArray containing the data.
00251 typedef std::pair<std::string, Matrix> FileData ;
00252 
00253 // Output operator for writing matrices to a Matlab file
00254 File& operator<<(File& f, const FileData& d) ;
00255 
00256 //-----------------------------------------------------------------------
00257 
00258 } // end of namespace encapsulating this file
00259 
00260 /* So things look consistent in everyone's emacs... */
00261 /* Local Variables: */
00262 /* indent-tabs-mode: nil */
00263 /* End: */
00264 
00265 #endif
Generated on Sun May 8 08:40:59 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3