Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Fortran mex file common blocks

26 views
Skip to first unread message

Scott Tyler

unread,
Feb 8, 2010, 6:46:02 PM2/8/10
to
I have several Fortran subroutines, each with multiple named common blocks. I would like to call these subroutines from Matlab instead of from a main fortran routine. However, I am not sure how to generate the common block data, required by the fortran subroutines, from Matlab. Any help will be greatly appreciated.
Scott

James Tursa

unread,
Feb 8, 2010, 9:48:04 PM2/8/10
to
"Scott Tyler" <sty...@live.com> wrote in message <hkq7nq$m3b$1...@fred.mathworks.com>...

> I have several Fortran subroutines, each with multiple named common blocks. I would like to call these subroutines from Matlab instead of from a main fortran routine. However, I am not sure how to generate the common block data, required by the fortran subroutines, from Matlab. Any help will be greatly appreciated.
> Scott

Not sure what you are asking. Are you simply asking how to populate the variables in a COMMON block with data generated on the MATLAB side? e.g., are you trying to write a mex function that passes in MATLAB variables and then calls a Fortran subroutine that takes part or all of its input from COMMON blocks? If so, I can help with that.

James Tursa

Scott Tyler

unread,
Feb 8, 2010, 10:05:23 PM2/8/10
to
"James Tursa" <aclassyguy_wi...@hotmail.com> wrote in message <hkqid4$977$1...@fred.mathworks.com>...


Yes, that is correct. I am trying to call a fortran routine from Matlab that requires information from a COMMON block. I need to create and populate that block from Matlab.

Scott

James Tursa

unread,
Feb 9, 2010, 1:45:23 AM2/9/10
to
"Scott Tyler" <sty...@live.com> wrote in message <hkqjdj$b53$1...@fred.mathworks.com>...

I will offer two methods. Both of them involve copying, which can't be avoided if you want to retain the COMMON block interface. The first uses only stock MATLAB API routines. The second uses my Fortran 95 Interface routines which can be found here:

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

Both take a 5-element double vector, multiply it by 2, and return the result.

James Tursa

--------------------------------------------------------------------------------------------

Call the 1st file e.g. common1.f and compile it with

mex common1.f

Run it with

common1([1 2 3 4 5])

--------------------------------------------------------------------------------------------

#include "fintrf.h"

#ifndef mwSize
#define mwSize integer*4
#endif

#ifndef mwPointer
#define mwPointer integer*4
#endif

!---------------------------------------------------------------------

subroutine mexFunction(nlhs, plhs, nrhs, prhs)
implicit none
!-ARG
mwPointer plhs(*), prhs(*)
integer*4 nlhs, nrhs
!-FUN
mwPointer, external :: mxGetPr
mwPointer, external :: mxCreateDoubleMatrix
integer*4, external :: mxIsDouble
mwSize, external :: mxGetNumberOfElements
mwSize, external :: mxGetM
mwSize, external :: mxGetN
!-COM
real(8) inarray(5), outarray(5)
common /stuff/ inarray, outarray
!-LOC
mwSize :: m, n
integer*4 :: mxREAL = 0
mwPointer pr
logical ok
!-----
ok = .false.
if( nrhs == 1 ) then
if( mxIsDouble(prhs(1)) == 1 ) then
if( mxGetNumberOfElements(prhs(1)) == 5 ) then
ok = .true.
endif
endif
endif
if( .not.ok ) then
call mexErrMsgTxt("Need one 5-element double input")
endif
if( nlhs > 1 ) then
call mexErrMsgTxt("Too many outputs")
endif
pr = mxGetPr(prhs(1))
m = mxGetM(prhs(1))
n = mxGetN(prhs(1))
call mxCopyPtrToReal8(pr, inarray, m*n)
call sub
plhs(1) = mxCreateDoubleMatrix(m, n, mxREAL)
pr = mxGetPr(plhs(1))
call mxCopyReal8ToPtr(outarray, pr, m*n)
end subroutine mexFunction
!---------------------------------------------------------------
subroutine sub
implicit none
!-COM
real(8) inarray(5), outarray(5)
common /stuff/ inarray, outarray
!-----
outarray = 2.d0 * inarray
end subroutine sub


--------------------------------------------------------------------------------------------

Call the 2nd file e.g. common2.f and compile it with

mex -c MatlabAPImex.f
mex -c MatlabAPImx.f
mex common2.f MatlabAPImex.obj MatlabAPImx.obj

Run it with

common2([1 2 3 4 5])

--------------------------------------------------------------------------------------------

#include "fintrf.h"

#ifndef mwSize
#define mwSize integer*4
#endif

#ifndef mwPointer
#define mwPointer integer*4
#endif

!---------------------------------------------------------------------

subroutine mexFunction(nlhs, plhs, nrhs, prhs)
use MatlabAPImex
use MatlabAPImx
implicit none
!-ARG
mwPointer plhs(*), prhs(*)
integer*4 nlhs, nrhs
!-COM
real(8) inarray(5), outarray(5)
common /stuff/ inarray, outarray
!-LOC
real(8), pointer :: fp(:)
!-----
if( nrhs /= 1 ) goto 900
if( nlhs > 1 ) then
call mexErrMsgTxt("Too many outputs")
endif
fp => fpGetPr1(prhs(1))
if( .not.associated(fp) ) goto 900
if( size(fp) /= 5 ) goto 900
inarray = fp
call sub
plhs(1) = mxArray(outarray, orient="row")
return
900 call mexErrMsgTxt("Need one 5-element double input")
end subroutine mexFunction
!---------------------------------------------------------------
subroutine sub
implicit none
!-COM
real(8) inarray(5), outarray(5)
common /stuff/ inarray, outarray
!-----
outarray = 2.d0 * inarray
end subroutine sub

benbarrowes

unread,
Feb 9, 2010, 6:58:19 AM2/9/10
to
On Feb 8, 10:05 pm, "Scott Tyler" <sty...@live.com> wrote:
> "James Tursa" <aclassyguy_with_a_k_not_...@hotmail.com> wrote in message <hkqid4$97...@fred.mathworks.com>...
> > "Scott Tyler" <sty...@live.com> wrote in message <hkq7nq$m3...@fred.mathworks.com>...

> > > I have several Fortran subroutines, each with multiple named common blocks. I would like to call these subroutines from Matlab instead of from a main fortran routine. However, I am not sure how to generate the common block data, required by the fortran subroutines, from Matlab. Any help will be greatly appreciated.
> > > Scott
>
> > Not sure what you are asking. Are you simply asking how to populate the variables in a COMMON block with data generated on the MATLAB side?  e.g., are you trying to write a mex function that passes in MATLAB variables and then calls a Fortran subroutine that takes part or all of its input from COMMON blocks? If so, I can help with that.
>
> > James Tursa
>
> Yes, that is correct. I am trying to call a fortran routine from Matlab that requires information from a COMMON block. I need to create and populate that block from Matlab.
>
> Scott

Scott,

I know this isn't what you originally asked, but you may consider
converting the fortran to matlab code. I wrote f2matlab to do this
kind of thing, and it can handle common blocks. It is at the file
exchange:
http://www.mathworks.com/matlabcentral/fileexchange/5260

Let me know if you run into problems,
Ben Barrowes

Scott Tyler

unread,
Feb 13, 2010, 10:47:02 AM2/13/10
to
"James Tursa" <aclassyguy_wi...@hotmail.com> wrote in message <hkr0a3$4fn$1...@fred.mathworks.com>...


James,
Thanks for the suggestion. This worked out well.
Scott

Scott Tyler

unread,
Feb 13, 2010, 11:04:07 AM2/13/10
to
benbarrowes <benba...@gmail.com> wrote in message <adb304f1-740d-4e38...@3g2000yqn.googlegroups.com>...

Ben,
Thanks for the suggestion. I will let you know of any problems.
Scott

0 new messages