PLearn 0.1
Public Member Functions | Static Public Member Functions | Public Attributes | Protected Attributes
PLearn::MatlabInterface Class Reference

#include <MatlabInterface.h>

Collaboration diagram for PLearn::MatlabInterface:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 MatlabInterface (string matlab_file_header, string matlab_file="", string id="", bool launch_in_background=false, bool erase_tmp_files=true)
 MatlabInterface (vector< string > matlab_file_header, string matlab_file="", string id="", bool launch_in_background=false, bool erase_tmp_files=true)
Popenlaunch ()
bool launchAndWaitFor (string matlab_end_answer)

Static Public Member Functions

static string path ()
 returns where to find appropriate .m files will be appended to the matlab path
static void eigs_r11 (RowMapSparseMatrix< real > &A, Mat &evectors, int d, string which_eigenvalues, bool erase_tmp_files=true)
static void eigs_r11 (RowMapSparseMatrix< real > &A, Vec &evalues, int d, string which_eigenvalues, bool erase_tmp_files=true)
static void eigs_r11 (RowMapSparseMatrix< real > &A, Mat &evectors, Vec &evalues, int d, string which_eigenvalues, bool erase_tmp_files=true)

Public Attributes

Popenmatlab
 The communication object that contains the Matlab command line.
string matlab_file
 The pre-defined M-file.
string matlab_file_header
 The user-supplied header, that will be concatenated to the top of the M-file.

Protected Attributes

string id
 This is a unique id for a particular Matlab execution (to avoid conflicts).
bool launch_in_background
 Some flags.
bool erase_tmp_files

Detailed Description

This class permits the execution of a Matlab sub-routine from within a PLearn program. The parametrization of the sub-routine (if required) is performed by the concatenation of a set of "lines" (a header), optionnally followed by an existing M-file (Matlab program file format). Here is an example that shows how it works :

Suppose you want to execute the following matlb lines:

load mymat -ascii; [U,S,V] = svd(mymat); save U.dat U -ascii; save S.dat S -ascii;

then you just do the following:

MatlabInterface matlab("load mymat -ascii; [U,S,V] = svd(mymat); save U.dat U -ascii; save S.dat S -ascii; fprintf(1,'done
');"); matlab.launchAndWaitFor("done");

Where you should note the fprintf of 'done' in the matlab instructions so as to be able to detect the end of the matlab execution.

Another way to use this class is to concatenate these explicitly given lines of code with an existing matlab file. Suppose you have defined the file foo.m :

file foo.m

a = 1; a = b + c;

%%%%%%%%%%%

This execution of this file, by itself, would generate an error from the Matlab interpreter, stating that the variable b is not defined. You can then declare a MatlabInterface instance, with the line "b = 2;" as the header, the program will acquire a correct meaning. The underlying M-file will then become (exactly) :

b = 2; file foo.m

a = 1; a = b + c;

%%%%%%%%%%%

Another usage that you may find interesting is passing a matrix from a PLearn program to a Matlab program. Suppose you have defined a RowMapSparseMatrix M in a PLearn class. You want to pass it to a Matlab program, let's say foo.m again. First you have to export M to a format that Matlab can read :

M.exportToMatlabReadableFormat("Mijv.dat");

You can then generate a header using a STL vector :

vector<string> header; header.push_back("load Mijv.dat;"); header.push_back("M = spconvert(Mijv);");

You can then use that header, along with a M-file that makes use of the sparse matrix M, to initialize a MatlabInterface.

NOTE : to avoid any process conflicts at run-time, the M-file being executed is not the one supplied, but a new one, that has a unique id. This is the case, even if you want to execute a M-file that requires no header.

An example of application of MatlabInterface is given after this class definition, for finding eigen-pairs of a symmetric matrix using the eigs() program of matlab r11 on a RowMapSarseMatrix.

Definition at line 136 of file MatlabInterface.h.


Constructor & Destructor Documentation

PLearn::MatlabInterface::MatlabInterface ( string  matlab_file_header,
string  matlab_file = "",
string  id = "",
bool  launch_in_background = false,
bool  erase_tmp_files = true 
)

These constructors have 3 fields in common :

id : if this is set to "", a unique id will be generated for this particular Matlab execution.

launch_in_background : set this flag to true if you want to run Matlab in background.

erase_tmp_files : set this flag to true if you don't want any residual files remaining after the execution. If there is any trouble with the Matlab execution, you can examine the M-file that is the result of the concatenation of the header and the pre-defined M-file by setting this flag to false.

Use this constructor if the Matlab program you want to run does not need any parametrization (the M-file will be executed as is the Matlab interpreter. No header is necessary.

DEPRECATED CONSTRUCTOR. MatlabInterface(string matlab_file, string id = "", bool launch_in_background = false, bool erase_tmp_files = true);

Use this constructor if your entire header is contained in a string. Be careful to delimitate the lines with '
'. If matlab_file=="" then no matlab_file is concatenated.

Definition at line 63 of file MatlabInterface.cc.

{
  matlab_file_header = the_matlab_file_header;
  matlab_file = the_matlab_file;
  id = the_id;
  launch_in_background = the_launch_in_background;
  erase_tmp_files = the_erase_tmp_files;
}
PLearn::MatlabInterface::MatlabInterface ( vector< string >  matlab_file_header,
string  matlab_file = "",
string  id = "",
bool  launch_in_background = false,
bool  erase_tmp_files = true 
)

Definition at line 73 of file MatlabInterface.cc.

References i.

{
  for (unsigned int i = 0; i < the_matlab_file_header.size(); i++)
    matlab_file_header += (the_matlab_file_header[i] + "\n");
  id = the_id;
  matlab_file = the_matlab_file;
  launch_in_background = the_launch_in_background;
  erase_tmp_files = the_erase_tmp_files;
}

Member Function Documentation

void PLearn::MatlabInterface::eigs_r11 ( RowMapSparseMatrix< real > &  A,
Mat evectors,
int  d,
string  which_eigenvalues,
bool  erase_tmp_files = true 
) [static]

Definition at line 279 of file MatlabInterface.cc.

References PLearn::RowMapSparseMatrix< T >::exportToMatlabReadableFormat(), PLearn::Popen::in, launchAndWaitFor(), PLearn::RowMapSparseMatrix< T >::length(), PLearn::loadAsciiWithoutSize(), PLearn::looksNumeric(), matlab, matlab_file_header, PLearn::newFilename(), path(), PLERROR, PLWARNING, PLearn::remove_extension(), PLearn::TMat< T >::resize(), PLearn::toint(), and PLearn::tostring().

{
  string id = newFilename("", "");
  unlink(id.c_str());
  string A_file = "A_" + id + ".ijv";
  A.exportToMatlabReadableFormat(A_file);
  string A_file_noext = remove_extension(A_file);
  string evec_file = A_file_noext + "_evec.dat";
  vector<string> header;
  // that's where we expect to find eigs_r11.m
  header.push_back("path(path, '"+MatlabInterface::path()+"')");
  header.push_back("load " + A_file + ";");
  // convert to matlab sparse format
  header.push_back("M = spconvert(" + A_file_noext + ");");
  header.push_back("options.disp = 0; options.isreal = 1; options.issym = 1;");
  header.push_back("d = " + tostring(d) + ";");
  if (!looksNumeric(which_eigenvalues.c_str()))
    which_eigenvalues = "'" + which_eigenvalues + "'";
  header.push_back("[Evec, Eval] = eigs_r11(M, d, "+which_eigenvalues+", options);");
  //header.push_back("Evec = Evec';");
  header.push_back("save " + evec_file + " Evec -ascii -double;");
  header.push_back("fprintf(1, 'done ');");
  header.push_back("fprintf(1, '%d ', size(Eval));");
  header.push_back("quit");
  
  MatlabInterface matlab(header, "", id, false, erase_tmp_files);
  bool successful = matlab.launchAndWaitFor("done");
  if (!successful)
    PLERROR("eigs_r11: call to matlab was not successful, executing: %s",
          matlab.matlab_file_header.c_str());
  // get actual number of e-values found
  int actual_n_eval;
  string answer;
  // matlab.matlab->in >> actual_n_eval;
  matlab.matlab->in >> answer;
  if (answer==">>")
    matlab.matlab->in >> answer;
  if (!looksNumeric(answer.c_str()))
    PLERROR("eigs_r11: expected nb of eigenvalues, got %s",answer.c_str());
  actual_n_eval=toint(answer);
  evectors.resize(A.length(), actual_n_eval);
  //evectors.resize(actual_n_eval, A.length());
  if (actual_n_eval < d)
    PLWARNING("matlabR11eigs: found %d e-values out of %d required",
            actual_n_eval, d);
  // get results
  loadAsciiWithoutSize(evec_file, evectors);
  if (erase_tmp_files)
  {
    unlink(A_file.c_str());
    unlink(evec_file.c_str());
  }
}

Here is the call graph for this function:

void PLearn::MatlabInterface::eigs_r11 ( RowMapSparseMatrix< real > &  A,
Vec evalues,
int  d,
string  which_eigenvalues,
bool  erase_tmp_files = true 
) [static]

Definition at line 334 of file MatlabInterface.cc.

References PLearn::RowMapSparseMatrix< T >::exportToMatlabReadableFormat(), PLearn::Popen::in, launchAndWaitFor(), PLearn::loadAsciiWithoutSize(), PLearn::looksNumeric(), matlab, matlab_file_header, PLearn::newFilename(), path(), PLERROR, PLWARNING, PLearn::remove_extension(), PLearn::TVec< T >::resize(), PLearn::toint(), and PLearn::tostring().

{
  string id = newFilename("", "");
  unlink(id.c_str());
  string A_file = "A_" + id + ".ijv";
  A.exportToMatlabReadableFormat(A_file);
  string A_file_noext = remove_extension(A_file);
  string eval_file = A_file_noext + "_eval.dat";
  vector<string> header;
  // that's where we expect to find eigs_r11.m
  header.push_back("path(path, '"+MatlabInterface::path()+"')");
  header.push_back("load " + A_file + ";");
  // convert to matlab sparse format
  header.push_back("M = spconvert(" + A_file_noext + ");");
  header.push_back("options.disp = 0; options.isreal = 1; options.issym = 1;");
  header.push_back("d = " + tostring(d) + ";");
  if (!looksNumeric(which_eigenvalues.c_str()))
    which_eigenvalues = "'" + which_eigenvalues + "'";
  header.push_back("Eval = eigs_r11(M, d, "+which_eigenvalues+", options);");
  header.push_back("Eval = diag(Eval);");
  header.push_back("save " + eval_file + " Eval -ascii -double;");
  header.push_back("fprintf(1, 'done ');");
  header.push_back("fprintf(1, '%d ', size(Eval));");
  header.push_back("quit");
  
  MatlabInterface matlab(header, "", id, false, erase_tmp_files);
  bool successful = matlab.launchAndWaitFor("done");
  if (!successful)
    PLERROR("eigs_r11: call to matlab was not successful, executing: %s",
          matlab.matlab_file_header.c_str());
  // get actual number of e-values found
  int actual_n_eval;
  string answer;
  // matlab.matlab->in >> actual_n_eval;
  matlab.matlab->in >> answer;
  if (answer==">>")
    matlab.matlab->in >> answer;
  if (!looksNumeric(answer.c_str()))
    PLERROR("eigs_r11: expected nb of eigenvalues, got %s",answer.c_str());
  actual_n_eval=toint(answer);
  evalues.resize(actual_n_eval);
  if (actual_n_eval < d)
    PLWARNING("matlabR11eigs: found %d e-values out of %d required",
            actual_n_eval, d);
  // get results
  loadAsciiWithoutSize(eval_file, evalues);
  if (erase_tmp_files)
  {
    unlink(A_file.c_str());
    unlink(eval_file.c_str());
  }
}

Here is the call graph for this function:

void PLearn::MatlabInterface::eigs_r11 ( RowMapSparseMatrix< real > &  A,
Mat evectors,
Vec evalues,
int  d,
string  which_eigenvalues,
bool  erase_tmp_files = true 
) [static]

Definition at line 218 of file MatlabInterface.cc.

References PLearn::RowMapSparseMatrix< T >::exportToMatlabReadableFormat(), PLearn::Popen::in, launchAndWaitFor(), PLearn::RowMapSparseMatrix< T >::length(), PLearn::loadAsciiWithoutSize(), PLearn::looksNumeric(), matlab, matlab_file_header, PLearn::newFilename(), path(), PLERROR, PLWARNING, PLearn::remove_extension(), PLearn::TMat< T >::resize(), PLearn::TVec< T >::resize(), PLearn::toint(), and PLearn::tostring().

{
  string id = newFilename("", "");
  unlink(id.c_str());
  string A_file = "A_" + id + ".ijv";
  A.exportToMatlabReadableFormat(A_file);
  string A_file_noext = remove_extension(A_file);
  string evec_file = A_file_noext + "_evec.dat";
  string eval_file = A_file_noext + "_eval.dat";
  vector<string> header;
  // that's where we expect to find eigs_r11.m
  header.push_back("path(path, '"+MatlabInterface::path()+"')");
  header.push_back("load " + A_file + ";");
  // convert to matlab sparse format
  header.push_back("M = spconvert(" + A_file_noext + ");");
  header.push_back("options.disp = 0; options.isreal = 1; options.issym = 1;");
  header.push_back("d = " + tostring(d) + ";");
  if (!looksNumeric(which_eigenvalues.c_str()))
    which_eigenvalues = "'" + which_eigenvalues + "'";
  header.push_back("[Evec, Eval] = eigs_r11(M, d, "+which_eigenvalues+", options);");
  header.push_back("Evec = Evec';");
  header.push_back("save " + evec_file + " Evec -ascii -double;");
  header.push_back("Eval = diag(Eval);");
  header.push_back("save " + eval_file + " Eval -ascii -double;");
  header.push_back("fprintf(1, 'done ');");
  header.push_back("fprintf(1, '%d ',size(Eval));");
  header.push_back("quit");
  
  MatlabInterface matlab(header, "", id, false, erase_tmp_files);
  bool successful = matlab.launchAndWaitFor("done");
  if (!successful)
    PLERROR("eigs_r11: call to matlab was not successful, executing: %s",
          matlab.matlab_file_header.c_str());
  // get actual number of e-values found
  int actual_n_eval;
  string answer;
  // matlab.matlab->in >> actual_n_eval;
  matlab.matlab->in >> answer;
  if (answer==">>")
    matlab.matlab->in >> answer;
  if (!looksNumeric(answer.c_str()))
    PLERROR("eigs_r11: expected nb of eigenvalues, got %s",answer.c_str());
  actual_n_eval=toint(answer);
  evalues.resize(actual_n_eval);
  evectors.resize(actual_n_eval, A.length());
  //evectors.resize(A.length(), actual_n_eval);
  if (actual_n_eval < d)
    PLWARNING("matlabR11eigs: found %d e-values out of %d required",
            actual_n_eval, d);
  // get results
  loadAsciiWithoutSize(eval_file, evalues);
  loadAsciiWithoutSize(evec_file, evectors);
  if (erase_tmp_files)
  {
    unlink(A_file.c_str());
    unlink(eval_file.c_str());
    unlink(evec_file.c_str());
  }
}

Here is the call graph for this function:

Popen * PLearn::MatlabInterface::launch ( )

This method will run the Matlab interpreter on the prepared M-file. A pointer to the Popen communication object is returned, for you to manage the termination of the program. One way to do that is to poll the "in" field of the Popen object, waiting for an answer from Matlab :

MatlabInterface matlab(...); Popen* p = matlab.launch(); string answer;

do { p->in >> answer; } while (answer != <desired answer>="">);

Definition at line 84 of file MatlabInterface.cc.

References PLearn::endl(), and PLearn::newFilename().

{
  if (id == "")
  {
    id = newFilename("", "");
    unlink(id.c_str());
  }
  string tmp_matlab_file = id + ".m";
  ofstream tmp_out(tmp_matlab_file.c_str());
  tmp_out << matlab_file_header << endl;
  if (matlab_file != "")
  {
    string cat_command = "cat " + matlab_file + " >> " + tmp_matlab_file;
    system(cat_command.c_str());
  }
  string matlab_command = "matlab -nodisplay -nojvm < " + tmp_matlab_file + "";
  if (launch_in_background)
    matlab_command += " &";
  // Launch Matlab
  matlab = new Popen(matlab_command);
  return matlab;  
}

Here is the call graph for this function:

bool PLearn::MatlabInterface::launchAndWaitFor ( string  matlab_end_answer)

The method of "waiting for Matlab" described above is encapsulated in this function, where all you have to supply is the Matlab answer stating that the program is done. This method will also stop in case of matlab PLERROR(detected with the string "???"), and will return false in that case (return true if everything works).

Definition at line 107 of file MatlabInterface.cc.

References PLearn::endl(), and PLearn::newFilename().

Referenced by eigs_r11(), and PLearn::matlabR11eigs().

{
  if (id == "")
  {
    id = newFilename("", "");
    unlink(id.c_str());
  }
  string tmp_matlab_file = id + ".m";
  ofstream tmp_out(tmp_matlab_file.c_str());
  tmp_out << matlab_file_header << endl;
  if (matlab_file != "")
  {
    string cat_command = "cat " + matlab_file + " >> " + tmp_matlab_file;
    system(cat_command.c_str());
  }
  string matlab_command = "matlab -nodisplay -nojvm < " + tmp_matlab_file + "";
  if (launch_in_background)
    matlab_command += " &";
  // Launch Matlab
  matlab = new Popen(matlab_command);

  // Wait until Matlab outputs 'matlab_end_answer'
  string matlab_answer;
  do
  {
    matlab->in >> matlab_answer;
    if (0)
      cout << matlab_answer << endl;
  } while (!matlab->in.eof() && matlab_answer != matlab_end_answer 
           && matlab_answer.find("???",0)==string::npos);
  if (matlab_answer != matlab_end_answer)
    return false;
  if (erase_tmp_files)
    unlink(tmp_matlab_file.c_str());
  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static string PLearn::MatlabInterface::path ( ) [inline, static]

returns where to find appropriate .m files will be appended to the matlab path

Definition at line 143 of file MatlabInterface.h.

References PLERROR.

Referenced by eigs_r11(), and PLearn::matlabR11eigs().

    {
      const char* plearndir = PR_GetEnv("PLEARNDIR");
      if(!plearndir)
        PLERROR("PLEARNDIR environment variable not defined");
      return string(plearndir)+"/Contrib/matlab/";
    }

Here is the caller graph for this function:


Member Data Documentation

Definition at line 251 of file MatlabInterface.h.

string PLearn::MatlabInterface::id [protected]

This is a unique id for a particular Matlab execution (to avoid conflicts).

Definition at line 246 of file MatlabInterface.h.

Some flags.

Definition at line 249 of file MatlabInterface.h.

The communication object that contains the Matlab command line.

Definition at line 214 of file MatlabInterface.h.

Referenced by eigs_r11(), and PLearn::matlabR11eigs().

The pre-defined M-file.

Definition at line 217 of file MatlabInterface.h.

The user-supplied header, that will be concatenated to the top of the M-file.

Definition at line 221 of file MatlabInterface.h.

Referenced by eigs_r11(), and PLearn::matlabR11eigs().


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines