-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMexInterface.cpp
More file actions
105 lines (96 loc) · 3.2 KB
/
Copy pathMexInterface.cpp
File metadata and controls
105 lines (96 loc) · 3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Copyright (C) 2016 William H. Greene
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 3 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, see <http://www.gnu.org/licenses/>.
#include "MexInterface.h"
MexInterface::MexInterface(int maxOutArgs) : maxOutArgs(maxOutArgs)
{
matOutArgs.resize(maxOutArgs);
}
MexInterface::~MexInterface()
{
}
void MexInterface::print(const mxArray *a, const char *name)
{
mwSize m = mxGetM(a);
mwSize n = mxGetN(a);
const Eigen::Map<Eigen::MatrixXd> A(mxGetPr(a), m, n);
mexPrintf("%s(%d,%d)\n", name, m, n);
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++)
printf("%g ", A(i, j));
printf("\n");
}
}
void MexInterface::callMatlab(const mxArray *inArgs[], int nargin,
RealVector *outArgs[], int nargout)
{
int err = mexCallMATLAB(nargout, &matOutArgs[0], nargin,
const_cast<mxArray**>(inArgs), "feval");
if (err) {
char msg[1024];
std::string funcName = getFuncNameFromHandle(inArgs[0]);
sprintf(msg, "An error occurred in the call to user-defined function:\n\"%s\".",
funcName.c_str());
mexErrMsgIdAndTxt("bvp1d:mexCallMATLAB:err", msg);
}
for (int i = 0; i < nargout; i++) {
mxArray *a = matOutArgs[i];
if (!a)
mexErrMsgIdAndTxt("bvp1d:mexCallMATLAB:arg", "Error in mexCallMATLAB arg.");
mwSize retLen = mxGetNumberOfElements(a);
size_t exLen = outArgs[i]->size();
if (retLen != exLen) {
char msg[1024];
std::string funcName = getFuncNameFromHandle(inArgs[0]);
mwSize m = mxGetM(a), n = mxGetN(a);
sprintf(msg, "In the call to user-defined function:\n\"%s\"\n"
"returned entry %d had size (%d x %d) but a vector of size (%d x 1)"
" was expected.", funcName.c_str(), i + 1, m, n, exLen);
mexErrMsgIdAndTxt("bvp1d:mexCallMATLAB:arglen", msg);
}
std::copy_n(mxGetPr(a), retLen, outArgs[i]->data());
if (a)
mxDestroyArray(a);
}
}
std::string MexInterface::getFuncNameFromHandle(const mxArray *fh)
{
mxArray *funcName = 0;
int err = mexCallMATLAB(1, &funcName, 1,
const_cast<mxArray**>(&fh), "func2str");
if (err)
mexErrMsgIdAndTxt("bvp1d:mexCallMATLAB",
"Error in mexCallMATLAB.\n");
const int bufLen = 1024;
char buf[bufLen];
int len = mxGetString(funcName, buf, bufLen);
std::string nam(buf);
return nam;
}
Eigen::MatrixXd MexInterface::fromMxArray(const mxArray *a)
{
const mwSize m = mxGetM(a);
const mwSize n = mxGetN(a);
Eigen::MatrixXd mat(m, n);
std::copy_n(mxGetPr(a), m*n, mat.data());
return mat;
}
Eigen::VectorXd MexInterface::fromMxArrayVec(const mxArray *a)
{
const mwSize m = mxGetM(a);
const mwSize n = mxGetN(a);
Eigen::VectorXd mat(m*n);
std::copy_n(mxGetPr(a), m*n, mat.data());
return mat;
}