From: George on
"James Tursa" <aclassyguy_with_a_k_not_a_c(a)hotmail.com> wrote in message <hunb60$e0r$1(a)fred.mathworks.com>...
> "George " <guanjihou(a)gmail.com> wrote in message <hun8hl$qqv$1(a)fred.mathworks.com>...
> >
> > My understanding of your words is that in my Fortran main program I can use engCallMatlab to call a matlab routine, or matlab m file ...
>
> Yes.
>
> > ... while in this Matlab routine I can use the compiled mex-files to act as a bridge doing the communication work, right?
>
> The MATLAB engine can call mex routines, but I don't know what you mean by "bridge doing the communication work".
>
> > I have been confused about the difference between these Matlab engine and the Mex-files for quite a long time.
>
> Think of a mex routine as a subroutine that gets attached directly to MATLAB. So mex function calls etc happen through a direct interface to the routine ... only pointers to the variables are passed so it is very efficient. The prhs(*) pointers you get in the mexFunction argument list point directly at the MATLAB workspace variables. There is no extra copying involved, and you can access the contents of these workspace variables directly in your code. Likewise from within your mex routine you can make direct calls to MATLAB functions or m-files via the mexCallMATLAB routine ... no extra data copies are involved as you are only passing mxArray pointers to the routine.
>
> Think of the relationship between a program and a MATLAB engine as two completely separate programs running that have no direct communication with each other. Instead, they have to use a third party to talk to each other ... e.g., a COM interface. So to call an m-file from the program you have to first create an mxArray version of the variable you want to pass (maybe an extra copy), then pass that to the COM interface (via the engPutVariable routine), which causes another copy to be made on the MATLAB engine side. Then you can invoke the m-file via a engEvalString function call. Then to get the result back into your program you need to use engGetVariable which uses the COM interface and makes a copy of the MATLAB engine workspace output variable in your Fortran code. Then maybe there is another copy involved to get the data into a regular Fortran variable. That's a lot of extra work in

> the background to call the m-file, but it can be done and it can be quite useful to use built-in MATLAB functions or m-files this way in spite of the extra data movement.
>
> James Tursa

James,

Thanks very much. This really helps!!!
From: George on
> Think of a mex routine as a subroutine that gets attached directly to MATLAB. So mex function calls etc happen through a direct interface to the routine ... only pointers to the variables are passed so it is very efficient. The prhs(*) pointers you get in the mexFunction argument list point directly at the MATLAB workspace variables. There is no extra copying involved, and you can access the contents of these workspace variables directly in your code. Likewise from within your mex routine you can make direct calls to MATLAB functions or m-files via the mexCallMATLAB routine ... no extra data copies are involved as you are only passing mxArray pointers to the routine.
>
> Think of the relationship between a program and a MATLAB engine as two completely separate programs running that have no direct communication with each other. Instead, they have to use a third party to talk to each other ... e.g., a COM interface. So to call an m-file from the program you have to first create an mxArray version of the variable you want to pass (maybe an extra copy), then pass that to the COM interface (via the engPutVariable routine), which causes another copy to be made on the MATLAB engine side. Then you can invoke the m-file via a engEvalString function call. Then to get the result back into your program you need to use engGetVariable which uses the COM interface and makes a copy of the MATLAB engine workspace output variable in your Fortran code. Then maybe there is another copy involved to get the data into a regular Fortran variable. That's a lot of extra work in

> the background to call the m-file, but it can be done and it can be quite useful to use built-in MATLAB functions or m-files this way in spite of the extra data movement.
>
> James Tursa

James,

I have one confusing when using the engValString(). Please see the following simple code:

#include "fintrf.h"
program main
integer*4 engOpen
integer*4 ep
character(50) a1
integer*4 p1, result
C----------------------------------------------------------------------
C Other variable declarations here
integer engPutVariable, engEvalString, engClose, mxCreateString
integer temp, status
C
ep = engOpen('matlab ')
C
if (ep .eq. 0) then
write(6,*) 'Can''t start MATLAB engine'
stop
endif
C Plot the result
if (engEvalString(ep, 'x = -pi:0.01:pi;') .ne. 0) then
write(6,*) 'engEvalString failed'
stop
endif

if (engEvalString(ep, 'plot(x,sin(x)), grid on') .ne. 0) then
write(6,*) 'engEvalString failed'
stop
endif

p1= mxCreateString('Hi, this is a test')
if (engPutVariable(ep, 'a1',p1) .ne.0) then
write(6,*) 'engPutString initpsat failed'
stop
endif

result = engEvalString(ep, 'disp(a1)')

if(engEvalString(ep, 'disp(a1)') .ne.0) then
write(6,*) 'display failed'
stop
endif
status = engClose(ep)
C
if (status .ne. 0) then
write(6,*) 'engClose failed'
stop
endif
C
stop
end

The thing is that it works fine for the sin(x) and plot() call, while for the disp() call, I notice that in the command window, nothing display. I check the value of result, it is 0 which means that the execution is done. Then I type on that command window disp(a1), it just show what I want.

So My question is what was wrong in my code? Why the engEvalString(ep, 'disp(a1)') does't act as I want?

Thanks!
From: George on
"George " <guanjihou(a)gmail.com> wrote in message <huoo6k$kjo$1(a)fred.mathworks.com>...
> > Think of a mex routine as a subroutine that gets attached directly to MATLAB. So mex function calls etc happen through a direct interface to the routine ... only pointers to the variables are passed so it is very efficient. The prhs(*) pointers you get in the mexFunction argument list point directly at the MATLAB workspace variables. There is no extra copying involved, and you can access the contents of these workspace variables directly in your code. Likewise from within your mex routine you can make direct calls to MATLAB functions or m-files via the mexCallMATLAB routine ... no extra data copies are involved as you are only passing mxArray pointers to the routine.
> >
> > Think of the relationship between a program and a MATLAB engine as two completely separate programs running that have no direct communication with each other. Instead, they have to use a third party to talk to each other ... e.g., a COM interface. So to call an m-file from the program you have to first create an mxArray version of the variable you want to pass (maybe an extra copy), then pass that to the COM interface (via the engPutVariable routine), which causes another copy to be made on the MATLAB engine side. Then you can invoke the m-file via a engEvalString function call. Then to get the result back into your program you need to use engGetVariable which uses the COM interface and makes a copy of the MATLAB engine workspace output variable in your Fortran code. Then maybe there is another copy involved to get the data into a regular Fortran variable. That's a lot of extra work
in
>
> > the background to call the m-file, but it can be done and it can be quite useful to use built-in MATLAB functions or m-files this way in spite of the extra data movement.
> >
> > James Tursa
>
> James,
>
> I have one confusing when using the engValString(). Please see the following simple code:
>
> #include "fintrf.h"
> program main
> integer*4 engOpen
> integer*4 ep
> character(50) a1
> integer*4 p1, result
> C----------------------------------------------------------------------
> C Other variable declarations here
> integer engPutVariable, engEvalString, engClose, mxCreateString
> integer temp, status
> C
> ep = engOpen('matlab ')
> C
> if (ep .eq. 0) then
> write(6,*) 'Can''t start MATLAB engine'
> stop
> endif
> C Plot the result
> if (engEvalString(ep, 'x = -pi:0.01:pi;') .ne. 0) then
> write(6,*) 'engEvalString failed'
> stop
> endif
>
> if (engEvalString(ep, 'plot(x,sin(x)), grid on') .ne. 0) then
> write(6,*) 'engEvalString failed'
> stop
> endif
>
> p1= mxCreateString('Hi, this is a test')
> if (engPutVariable(ep, 'a1',p1) .ne.0) then
> write(6,*) 'engPutString initpsat failed'
> stop
> endif
>
> result = engEvalString(ep, 'disp(a1)')
>
> if(engEvalString(ep, 'disp(a1)') .ne.0) then
> write(6,*) 'display failed'
> stop
> endif
> status = engClose(ep)
> C
> if (status .ne. 0) then
> write(6,*) 'engClose failed'
> stop
> endif
> C
> stop
> end
>
> The thing is that it works fine for the sin(x) and plot() call, while for the disp() call, I notice that in the command window, nothing display. I check the value of result, it is 0 which means that the execution is done. Then I type on that command window disp(a1), it just show what I want.
>
> So My question is what was wrong in my code? Why the engEvalString(ep, 'disp(a1)') does't act as I want?
>
> Thanks!

Hi James,

This problem is solved now.

I have another question, which is a more general one. I am now writing a Fortran program, and I want to call a Matlab routine, which is a bunch of m files that perform certain computation functionality. After the Matlab routine finish the computation, there will be a lot of results sending back to Fortran, those results are stored in Matrix form. So my question is that what is the most efficient and convenient way to do this result sending back job? I know engGetVariable() can do this, but for so many results that need to be sent back, it would be a huge work.

Thanks!
From: Walter Roberson on
George wrote:

> I have another question, which is a more general one. I am now writing a
> Fortran program, and I want to call a Matlab routine, which is a bunch
> of m files that perform certain computation functionality. After the
> Matlab routine finish the computation, there will be a lot of results
> sending back to Fortran, those results are stored in Matrix form. So my
> question is that what is the most efficient and convenient way to do
> this result sending back job? I know engGetVariable() can do this, but
> for so many results that need to be sent back, it would be a huge work.

I have not worked in that area, so there might well be better ways, but:

How about if you executed "whos" on the engine in order to find the variable
names (and type information) and then looped through those using engGetVariable ?
From: George on
Walter Roberson <roberson(a)hushmail.com> wrote in message <hup37k$ogr$2(a)canopus.cc.umanitoba.ca>...
> George wrote:
>
> > I have another question, which is a more general one. I am now writing a
> > Fortran program, and I want to call a Matlab routine, which is a bunch
> > of m files that perform certain computation functionality. After the
> > Matlab routine finish the computation, there will be a lot of results
> > sending back to Fortran, those results are stored in Matrix form. So my
> > question is that what is the most efficient and convenient way to do
> > this result sending back job? I know engGetVariable() can do this, but
> > for so many results that need to be sent back, it would be a huge work.
>
> I have not worked in that area, so there might well be better ways, but:
>
> How about if you executed "whos" on the engine in order to find the variable
> names (and type information) and then looped through those using engGetVariable ?

Yes, this could be a method. I just want to know if there is a better way to do this.