-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathlogpost_c.cpp
139 lines (110 loc) · 3.81 KB
/
logpost_c.cpp
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
// compile with:
//
// mex logpost_c.cpp printmex.cpp -I/usr/local/boost-1.64.0/include/
// TODO dedupe with logprior_c and sample_c and loglik
//
// see https://stackoverflow.com/questions/16127060/what-is-the-default-location-for-boost-library-when-installed-using-macport-on-m
// and https://www.mathworks.com/matlabcentral/answers/7955-using-boost-libraries-with-mex-function-in-matlab
/* ========================================================================
* copy of
* phonebook.cpp
* example for illustrating how to manipulate structure.
*
* takes a (MxN) structure matrix which has first field as
* character array(name), and second field as scalar double (phone number).
* This function returns a new structure (1x1)containing following fields:
* for character array input, it will be (MxN) cell array;
* and for numeric double (noncomplex, scalar) input, it will be (MxN)
* cell array where each field is numeric array of type double.
*
* Build : from MATLAB
* >> mex phonebook.cpp
* Usage with example : from MATLAB
* >> friends(1).name = 'Jordan Robert';
* >> friends(1).phone = 3386;
* >> friends(2).name = 'Mary Smith';
* >> friends(2).phone = 3912;
* >> friends(3).name = 'Stacy Flora';
* >> friends(3).phone = 3238;
* >> friends(4).name = 'Harry Alpert';
* >> friends(4).phone = 3077;
* >> phonebook(friends)
*
* This is a MEX-file for MATLAB.
* Copyright 2017 The MathWorks, Inc.
*=======================================================================*/
#include "mex.hpp"
#include "mexAdapter.hpp"
#include "printmex.h"
#include "datastructs.h"
// needs to come last I think
#include "helpermex.h"
class MexFunction : public Function {
private:
std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr;
public:
/* Constructor for the class. */
MexFunction()
{
matlabPtr = getEngine();
}
void displayError(std::string errorMessage)
{
::displayError(errorMessage, matlabPtr);
}
/* This is the gateway routine for the MEX-file. */
void
operator()(ArgumentList outputs, ArgumentList inputs) {
std::srand(0); // for reproducibility
checkArguments (outputs,inputs);
// D
StructArray const matlabStructArrayD = inputs[1];
Data::check(matlabStructArrayD, matlabPtr);
Data D(matlabStructArrayD);
// h
StructArray const matlabStructArrayHyperparams = inputs[2];
Hyperparams::check(matlabStructArrayHyperparams, matlabPtr);
Hyperparams h(matlabStructArrayHyperparams);
// H
Hierarchy H(D.G.N);
StructArray const matlabStructArrayH = inputs[0];
Hierarchy::check(matlabStructArrayH, D, matlabPtr);
H.InitFromMATLAB(matlabStructArrayH);
H.Print();
// compute Logpost
//
double logp = H.LogPost(D, h);
// read up on https://www.mathworks.com/help/matlab/apiref/matlab.data.arrayfactory.html?searchHighlight=createarray&s_tid=doc_srchtitle#bvn7dve-1
ArrayFactory factory;
Array result = factory.createScalar<double>(logp);
outputs[0] = result;
}
// check function arguments
//
void checkArguments(ArgumentList outputs, ArgumentList inputs) {
if (inputs.size() < 3)
{
displayError("Specify H, D and h as input arguments.");
}
if (inputs.size() > 3)
{
displayError("Too many input arguments.");
}
if (outputs.size() > 1)
{
displayError("Too many outputs specified.");
}
if (inputs[0].getType() != ArrayType::STRUCT)
{
displayError("H must be a structure.");
}
if (inputs[1].getType() != ArrayType::STRUCT)
{
displayError("D must be a structure.");
}
if (inputs[2].getType() != ArrayType::STRUCT)
{
displayError("h must be a structure.");
}
}
};