PLearn 0.1
|
#include <MatlabInterface.h>
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) | |
Popen * | launch () |
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 | |
Popen * | matlab |
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 |
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.
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; }
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()); } }
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()); } }
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()); } }
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; }
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; }
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/"; }
bool PLearn::MatlabInterface::erase_tmp_files [protected] |
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.
bool PLearn::MatlabInterface::launch_in_background [protected] |
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().