Thread Subject: Fortran mex file common blocks

Subject: Fortran mex file common blocks

From: Scott Tyler

Date: 8 Feb, 2010 23:46:02

Message: 1 of 7

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

Subject: Fortran mex file common blocks

From: James Tursa

Date: 9 Feb, 2010 02:48:04

Message: 2 of 7

"Scott Tyler" <styler@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

Subject: Fortran mex file common blocks

From: Scott Tyler

Date: 9 Feb, 2010 03:05:23

Message: 3 of 7

"James Tursa" <aclassyguy_with_a_k_not_a_c@hotmail.com> wrote in message <hkqid4$977$1@fred.mathworks.com>...
> "Scott Tyler" <styler@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


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

Subject: Fortran mex file common blocks

From: James Tursa

Date: 9 Feb, 2010 06:45:23

Message: 4 of 7

"Scott Tyler" <styler@live.com> wrote in message <hkqjdj$b53$1@fred.mathworks.com>...
> "James Tursa" <aclassyguy_with_a_k_not_a_c@hotmail.com> wrote in message <hkqid4$977$1@fred.mathworks.com>...
> > "Scott Tyler" <styler@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
>
>
> 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

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

Subject: Fortran mex file common blocks

From: benbarrowes

Date: 9 Feb, 2010 11:58:19

Message: 5 of 7

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

Subject: Fortran mex file common blocks

From: Scott Tyler

Date: 13 Feb, 2010 15:47:02

Message: 6 of 7

"James Tursa" <aclassyguy_with_a_k_not_a_c@hotmail.com> wrote in message <hkr0a3$4fn$1@fred.mathworks.com>...
> "Scott Tyler" <styler@live.com> wrote in message <hkqjdj$b53$1@fred.mathworks.com>...
> > "James Tursa" <aclassyguy_with_a_k_not_a_c@hotmail.com> wrote in message <hkqid4$977$1@fred.mathworks.com>...
> > > "Scott Tyler" <styler@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
> >
> >
> > 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
>
> 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


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

Subject: Fortran mex file common blocks

From: Scott Tyler

Date: 13 Feb, 2010 16:04:07

Message: 7 of 7

benbarrowes <benbarrowes@gmail.com> wrote in message <adb304f1-740d-4e38-a88e-ef152ba4feb1@3g2000yqn.googlegroups.com>...
> 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

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

Tags for this Thread

Everyone's Tags:

Add a New Tag:

Separated by commas
Ex.: root locus, bode

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Tag Activity for This Thread
Tag Applied By Date/Time
mex file Scott Tyler 8 Feb, 2010 18:49:05
fortran Scott Tyler 8 Feb, 2010 18:49:05
common block Scott Tyler 8 Feb, 2010 18:49:05
rssFeed for this Thread

Contact us at files@mathworks.com