-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMXsparseQuadrature.cpp
More file actions
143 lines (123 loc) · 4.78 KB
/
Copy pathMXsparseQuadrature.cpp
File metadata and controls
143 lines (123 loc) · 4.78 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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include <string>
#include <iostream>
#include <Eigen/Dense>
#include "mex.h"
#include "matrix.h"
#include "SparseIndexSet.hpp"
#include "TDindexSet.hpp"
#include "HCindexSet.hpp"
#include "SparseQuadrature.hpp"
#include "Cell2univariateQuadrature.hpp"
// fancy compare functor that performs the callback to Matlab
struct MatlabCpFun {
const mxArray *_prhs[2];
mxArray *_MatAlpha;
int _dim;
MatlabCpFun(const mxArray *prhs, int dim) {
_MatAlpha = mxCreateDoubleMatrix(dim, 1, mxREAL);
_prhs[0] = prhs;
_prhs[1] = _MatAlpha;
_dim = dim;
};
double operator()(const Eigen::VectorXi &alpha) const {
mxArray *plhs;
Eigen::Map<Eigen::VectorXd>(mxGetPr(_MatAlpha), _dim) =
alpha.cast<double>();
mexCallMATLAB(1, &plhs, 2, const_cast<mxArray **>(_prhs),
(const char *)"feval");
if (mxIsScalar(plhs))
return *(mxGetPr(plhs));
else
mexErrMsgIdAndTxt(
"MATLAB:MXsparseQuadraturecpp",
"MXsparseQuadrature requires adequate function handle. Check help.");
return 0.;
};
};
/** nlhs Number of expected output mxArrays
* plhs Array of pointers to the expected output mxArrays
* nrhs Number of input mxArrays
* prhs Array of pointers to the input mxArrays.
* Do not modify any prhs values in your MEX file.
* Changing the data in these read-only mxArrays can
* produce undesired side effects.
*/
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
int q = 0;
int dim = 0;
int nPts = 0;
int myCASE = 0;
TDindexSet TDind;
HCindexSet HCind;
SparseIndexSet GENind;
SparseQuadrature Q;
Cell2univariateQuadrature CellUniQ;
if (nrhs != 5) {
mexErrMsgIdAndTxt(
"MATLAB:MXsparseQuadraturecpp:nargin",
"MXsparseQuadrature requires five input arguments. Check help.");
} else if (nlhs < 2) {
mexErrMsgIdAndTxt("MATLAB:MXsparseQuadraturecpp:nargin",
"MXsparseQuadrature requires at least two output "
"arguments. Check help.");
} else if (!mxIsScalar(prhs[0]) || !mxIsScalar(prhs[1])) {
mexErrMsgIdAndTxt("MATLAB:MXsparseQuadraturecpp",
"First two arguments have to be scalar. Check help.");
} else if (!mxIsChar(prhs[2])) {
mexErrMsgIdAndTxt("MATLAB:MXsparseQuadraturecpp",
"Third argument has to be a string. Check help.");
} else if (!mxIsCell(prhs[3]))
mexErrMsgIdAndTxt("MATLAB:MXsparseQuadraturecpp",
"Fourth argument has to be a Cell array. Check help.");
q = std::round(*(mxGetPr(prhs[0])));
dim = std::round(*(mxGetPr(prhs[1])));
std::string type(mxArrayToString(prhs[2]));
CellUniQ.initQuadrature(prhs[3]);
// convert type to uppercase
for (auto i = type.begin(); i != type.end(); ++i)
*i = std::toupper(*i);
if (type == "TD") {
if (mxIsClass(prhs[4], "function_handle"))
mexErrMsgIdAndTxt(
"MATLAB:MXsparseQuadraturecpp",
"Last argument has to be array if TD is used. Check help.");
TDind.computeIndexSet(q, Eigen::Map<Eigen::VectorXd>(mxGetPr(prhs[4]), dim));
Q = SparseQuadrature(TDind, CellUniQ);
Q.purgeSparseQuadrature();
plhs[2] = mxCreateDoubleMatrix(dim, 1, mxREAL);
Eigen::Map<Eigen::VectorXd> sort(mxGetPr(plhs[2]), dim);
const Eigen::VectorXi &mySort = TDind.get_sortW();
sort = mySort.cast<double>().array() + 1;
} else if (type == "HC") {
if (mxIsClass(prhs[4], "function_handle"))
mexErrMsgIdAndTxt(
"MATLAB:MXsparseQuadraturecpp",
"Last argument has to be array if HC is used. Check help.");
HCind.computeIndexSet(q, Eigen::Map<Eigen::VectorXd>(mxGetPr(prhs[4]), dim));
Q = SparseQuadrature(HCind, CellUniQ);
Q.purgeSparseQuadrature();
} else if (type == "GEN") {
if (!mxIsClass(prhs[4], "function_handle"))
mexErrMsgIdAndTxt("MATLAB:MXsparseQuadraturecpp",
"Last argument has to be function handle if Gen is "
"used. Check help.");
GENind.computeIndexSet(q, dim, MatlabCpFun(prhs[4], dim));
Q = SparseQuadrature(GENind, CellUniQ);
Q.purgeSparseQuadrature();
} else {
mexErrMsgIdAndTxt("MATLAB:MXsparseQuadraturecpp",
"type has an invalid value. Check help.");
}
const Eigen::MatrixXd &myqPoints = Q.get_qPoints();
const Eigen::VectorXd &myqWeights = Q.get_qWeights();
nPts = myqWeights.size();
plhs[0] = mxCreateDoubleMatrix(dim, nPts, mxREAL);
plhs[1] = mxCreateDoubleMatrix(nPts, 1, mxREAL);
if (nlhs == 3 && type != "TD") plhs[2] = mxCreateDoubleMatrix(0, 0, mxREAL);
// set quadrature Points and Weights
Eigen::Map<Eigen::MatrixXd> qPoints(mxGetPr(plhs[0]), dim, nPts);
Eigen::Map<Eigen::VectorXd> qWeights(mxGetPr(plhs[1]), nPts);
qPoints = myqPoints;
qWeights = myqWeights;
return;
}