3
votes

I have a function in a MATLAB algorithm which uses the function sum. As described in the doc, the input of that function must be one of these types:

  • Vector
  • Matrix
  • Multidimentionnal array

I know there are functions and doc on the MATLAB website to convert those datatypes. The problem is that I do not have the permission to modify the algorithm, only what I am sending it to. Is there a way to make the appropriate changes in python rather than taking the python data in MATLAB an making the data type changes?

For now, I have tried to use the MATLAB functions from the engine into python directly. I'm not sure that the conversion works properly.

Here is a MWE of my problem:

import matlab
import matlab.engine

myEngine = matlab.engine.start_matlab()
pythonData = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
pythonData = myEngine.cellstr(pythonData)
print('after cellstr()', pythonData)
pythonData = myEngine.cell2mat(pythonData)
print('after cell2mat()', pythonData)
matlabSum = myEngine.sum(pythonData)
print('sum:', matlabSum)

Here is the output on my terminal.

You will notice that cellstr didn't do much, which is weird. Does anyone have an idea on how to properly make those conversion? Also, the sum is not 477. It sould be 45. I'm pretty sure it is because it converts it into ASCII, which would result in [49,50,51,...] giving 477.

Since matlab convert automatically lists into cells, I have tried changing every values for integers and then using engine.cell2mat directly onto the list, but I get this error:

TypeError: array of MATLAB int64 type cannot be returned on this platform

As of now, I'm still trying to convert a python into one of the MATLAB data formats mentioned above. I run Python 2.7.

1
I don't get the 477 number. The sum of those values is 45...?tryman
While you run the code? I assure you it sums to 477. I'll add a figure. I know that the arithmetical sum of the numbers in the list sums to 45...PyThagoras
I saw your post before the edit "It should be 45" and it was as if the expected sum was 477 (and not 45).tryman

1 Answers

3
votes

pythonData is a string:

>>> pythonData = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
>>> pythonData = myEngine.cellstr(pythonData)
>>> pythonData = myEngine.cell2mat(pythonData)
>>> type(pythonData)
<class 'str'>

When you call the MATLAB engine function, the string is being converted to a char.

When you pass Python® data as input arguments to MATLAB® functions, the MATLAB Engine for Python converts the data into equivalent MATLAB data types.

As documented here. In this case, the conversion is from str to char. When you call the function sum, MATLAB is converting the characters to numbers (a 0 is 48 in ASCII, 1 is 49 and so on) , and performing the sum along the second dimension, which results in the puzzling number 477. If you perform the sum on the first dimension, you can see that MATLAB is, in fact, converting the characters in the string to numbers:

>>> myEngine.sum(pythonData,1)
matlab.double([[49.0,50.0,51.0,52.0,53.0,54.0,55.0,56.0,57.0]])

To resolve this, you can create a matlab.double object from a Python list of ints. Then, you can call the sum function and obtain the expected result. In Python 3, you can do this as follows:

>>> pythonData = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
>>> pythonNum = list(map(int,results))
>>> matlabNum=matlab.double(pythonNum)
>>> myEngine.sum(matlabNum)
45.0

Above, I use this solution for the conversion.