viatra / massif

Massif is a Matlab Simulink Integration Framework for Eclipse
https://viatra.github.io/massif/
Eclipse Public License 1.0
19 stars 14 forks source link

Cannot send CellArrays to Matlab from Java using the Massif API #58

Closed m-morelli closed 6 years ago

m-morelli commented 7 years ago

Hello, I have a running Matlab instance and a Java program properly connected to it. I mean, through properly instantiated

MatlabCommandFactory commandFactory = new MatlabCommandFactory(commandEvaluator);

Now, I want to call a Matlab function to do some work with data coming from my Java program, that I store in a cell array. Here's is how I create the cell array and call the Matlab function using the Massif API:

CellMatlabData s = new CellMatlabData();
s.addData(new Handle(1.0));
s.addData(new Handle(2.0));
commandFactory.customCommand("myTest___XYZ__DRF", 0).addParam(s).execute();

I can't succeed in sending the whole array to Matlab. Indeed, the following implementation of my test function

function myTest___XYZ__DRF(a)
    save 'xxx.mat' a;
end

creates a scalar a in a xxx.mat file, the scalar having the value 2. So it happens that only the last value of the cell array is actually transferred to Matlab.

Any hints? Thanks. Matteo

imbur commented 6 years ago

In this case, multiple function calls are made to MATLAB with the values stored in the cell array, instead of simply creating a cell structure in MATLAB then calling the function. The two commands evaluated are myTest___XYZ__DRF(1.0) and myTest___XYZ__DRF(2.0), which is in line with the reported behavior that xxx.mat only holds the value 2.0, since the initial 1.0 is overwritten by the second call. The reason that we implemented this behavior is that this way the implementations of importer and exporter (main functionalities from an end-user aspect) have become much simpler since there are several methods working on the values stored in some data structure (e.g. cell array) returned by previous calls. Workaround: I cannot think of any elegant way of working around the problem (using the version available on the master branch), but using CustomCommands. E.g.:

Handle handles[] = new Handle[] {new Handle(1.0), new Handle(2.0)};
String varName = "a";
commandFactory.customCommand(varName + " = {}",0).execute();
for (int i = 1; i <=handles.length; i ++) {
    commandFactory.customCommand(varName + "{1," + i + "} = ", 0).addParam(handles[i-1]).execute();         
}
commandFactory.customCommand("myTest___XYZ__DRF("+ varName +")", 0).execute();

(Unfortunately wrapping s to an additional CellMatlabData instance will not work because multiple levels of nesting data structures are not supported as of now.)