Darwin  1.10(beta)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
drwnMatlabUtils.h
1 /*****************************************************************************
2 ** DARWIN: A FRAMEWORK FOR MACHINE LEARNING RESEARCH AND DEVELOPMENT
3 ** Distributed under the terms of the BSD license (see the LICENSE file)
4 ** Copyright (c) 2007-2015, Stephen Gould
5 ** All rights reserved.
6 **
7 ******************************************************************************
8 ** FILENAME: drwnMatlabUtils.h
9 ** AUTHOR(S): Stephen Gould <stephen.gould@anu.edu.au>
10 **
11 *****************************************************************************/
12 
13 #pragma once
14 
15 #include <cstdlib>
16 #include <cassert>
17 #include <string>
18 #include <map>
19 
20 // eigen
21 #include "Eigen/Core"
22 
23 // matlab
24 #include "mex.h"
25 #include "matrix.h"
26 
27 // darwin
28 #include "drwnBase.h"
29 #include "drwnIO.h"
30 #include "drwnPGM.h"
31 
32 using namespace std;
33 using namespace Eigen;
34 
35 // drwnMatlabUtils ---------------------------------------------------------
37 
38 namespace drwnMatlabUtils {
39 
41  void mexMsgTxt(const char *message) { mexPrintf("%s\n", message); }
42 
44  void setupLoggerCallbacks();
45 
48  drwnTableFactor *parseFactor(const drwnVarUniversePtr& pUniverse,
49  const mxArray *factor, int factorIndx = 0);
50 
52  void printStandardOptions();
53 
55  void initializeStandardOptions(map<string, string>& options);
56 
59  bool parseOptions(const mxArray *optionStruct, map<string, string>& options);
60 
62  void processStandardOptions(map<string, string>& options);
63 
65  void mxArrayToVector(const mxArray *m, vector<vector<double> > &v);
66 
68  void mxArrayToEigen(const mxArray *m, MatrixXd& A);
69 
71  void mxArrayToEigen(const mxArray *m, VectorXd& b);
72 
74  void mxArrayToEigen(const mxArray *m, vector<MatrixXd>& A);
75 };
76 
77 // drwnMatlabUtils implementation ------------------------------------------
78 
79 // TODO: work out how to compile these not inline
80 
82 {
83  // setup callbacks
84  drwnLogger::showFatalCallback = mexErrMsgTxt;
85  drwnLogger::showErrorCallback = mexErrMsgTxt;
86  drwnLogger::showWarningCallback = mexWarnMsgTxt;
89 
90  // reset since statics persist between Matlab calls
91  drwnLogger::setLogLevel(DRWN_LL_MESSAGE);
92 }
93 
94 
96  const mxArray *factor, int factorIndx)
97 {
98  mxAssert(mxIsStruct(factor), "invalid factor datastructure");
99 
100  // add variables
101  mxArray *vars = mxGetField(factor, factorIndx, "vars");
102  mxAssert(vars != NULL, "field 'vars' missing");
103 
104  drwnTableFactor *phi = new drwnTableFactor(pUniverse);
105  for (int i = 0; i < mxGetNumberOfElements(vars); i++) {
106  phi->addVariable((int)mxGetPr(vars)[i]);
107  }
108 
109  // add data
110  mxArray *data = mxGetField(factor, factorIndx, "data");
111  if ((data == NULL) || mxIsEmpty(data)) {
112  return phi;
113  }
114  mxAssert(mxGetNumberOfElements(data) == (int)phi->entries(),
115  "wrong number of elements in field 'data'");
116 
117  for (int i = 0; i < phi->entries(); i++) {
118  (*phi)[i] = mxGetPr(data)[i];
119  }
120 
121  return phi;
122 }
123 
125 {
126  mexPrintf(" config :: configure Darwin from XML file\n");
127  mexPrintf(" set :: set configuration (module, property, value triplets)\n");
128  mexPrintf(" profile :: profile code\n");
129  mexPrintf(" verbose :: show verbose messages\n");
130  mexPrintf(" debug :: show debug messages\n");
131 }
132 
133 void drwnMatlabUtils::initializeStandardOptions(map<string, string>& options)
134 {
135  options[string("config")] = string("");
136  options[string("set")] = string("");
137  options[string("profile")] = string("0");
138  options[string("verbose")] = string("0");
139  options[string("debug")] = string("0");
140 }
141 
142 bool drwnMatlabUtils::parseOptions(const mxArray *optionStruct, map<string, string>& options)
143 {
144  if ((optionStruct == NULL) || (mxIsEmpty(optionStruct))) {
145  return false;
146  }
147 
148  if (!mxIsStruct(optionStruct)) {
149  DRWN_LOG_FATAL("options must be a Matlab structure");
150  }
151 
152  int N = mxGetNumberOfFields(optionStruct);
153  for (int i = 0; i < N; i++) {
154  // get field name and value
155  const char *name = mxGetFieldNameByNumber(optionStruct, i);
156  mxArray *value = mxGetFieldByNumber(optionStruct, 0, i);
157  if ((value == NULL) || (mxIsEmpty(value))) {
158  continue;
159  }
160 
161  // check value type
162  if (mxIsChar(value)) {
163  char *v = mxArrayToString(value);
164  options[string(name)] = string(v);
165  mxFree(v);
166  } else if (mxIsNumeric(value)) {
167  if (mxGetNumberOfElements(value) == 1) {
168  options[string(name)] = toString(mxGetScalar(value));
169  } else {
170  string v;
171  for (int i = 0; i < mxGetNumberOfElements(value); i++) {
172  if (i > 0) v = v + string(" ");
173  v = v + toString(mxGetPr(value)[i]);
174  }
175  options[string(name)] = v;
176  }
177  } else {
178  mexErrMsgTxt("invalid option value");
179  }
180  }
181 
182  return true;
183 }
184 
185 void drwnMatlabUtils::processStandardOptions(map<string, string>& options)
186 {
187  // xml configuration
188  if (!options[string("config")].empty()) {
189  drwnConfigurationManager::get().configure(options[string("config")].c_str());
190  }
191 
192  // module property setting
193  if (!options[string("set")].empty()) {
194  vector<string> tokens;
195  const int n = drwn::parseString(options[string("set")], tokens);
196  if (n == 1) {
197  drwnConfigurationManager::get().showModuleUsage(tokens[0].c_str());
198  mexErrMsgTxt("");
199  }
200  if (n % 3 != 0) {
201  DRWN_LOG_FATAL("'set' option requires triplets of the form 'module property value'");
202  }
203 
204  for (int i = 0; i < n; i += 3) {
205  drwnConfigurationManager::get().configure(tokens[i].c_str(),
206  tokens[i + 1].c_str(), tokens[i + 2].c_str());
207  }
208  }
209 
210  // code profiling
211  drwnCodeProfiler::enabled = (atoi(options[string("profile")].c_str()) != 0);
212 
213  // message verbosity
214  if (atoi(options[string("verbose")].c_str()) != 0) {
215  drwnLogger::setLogLevel(DRWN_LL_VERBOSE);
216  }
217  if (atoi(options[string("debug")].c_str()) != 0) {
218  drwnLogger::setLogLevel(DRWN_LL_DEBUG);
219  }
220 }
221 
222 void drwnMatlabUtils::mxArrayToVector(const mxArray *m, vector<vector<double> > &v)
223 {
224  if (mxGetClassID(m) != mxDOUBLE_CLASS) {
225  DRWN_LOG_FATAL("expecting matrix of type double");
226  }
227 
228  const int nRows = mxGetM(m); // number of rows
229  const int nCols = mxGetN(m); // number of columns
230  v.resize(nRows);
231  const double *p = mxGetPr(m);
232  for (int i = 0; i < nRows; i++) {
233  v[i].resize(nCols);
234  for (int j = 0; j < nCols; j++) {
235  v[i][j] = p[j * nRows + i];
236  }
237  }
238 }
239 
240 void drwnMatlabUtils::mxArrayToEigen(const mxArray *m, MatrixXd& A)
241 {
242  if (mxGetClassID(m) != mxDOUBLE_CLASS) {
243  DRWN_LOG_FATAL("expecting matrix of type double");
244  }
245 
246  const int nRows = mxGetM(m); // number of rows
247  const int nCols = mxGetN(m); // number of columns
248  DRWN_LOG_DEBUG("parsing a " << nRows << "-by-" << nCols << " matrix...");
249 
250  A.resize(nRows, nCols);
251  const double *p = mxGetPr(m);
252  for (int i = 0; i < nRows; i++) {
253  for (int j = 0; j < nCols; j++) {
254  A(i, j) = p[j * nRows + i];
255  }
256  }
257 }
258 
259 void drwnMatlabUtils::mxArrayToEigen(const mxArray *m, VectorXd& b)
260 {
261  if (mxGetClassID(m) != mxDOUBLE_CLASS) {
262  DRWN_LOG_FATAL("expecting matrix of type double");
263  }
264 
265  const int nRows = mxGetM(m); // number of rows
266  const int nCols = mxGetN(m); // number of columns
267 
268  b = Eigen::Map<VectorXd>(mxGetPr(m), nRows * nCols);
269 }
270 
271 void drwnMatlabUtils::mxArrayToEigen(const mxArray *m, vector<MatrixXd>& A)
272 {
273  if (mxGetNumberOfDimensions(m) < 3) {
274  A.resize(1);
275  mxArrayToEigen(m, A[0]);
276  return;
277  }
278 
279  DRWN_ASSERT(mxGetNumberOfDimensions(m) == 3);
280  const int nRows = mxGetDimensions(m)[0]; // number of rows
281  const int nCols = mxGetDimensions(m)[1]; // number of columns
282  const int nChannels = mxGetDimensions(m)[2]; // number of channels
283  DRWN_LOG_DEBUG("parsing a " << nRows << "-by-" << nCols << "-by-" << nChannels << " matrix...");
284 
285  A.resize(nChannels, MatrixXd::Zero(nRows, nCols));
286  const double *p = mxGetPr(m);
287  for (int c = 0; c < nChannels; c++) {
288  for (int x = 0; x < nCols; x++) {
289  for (int y = 0; y < nRows; y++) {
290  A[c](y, x) = *p++;
291  }
292  }
293  }
294 }
void configure(const char *filename)
configure all registered modules from XML file
Definition: drwnConfigManager.cpp:98
bool parseOptions(const mxArray *optionStruct, map< string, string > &options)
parses Matlab structure of options, assuming that each field is either a scalar or a string...
Definition: drwnMatlabUtils.h:142
static void(* showErrorCallback)(const char *message)
callback for non-fatal errors
Definition: drwnLogger.h:99
static void(* showWarningCallback)(const char *message)
callback for warnings
Definition: drwnLogger.h:101
void mxArrayToEigen(const mxArray *m, MatrixXd &A)
converts a Matlab matrix to an eigen matrix
Definition: drwnMatlabUtils.h:240
void showModuleUsage(const char *module) const
show usage for a specific module
Definition: drwnConfigManager.cpp:137
static void(* showStatusCallback)(const char *message)
callback for status updates
Definition: drwnLogger.h:103
static bool enabled
set true to enable profiling
Definition: drwnCodeProfiler.h:70
void processStandardOptions(map< string, string > &options)
processes standard options
Definition: drwnMatlabUtils.h:185
static void(* showFatalCallback)(const char *message)
callback for fatal errors
Definition: drwnLogger.h:97
Factor which stores the value of each assignment explicitly in table form.
Definition: drwnTableFactor.h:144
void setupLoggerCallbacks()
sets drwnLogger callbacks to output to Matlab
Definition: drwnMatlabUtils.h:81
void initializeStandardOptions(map< string, string > &options)
initializes standard options structure
Definition: drwnMatlabUtils.h:133
void mxArrayToVector(const mxArray *m, vector< vector< double > > &v)
converts a Matlab matrix to an stl vector of vectors
Definition: drwnMatlabUtils.h:222
std::string toString(const T &v)
Templated function to make conversion from simple data types like int and double to strings easy for ...
Definition: drwnStrUtils.h:134
void mexMsgTxt(const char *message)
print a message to the matlab console
Definition: drwnMatlabUtils.h:41
drwnTableFactor * parseFactor(const drwnVarUniversePtr &pUniverse, const mxArray *factor, int factorIndx=0)
parse a table factor from a structure array s with fields s.vars and s.data
Definition: drwnMatlabUtils.h:95
void addVariable(int var)
add variable by id
Definition: drwnTableFactor.cpp:236
static void(* showMessageCallback)(const char *message)
callback for messages (standard, verbose and debug)
Definition: drwnLogger.h:105
static void setLogLevel(drwnLogLevel level)
set the current verbosity level
Definition: drwnLogger.h:132
static drwnConfigurationManager & get()
get the configuration manager (singleton object)
Definition: drwnConfigManager.cpp:92
void printStandardOptions()
prints standard options to Matlab console
Definition: drwnMatlabUtils.h:124