Thread Subject: using matlab engine in fortran subroutine

Subject: using matlab engine in fortran subroutine

From: Yi

Date: 17 Mar, 2010 17:01:21

Message: 1 of 6

Hi:

I am trying to use fortran to call matlab software by using fortran mex file and matlab engine. I came across some problems:

I wrote a main program and a subroutine in fortran. and try to use all engine functions in the subroutine

when I put the main program and the subroutine in different files, I use:
mex ('-f', [matlabroot '\bin\win32\mexopts\intelf91msvs2005engmatopts.bat'],'interpo.f','sub.f')
 to compile these two files. it doesn't work. the error information is:

sub.f(7) : Error: Syntax error, found ',' when expecting one of: => = . ( : %
       mwpointer engOpen, engGetVariable, mxCreateDoubleMatrix
------------------------^
sub.f(8) : Error: Syntax error, found END-OF-STATEMENT when expecting one of: => = . ( : %
       mwpointer mxGetPr
------------------------^
sub.f(9) : Error: Syntax error, found ',' when expecting one of: => = . ( : %
       mwpointer ep, mtdataz, mtdatapoc, mtrealz, mtrealpoc
-------------------^
sub.f(23) : Error: This name does not have a type, and must have an explicit type. [EP]
      ep = engOpen('matlab ')
------^
sub.f(23) : Error: This name does not have a type, and must have an explicit type. [ENGOPEN]
      ep = engOpen('matlab ')
-----------^
sub.f(34) : Error: This name does not have a type, and must have an explicit type. [MXGETPR]
      call mxCopyReal8ToPtr(dataz, mxGetPr(mtdataz),7)

However, when I put the main program and the subroutine in one file and compile it, it works!!
mex ('-f', [matlabroot '\bin\win32\mexopts\intelf91msvs2005engmatopts.bat'],'interpo.f')

I just don't know why it doesn't work when I put them in separate files .Thank you so much!!

Here is my code:

      program interpo
      implicit none
      real*8 realpoc(402)
      
      call execute(realpoc)
      write(*,*)realpoc
      stop
      end
      
      subroutine execute(realpoc)
      implicit none
      integer pass
      double precision datapoc(7),dataz(7),realz(402),realpoc(402)
      integer engPutVariable, engEvalString, engClose
      integer temp, i, status
       mwpointer engOpen, engGetVariable, mxCreateDoubleMatrix
       mwpointer mxGetPr
       mwpointer ep, mtdataz, mtdatapoc, mtrealz, mtrealpoc

C initial value for z and the poc data
      data dataz / 0, 350, 355, 365, 390, 395, 400 /
      data datapoc / 0.00001, 2, 5, 10, 13, 17, 63 /
      realz(1)=0
      realz(2)=0.5
      do i=3,401
          realz(i)=realz(i-1)+1
      enddo
      realz(402)=400
C
      ep = engOpen('matlab ')
      
      if (ep .eq. 0) then
         write(6,*) 'Can''t start Matlab engine'
         stop
      endif
      
      mtdataz = mxCreateDoubleMatrix(1,7,0)
      mtdatapoc = mxCreateDoubleMatrix(1,7,0)
      mtrealz = mxCreateDoubleMatrix(1,402,0)
      
      call mxCopyReal8ToPtr(dataz, mxGetPr(mtdataz),7)
      call mxCopyReal8toPtr(datapoc,mxGetPr(mtdatapoc),7)
      call mxCopyReal8toPtr(realz,mxGetPr(mtrealz),402)
      
      status = engPutVariable(ep, 'mtdataz', mtdataz)
      if (status .ne. 0) then
         write(6,*) 'engPutVariable failed'
         stop
      endif
      
      status = engPutVariable(ep, 'mtdatapoc', mtdatapoc)
      if (status .ne. 0) then
         write(6,*) 'engPutVariable failed'
         stop
      endif
      
      status = engPutVariable(ep, 'mtrealz', mtrealz)
      if (status .ne. 0) then
         write(6,*) 'engPutVariable failed'
         stop
      endif
      
      if (engEvalString(ep, 'mtrealpoc=interp1(mtdataz,mtdatapoc,mtrealz
     & ,''cubic'');') .ne. 0) then
         write(6, *) 'engEvalString failed'
         stop
      endif
      
      if (engEvalString(ep, 'plot(mtrealpoc,mtrealz);') .ne. 0) then
         write(6, *) 'engEvalString failed'
         stop
      endif
      
      print *, 'Type 0 <return> to Exit'
      print *, 'Type 1 <return> to continue'
      
      read(*,*) temp
      
      if (temp .eq. 0) then
         print *,'EXIT!'
         status = engClose(ep)
         
         if (status .ne. 0) then
            write(6, *) 'engClose failed'
         end if
         
         stop
      endif
      
      mtrealpoc = engGetVariable(ep, 'mtrealpoc')
      call mxCopyPtrToReal8(mxGetPr(mtrealpoc), realpoc, 402)
     
      
      call mxDestroyArray(mtrealz)
      call mxDestroyArray(mtrealpoc)
      call mxDestroyArray(mtdataz)
      call mxDestroyArray(mtdatapoc)
      
      status = engClose(ep)
      
      if (status .ne. 0) then
         write(6, *) 'engClose failed'
         stop
      endif
      return
      end subroutine

Subject: using matlab engine in fortran subroutine

From: James Tursa

Date: 17 Mar, 2010 18:58:08

Message: 2 of 6

"Yi " <njumeiyi@gmail.com> wrote in message <hnr1t1$crj$1@fred.mathworks.com>...
>
> I am trying to use fortran to call matlab software by using fortran mex file and matlab engine. I came across some problems:
>
> I wrote a main program and a subroutine in fortran. and try to use all engine functions in the subroutine
>
> when I put the main program and the subroutine in different files, I use:
> mex ('-f', [matlabroot '\bin\win32\mexopts\intelf91msvs2005engmatopts.bat'],'interpo.f','sub.f')
> to compile these two files. it doesn't work.

You need to have the following line at the top of each source file:

#include "fintrf.h"

That header file has all of the mwpointer etc. macros in it.

James Tursa

Subject: using matlab engine in fortran subroutine

From: Yi

Date: 17 Mar, 2010 20:45:22

Message: 3 of 6

Thank you so much James.

I tried add #include "fintrf.h" on the top of each my source file and compile it using:
mex ('-f', [matlabroot '\bin\win32\mexopts\intelf91msvs2005engmatopts.bat'],'interpo.f','sub.f')
it gives the following error information:
sub.f(1) : Error: Syntax error, found POUND_BASE '' when expecting one of: <LABEL> <END-OF-STATEMENT> ; BLOCK BLOCKDATA PROGRAM TYPE COMPLEX BYTE CHARACTER ...
      #include "fintrf.h"
------^
sub.f(1) : Severe: Could not recover from previous syntax error
      #include "fintrf.h"
------^
compilation aborted for sub.f (code 1)
C:\PROGRA~1\MATLAB\R2009A\BIN\MEX.PL: Error: Compile of 'sub.f' failed.

My question is: I didn't even use (#include "fintrf.h") when I put the two parts(main program and subroutine) in one file, it still works, gave the results I expected.

It doesn't work when I put the main program and subroutine in different files. (I compile command I use is <mex ('-f', [matlabroot '\bin\win32\mexopts\intelf91msvs2005engmatopts.bat'],'interpo.f','sub.f'))>

  
"James Tursa" <aclassyguy_with_a_k_not_a_c@hotmail.com> wrote in message <hnr8o0$chu$1@fred.mathworks.com>...
> "Yi " <njumeiyi@gmail.com> wrote in message <hnr1t1$crj$1@fred.mathworks.com>...
> >
> > I am trying to use fortran to call matlab software by using fortran mex file and matlab engine. I came across some problems:
> >
> > I wrote a main program and a subroutine in fortran. and try to use all engine functions in the subroutine
> >
> > when I put the main program and the subroutine in different files, I use:
> > mex ('-f', [matlabroot '\bin\win32\mexopts\intelf91msvs2005engmatopts.bat'],'interpo.f','sub.f')
> > to compile these two files. it doesn't work.
>
> You need to have the following line at the top of each source file:
>
> #include "fintrf.h"
>
> That header file has all of the mwpointer etc. macros in it.
>
> James Tursa

Subject: using matlab engine in fortran subroutine

From: James Tursa

Date: 18 Mar, 2010 04:55:05

Message: 4 of 6

"Yi " <njumeiyi@gmail.com> wrote in message <hnrf12$61o$1@fred.mathworks.com>...
> Thank you so much James.
>
> I tried add #include "fintrf.h" on the top of each my source file and compile it using:
> mex ('-f', [matlabroot '\bin\win32\mexopts\intelf91msvs2005engmatopts.bat'],'interpo.f','sub.f')
> it gives the following error information:
> sub.f(1) : Error: Syntax error, found POUND_BASE '' when expecting one of: <LABEL> <END-OF-STATEMENT> ; BLOCK BLOCKDATA PROGRAM TYPE COMPLEX BYTE CHARACTER ...
> #include "fintrf.h"
> ------^
> sub.f(1) : Severe: Could not recover from previous syntax error
> #include "fintrf.h"
> ------^
> compilation aborted for sub.f (code 1)
> C:\PROGRA~1\MATLAB\R2009A\BIN\MEX.PL: Error: Compile of 'sub.f' failed.

Put the #include statement starting in column 1.

> My question is: I didn't even use (#include "fintrf.h") when I put the two parts(main program and subroutine) in one file, it still works, gave the results I expected.

I don't know how this can possibly work. What did the compiler do when it encountered the token mwpointer? This is a macro that is part of the fintrf.h header ... how did the compiler know what to do with it? Are you sure you didn't already have this in the combined code?

James Tursa

Subject: using matlab engine in fortran subroutine

From: Yi

Date: 18 Mar, 2010 06:34:08

Message: 5 of 6

Hi James:

 I found the problem, I used the fortran77 format. each line start at column 7, I thought #include "fintrf.h" should also start at column 7, that's the reason why it doesn't work, when I make #include "fintrf.h" start at the first column, it works...

I do have #include "fintrf.h" in the first file starting at the first column of the code. i thought it' s comments..but it's really something missing from the second file, when I added this to the second file, it works!

Thanks!

Is it always the same case in fortran 77 that #include "*.h" start at the first column and the rest of the code start from the 7th column...?

"James Tursa" <aclassyguy_with_a_k_not_a_c@hotmail.com> wrote in message <hnsbn9$q5f$1@fred.mathworks.com>...
> "Yi " <njumeiyi@gmail.com> wrote in message <hnrf12$61o$1@fred.mathworks.com>...
> > Thank you so much James.
> >
> > I tried add #include "fintrf.h" on the top of each my source file and compile it using:
> > mex ('-f', [matlabroot '\bin\win32\mexopts\intelf91msvs2005engmatopts.bat'],'interpo.f','sub.f')
> > it gives the following error information:
> > sub.f(1) : Error: Syntax error, found POUND_BASE '' when expecting one of: <LABEL> <END-OF-STATEMENT> ; BLOCK BLOCKDATA PROGRAM TYPE COMPLEX BYTE CHARACTER ...
> > #include "fintrf.h"
> > ------^
> > sub.f(1) : Severe: Could not recover from previous syntax error
> > #include "fintrf.h"
> > ------^
> > compilation aborted for sub.f (code 1)
> > C:\PROGRA~1\MATLAB\R2009A\BIN\MEX.PL: Error: Compile of 'sub.f' failed.
>
> Put the #include statement starting in column 1.
>
> > My question is: I didn't even use (#include "fintrf.h") when I put the two parts(main program and subroutine) in one file, it still works, gave the results I expected.
>
> I don't know how this can possibly work. What did the compiler do when it encountered the token mwpointer? This is a macro that is part of the fintrf.h header ... how did the compiler know what to do with it? Are you sure you didn't already have this in the combined code?
>
> James Tursa

Subject: using matlab engine in fortran subroutine

From: James Tursa

Date: 18 Mar, 2010 07:25:07

Message: 6 of 6

"Yi " <njumeiyi@gmail.com> wrote in message <hnshh0$p9s$1@fred.mathworks.com>...
> Hi James:
>
> I found the problem, I used the fortran77 format. each line start at column 7, I thought #include "fintrf.h" should also start at column 7, that's the reason why it doesn't work, when I make #include "fintrf.h" start at the first column, it works...
>
> I do have #include "fintrf.h" in the first file starting at the first column of the code. i thought it' s comments..but it's really something missing from the second file, when I added this to the second file, it works!
>
> Thanks!
>
> Is it always the same case in fortran 77 that #include "*.h" start at the first column and the rest of the code start from the 7th column...?

The #include stuff is not Fortran at all. It is part of the pre-processor that most Fortran compilers include these days for the convenience of the user, but there is no pre-processor in the Fortran language standard (Unlike C and C++ which do have a pre-processor as part of the language). As such, it is up to the Fortran compiler vendor as to how to implement it and what capabilities to include. Apparently Intel Fortran requires the # to be in column 1. The pre-processor runs before the compiler itself even looks at the source code. Also, Fortran is case insensitive, but the pre-processor is case *sensitive*, so be careful.

James Tursa

Tags for this Thread

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.

rssFeed for this Thread

Contact us at files@mathworks.com