3

I have a dataframe which holds covariance data, hence we have a square matrix. I translate this dataframe into numpy and then to list as below, so that I can use it with the matlab api:

import matlab.engine
eng = matlab.engine.start_matlab()

covdata_list = covdata.values.tolist()
covdata_MATLAB = matlab.double(covdata_list)

Then I create an anonymous function from python using the matlab api as follows, which does the simplest task ever:

eng.eval(f"obj_func = @(x) x;", nargout=0)

All good so far, BUT when I send the covariance data-translated in MATLAB's format- i.e. covdata_MATLAB the following happens:

returns = eng.eval(f'obj_func({covdata_MATLAB})', nargout=1)
eng.size(returns)
>>>> matlab.double([[1.0,15625.0]])

While:

eng.size(covdata_MATLAB)
>>>> matlab.double([[125.0,125.0]])

As we can see it as if it "flattens" the covariance and produces a row vector of 1 X (125*125).

Is there a workaround or is there something I am missing?

  • 1
    In both matlab and python, arrays are all 1D under the hood. Its easier (and more efficient) to have 1D arrays and just wrap some fancy dimensional index on top. Maybe size info gets lost somewhere on the way – Ander Biguri Feb 01 '21 at 19:25
  • @AnderBiguri true and agree, but there should be some workaround. Is there any 1-liner that combined with eng.eval() from python can bring back the “shape” of the covariance? – wanna_be_quant Feb 01 '21 at 19:29

1 Answers1

0

It is not an exact solution to the above, but -I would say- rather a workaround which in my case and given my programming goals works.

So the goal was to pass the variable to MATLAB without the need to reshape/resize the matrix.

  • What I was trying to do and the output I got:

    returns = eng.eval(f'obj_func({covdata_MATLAB})', nargout=1)
    eng.size(returns)
    >>>> matlab.double([[1.0,117649.0]])
    

(117649.0 corresponds to 343x343 which the square matrix used for this example; in initial Q I was using 125x125 hence the 15625.0, I hope this is clear)

  • What I do now and everything has the appropriate size:

    covdata_MATLAB = matlab.double(covdata_list)
    eng.size(covdata_MATLAB)
    >>>> matlab.double([[343.0,343.0]])
    
    eng.workspace['covariance'] = covdata_MATLAB 
    

If I have a look at the workspace now I can see the following:

enter image description here

This is convenient in my case it may not be a solution for others.

end result when calling:

returns = eng.eval(f'obj_func(covariance)', nargout=1) #be careful now you have to use the variable name defined in the MATLAB workspace, i.e covariance and not covdata_MATLAB
eng.size(returns)
>>>> matlab.double([[343.0,343.0]])
Dharman
  • 30,962
  • 25
  • 85
  • 135