Hi,
I am trying to use an S-function in Matlab to use Genie mid-simulation in Simulink. The model needs to be used in the software Veristand, so I need to build the model and therefore generate a function wrapper in C or C++. Does anyone have an example of an S-function wrapper in C or C++ which calls Smile/Genie?
If not, what are the necessary steps to implement the Genie connection to Matlab in C/C++?
Thanks in advance!
Ina
S-function in Simulink
-
- Site Admin
- Posts: 61
- Joined: Mon Nov 06, 2017 6:41 pm
Re: S-function in Simulink
Code: Select all
mex -setup cpp
Code: Select all
cd('full/path/to/smile/directory');
Code: Select all
.
.
.
class MexFunction : public matlab::mex::Function {
public:
void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) {
std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
matlab::data::ArrayFactory factory;
int method = checkMethod(inputs);
checkArguments(method, outputs, inputs);
wrapperBegin(method, outputs, inputs);
}
private:
.
.
.
//WRAPPER BLOCK
int nodesCount(const void * netPtr) {
DSL_network * net = (DSL_network*)netPtr;
return net->GetNumberOfNodes();
}
.
.
.
void wrapperNodesCount(matlab::mex::ArgumentList & outputs, matlab::mex::ArgumentList & inputs) {
matlab::data::ArrayFactory factory;
matlab::data::TypedArray<uint64_t> arr = inputs[1];
auto netPtr = decodePtr(arr[0]);
outputs[0] = factory.createScalar(nodesCount(netPtr));
}
.
.
.
};
Methods whose names starts with "wrapper" are a "bridge" between Matlab and C++ and those above them do all logic.
You can compile the code with the command:
Code: Select all
mex matsmile.cpp
Example commands:
Code: Select all
NET = matsmile('createnetwork'); % create new DSL_network object
matsmile('readfile', NET, 'hepar.xdsl'); % read network from xdsl file
matsmile('nodescount', NET); % get number of nodes in loaded/created network
matsmile('setevidence' NET, 'alcoholism', 'present'); % set evidence on given node
matsmile('freenetwork', NET); % releases memory, don't forget about that because of memory leaks :)
Re: S-function in Simulink
Thank you, the connection between Matlab and Genie using C++ works!
However, Matlab is crashing during simulation in Simulink. It seems to be the GetMatrix() function, as the simulation runs fine without this. Are there alternative ways to extract the probability of a state at a particular node? Preferably as an integer so it can be used further in simulation.
Ina
However, Matlab is crashing during simulation in Simulink. It seems to be the GetMatrix() function, as the simulation runs fine without this. Are there alternative ways to extract the probability of a state at a particular node? Preferably as an integer so it can be used further in simulation.
Ina
-
- Site Admin
- Posts: 61
- Joined: Mon Nov 06, 2017 6:41 pm
Re: S-function in Simulink
https://support.bayesfusion.com/docs/SM ... value.html. If your network contains Equation nodes, you have to get node value as DSL_valEqEvaluation.
But it is still probabilities vector.
If you need integer, chosen node should be observed:
I hope the answer was helpful.
I added node and outcome validation, so the debugging process should be easier now. Getting node value depends on its type, but most common case (CPT node) is described here Code: Select all
DSL_valEqEvaluation * eqValue = static_cast<DSL_valEqEvaluation *>(nodeValue);
const vector<double> &discBeliefs = eqValue->GetDiscBeliefs();
If you need integer, chosen node should be observed:
Code: Select all
node->Value()->IsRealEvidence();
node->Value()->GetEvidence();
-
- Site Admin
- Posts: 61
- Joined: Mon Nov 06, 2017 6:41 pm
Re: S-function in Simulink
There is slightly-improved Smile-Matlab wrapper:
Hello program that uses wrapper looks like this:
It has minimal functionality to support Discrete Bayesian Networks.Hello program that uses wrapper looks like this:
Code: Select all
net = matsmile('newNetwork');
matsmile('readFile', net, 'VentureBN.xdsl');
matsmile('setEvidence', net, 'Forecast', 'Moderate');
matsmile('updateBeliefs', net);
beliefs = matsmile('getValue', net, 'Success');
outcomeIds = matsmile('getOutcomeIds', net, 'Success');
fprintf("%s\n", outcomeIds + "=" + beliefs);
matsmile('deleteNetwork', net);
-
- Site Admin
- Posts: 1419
- Joined: Mon Nov 26, 2007 5:51 pm
Re: S-function in Simulink
The information about calling SMILE from Matlab (including the source code of matsmile.cpp) is now included in main SMILE manual at https://support.bayesfusion.com/docs