Clear Filters
Clear Filters

MEX - Multidimensional Array passing to Fortran

3 views (last 30 days)
Hello, I want to pass back and forth a MxN matrix with K number of pages from matlab to fortran. What mex function/commands would be used to do this? I can do the 2d arrays but haven't found anything for multidimensional arrays.

Accepted Answer

James Tursa
James Tursa on 13 Jul 2012
A couple of options:
--------------------------------------
1)
See this FEX submission:
To use a MATLAB 3D variable passed in to the mex function, e.g.:
use MatlabAPImx
real*8, pointer :: X(:,:,:)
X => fpGetPr3(prhs(1)) ! Does not copy the data
Then you can use X as a regular read-only Fortran variable since it is pointing directly at the data area of the original MATLAB variable in the workspace. I.e., no copy is made. If you need to alter the contents of X then use the copy version of the function instead with an appropriate deallocation at the end:
use MatlabAPImx
real*8, pointer :: X(:,:,:)
X => fpGetPr3copy(prhs(1)) ! Copies the data
! use/modify X
call fpDeallocate(X)
To copy a 3D Fortran array back to an output variable:
use MatlabAPImx
! X is a 3D Fortran real*8 variable
plhs(1) = mxArray(X)
To copy the input to a new matrix, modify it as a Fortran 3D variable, and return the result back to MATLAB you could do this:
use MatlabAPImx
real*8, pointer :: X(:,:,:)
plhs(1) = mxDuplicateArray(prhs(1)) ! Copies the data
X => fpGetPr3(plhs(1)) ! Points to the new copy
! use/modify X
--------------------------------------
2)
Manually get and copy the contents back & forth using mxGetNumberOfDimensions, mxGetDimensions, mxGetPr, mxCopyReal8ToPtr, mxCopyPtrToReal8, and Fortran allocated variables as necessary. Or some combination of the above with the %VAL() construct if you want to avoid data copies. It gets ugly so I will not attempt to write all of the details here.
  2 Comments
Chris
Chris on 16 Jul 2012
Hi James,
I wanted to see if you can help me. I've tried the following but receive an error that states:
error #6159: A component cannot be an array if the encompassing structure is an array. [ORIENTATION] call mxcopyptrtoreal8700(mxGetDimensions700(Blade1_pr),InputMarkers%Blade(:,:)%Orientation,mxGetNumberOfDimensions700(Blade1_pr))
*************************************
my mex input is as follows:
Blades_pr = mxGetField(prhs(1),1, 'Blade(:,1)')
Blade1_pr = mxGetField(Blades_pr,1,'Orientation')
Blade1_ptr = mxGetPr(Blade1_pr)
call mxcopyptrtoreal8(mxGetDimensions(Blade1_pr),InputMarkers%Blade(:,:)%Orientation,mxGetNumberOfDimensions(Blade1_pr))
I want to pass myvar.myfield(:,:).subfield, which is a 3x3 array with 17 pages to the fortran code. I'm not sure if I did the mxgetdimensions part right or not.
James Tursa
James Tursa on 16 Jul 2012
You cannot specify 'Blade(:,1)' as a field name. It has to be just the field name itself, e.g. 'Blade'.
mxGetDimensions is hard to work with in Fortran since it returns a pointer to an integer array and you can't work with it directly as is. You would need to pass it to a subroutine via %VAL() to be able to get at the dimension values.
Can you show what the declarations are for InputMarkers, Blade, and Orientation? I am not sure what you are trying to copy here.

Sign in to comment.

More Answers (0)

Categories

Find more on Fortran with MATLAB in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!