From: HIEU on
Hello,
After fighting the problem the whole Saturday, I think I need some experts' help.

My problem: a 3-dimensional array, say data(m,n,p) where m,n,p are positive integers, is written to a MAT-file in Matlab.

Question: How to read the MAT-file in Fortran F90 and store the data in a similar 3-dimensional array? I am, a novice of course, using Intel Visual Fortran Compiler on XP 32bit.

I tried to use the module MatData.f90 by Chen at:
http://www.mathworks.fr/matlabcentral/fileexchange/4902-matdata-ver-1-02
but was unable to get it to work and received a message "error LNK2019: unresolved external symbol _READ referenced in function _MAIN_"

Below is my simple fortran code to use the module:

PROGRAM READINPUT
USE MatData
IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(2,2,2) :: localvar
CALL READ('test.mat','wind',localvar)
END PROGRAM READINPUT

where test.mat is a MAT-file stores a 2x2x2 array created by MATLAB.
It seems the module MatData.f90 by Chen does not work with Intel Fortran Compiler.

Do you have any idea or suggestion to solve the problem (read 3-dimensional array from a MAT-file in Fortran 90)?
Any helpwould be highly appreciated.
Thanks
Hieu
From: Rune Allnor on
On 27 Des, 07:26, "HIEU " <nguyenhuyh...(a)gmail.com> wrote:
> Hello,
> After fighting the problem the whole Saturday, I think I need some experts' help.
>
> My problem: a 3-dimensional array, say data(m,n,p) where m,n,p are positive integers, is written to a MAT-file in Matlab.
>
> Question: How to read the MAT-file in Fortran F90 and store the data in a similar 3-dimensional array? I am, a novice of course, using Intel Visual Fortran Compiler on XP 32bit.

You might be able to use a matlab engine, if this kind
of thing is available for fortran. Check the "External
Interfaces" section of the matlab documentation.

A quick'n dirty solution is to skip the .mat format
alltogether, and instead write the array to a text
file from matla, that is read from fortran. Write the
data as p tables of size m x n, either consecutively
in the same file, or in p files.

This kind of thing is fast to implement, but might
be a bit slow to run if the array is large.

Rune

From: James Tursa on
"HIEU " <nguyenhuyhieu(a)gmail.com> wrote in message <hh6ulr$e38$1(a)fred.mathworks.com>...
> Hello,
> After fighting the problem the whole Saturday, I think I need some experts' help.
>
> My problem: a 3-dimensional array, say data(m,n,p) where m,n,p are positive integers, is written to a MAT-file in Matlab.
>
> Question: How to read the MAT-file in Fortran F90 and store the data in a similar 3-dimensional array? I am, a novice of course, using Intel Visual Fortran Compiler on XP 32bit.
>
> I tried to use the module MatData.f90 by Chen at:
> http://www.mathworks.fr/matlabcentral/fileexchange/4902-matdata-ver-1-02
> but was unable to get it to work and received a message "error LNK2019: unresolved external symbol _READ referenced in function _MAIN_"
>
> Below is my simple fortran code to use the module:
>
> PROGRAM READINPUT
> USE MatData
> IMPLICIT NONE
> DOUBLE PRECISION, DIMENSION(2,2,2) :: localvar
> CALL READ('test.mat','wind',localvar)
> END PROGRAM READINPUT
>
> where test.mat is a MAT-file stores a 2x2x2 array created by MATLAB.
> It seems the module MatData.f90 by Chen does not work with Intel Fortran Compiler.
>
> Do you have any idea or suggestion to solve the problem (read 3-dimensional array from a MAT-file in Fortran 90)?
> Any helpwould be highly appreciated.
> Thanks
> Hieu

I wrote a Fortran 95 interface to the MATLAB API that should solve your problem. It has been tested with the Intel Fortran compiler. You can find the submission here:

http://www.mathworks.com/matlabcentral/fileexchange/25934-fortran-95-interface-to-matlab-api-with-extras

In particular, look at the MatlabAPI_matfile.f file for an example of loading variables from a mat file, and MatlabAPI_real.f for examples of turning mxArray variables into Fortran arrays and vice-versa. e.g., this line in the code loads an mxArray variable from the mat file:

mx = matGetVariable(matfile, names(i))

To turn that mxArray variable mx into a regular Fortran array that you can use downstream, I supply two functions. The first function points directly at the mxArray data area, so changes to the target array will be direct changes to the mxArray data area. It can be used like this for a 3D mxArray:

use MatlabAPImx
use MatlabAPImat
:
real(8), pointer :: fp(:,:,:)
:
mx = matGetVariable(matfile, names(i))
if( mx == 0 ) error, so do something
fp => fpGetPr(mx)
if( .not.associated(fp) ) error, so do something
fp(1,2,3) = 5.d0 ! <-- This will change the data area of mx

Then the Fortran pointer fp can be used just like a regular 3D Fortran array in all your downstream code, with changes to the fp target being direct changes to the data area of the mxArray mx. After you are done with the data, destroy the mxArray variable mx:

mxDestroyArray(mx)

The other method is to make a copy of the mxArray mx data area and get a pointer to that. Changes to the target array of this pointer will *not* affect the mxArray mx data area. The use for a 3D array is as follows:

use MatlabAPImx
use MatlabAPImat
:
real(8), pointer :: fp(:,:,:)
:
mx = matGetVariable(matfile, names(i))
if( mx == 0 ) error, so do something
fp => fpGetPrCopy(mx)
if( .not.associated(fp) ) error, so do something
fp(1,2,3) = 5.d0 ! <-- This will *not* change the data area of mx

Like above, this fp can be used downstream in your code just like it was a regular 3D Fortran array. When you are done with the target array of fp and the mxArray mx variable, deallocate fp and destroy mx as follows:

fpDeallocate(fp)
mxDestroyArray(mx)

Take special note ... when you point at the data area of an mxArray directly, you do *not* deallocate the pointer fp. But when you point at a *copy* of the data area of an mxArray, there is newly allocated memory involved that needs to be deallocated with the fpDeallocate function.

If you need help please don't hesitate to post more questions.

James Tursa
From: James Tursa on
"James Tursa" <aclassyguy_with_a_k_not_a_c(a)hotmail.com> wrote in message <hh7b1e$t60$1(a)fred.mathworks.com>...
>
> fp => fpGetPr(mx)

Typo, that should be

fp => fpGetPr3(mx)

> fp => fpGetPrCopy(mx)

and that should be

fp => fpGetPrCopy3(mx)

James Tursa
From: HIEU on
@James Tursa: I realized you have been doing a great job on Fortran Interface to MATLAB API. Thanks for your hard work. But I am just a beginner and I need more help on this if you don't mind.

So by copying your routines, I have a Fortran program named readinput.f90 like this:

#include "mex.h"
#include "fintrf.h"

PROGRAM readinput
use MatlabAPImx
use MatlabAPImat

character(len=NameLengthMaxMex), pointer :: names(:)
mwPointer mx, matfile
integer*4 i, k
real(8), pointer :: fp(:,:,:)

!\
! Open the mat file in read-only mode.
!/
k = mexPrint("... Opening mat file test.mat")
matfile = matOpen("test.mat","r")
if( matfile == 0 ) then
call mexErrMsgTxt("Unable to open mat file")
endif
!\
! Get a list of variable names in the mat file.
!/
k = mexPrint("... List of variable names in the file:")
names => fpMatGetNames(matfile)
if( associated(names) ) then
do i=1,size(names)
k = mexPrint(names(i))
enddo
else
call mexErrMsgTxt("Unable to read the variable names")
endif
!\
! Go get the variables and print out some info
!/
k = mexPrint("... Getting all the variables from the file")
do i=1,size(names)
mx = matGetVariable(matfile, names(i))
if( mx /= 0 ) then
k = mexPrint("Got the variable "//names(i))
!call mxDestroyArray(mx)
else
call mexErrMsgTxt("Unable to get variable "//names(i))
endif
enddo
!call fpDeallocate1CharacterMex(names)

mx = matGetVariable(matfile, wind)
if( mx /= 0 ) then
k = mexPrint("Got the variable "//names(i))
call mxDestroyArray(mx)
else
call mexErrMsgTxt("Unable to get variable "//names(i))
endif

fp => fpGetPr3(mx)
if( .not.associated(fp) ) then
call mxDestroyArray(mx)
call mexErrMsgTxt("Unable to associate pointer fp")
endif

write (*,*) 'Hello, world!' ! This is an inline comment
write (*,*) , fp

! After you are done with the data, destroy the mxArray variable mx:
! mxDestroyArray(mx)

k = mexPrint("... Done.")
k = matClose(matfile)

END PROGRAM readinput


Then I did the followings in Matlab:
1. > mex -setup % set Intel Fortran 11 + Visual Studio 2005 as compiler
2. > options = [matlabroot '\bin\win32\mexopts\intelf11msvs2005opts.bat']
% intelf11msvs2005opts.bat is from the FEX
http://www.mathworks.com/matlabcentral/fileexchange/22290-windows-mex-setup-with-ifort-11-0
3. > mex('-f',options,'readinput.f90')

All I get is a bunch of: "sal.h(502): #error: macro recursion: __pre"
So could you please take a look at my code and point out what I am missing or any error I made? Also, what do I need to do with linking (and compiling)?
many thanks,
Hieu
 |  Next  |  Last
Pages: 1 2 3 4 5
Prev: plotregion
Next: how to send keyboard event