MATLAB,mex文件,Fortran,警告和错误 [英] MATLAB, mex files, Fortran, warnings and errors

查看:208
本文介绍了MATLAB,mex文件,Fortran,警告和错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不太清楚自己遇到的问题,并且我尝试了在其他论坛帖子中看到的建议.我正在尝试根据老板的要求编写一个(fortran)mex文件.但是,将矩阵传递给我的计算例程时,我收到警告.如果我忽略了警告,我的MATLAB将关闭.所以现在我正在尝试一个更简单的程序,一个内部产品.但是,我仍然收到警告:在(1)处出现了一个过程",其中(1)在x下方的"call innerProd(x,y,c)"处.我不确定这意味着什么...我已经包含了我的代码.

I'm not quite seeing the issue I'm having, and I've tried suggestions I've seen in other forum posts. I am trying to write a (fortran) mex file, per request of my boss. However, I was getting warnings when passing a matrix to my computational routine. If I ignored the warning, my MATLAB shut down. So now I'm trying a simpler program, an inner product. However, I am still getting the warning: "Expected a procedure at (1)" where (1) is at 'call innerProd(x,y,c)' underneath the x. I'm not sure what that means... I've included my code.

#include "fintrf.h"
C======================================================================
#if 0      
C
C     innerProd.F
C     .F file needs to be preprocessed to generate .for equivalent
C     
#endif 
C
C     innerProd.F
C     calculates the inner product

C     This is a MEX file for MATLAB.
C     Copyright 1984-2011 The MathWorks, Inc.
C     $Revision: 1.12.2.9 $

C======================================================================
C     Gateway routine      
      subroutine mexFunction(nlhs, plhs, nrhs, prhs)

C     Declarations
     implicit none

C     mexFunction arguments:
      mwPointer:: plhs(*), prhs(*)
      integer:: nlhs, nrhs

C     Function declarations:
      mwPointer:: mxCreateDoubleMatrix, mxGetPr,mxGetM, mxGetData
      integer:: mxIsNumeric

C     Pointers to input/output mxArrays:   
      mwPointer:: x_ptr, y_ptr, c_ptr 

C     Array information:
     mwSize:: m

C     Arguments for computational routine:      
      real*8::  x,y,c

C----------------------------------------------------------------------
C     Check for proper number of arguments. 
      if (nrhs .ne. 2) then
         call mexErrMsgTxt('Error.')
      elseif (nlhs .ne. 1) then
         call mexErrMsgTxt('One output required.')
      endif

C     Check to see if inputs are numeric.
      if (mxIsNumeric(prhs(1)) .ne. 1 ) then
         call mexErrMsgTxt('Input # 1 is not a numeric array.')
      elseif (mxIsNumeric(prhs(2)) .ne. 1) then
         call mexErrMsgTxt('Input #2 is not a numeric array.')
      endif

C     Find dimensions of mxArrays
      m=mxGetM(prhs(1))

C     create Fortran arrays from the input arguments      
      x_ptr=mxGetData(prhs(1))
      call mxCopyPtrToReal8(x_ptr,x,m)
      y_ptr= mxGetData(prhs(2))   
      call mxCopyPtrToReal8(y_ptr,y,m)

C     create matrix for the return argument
     plhs(1) =mxCreateDoubleMatrix(1,1,0)      
     c_ptr= mxGetPr(plhs(1))

C     Call the computational subroutine.
     call innerProd(x,y,c)

C     Load the output into a MATLAB array.
     call mxCopyReal8ToPtr(c, c_ptr, 1)

     return
     end subroutine mexFunction

C----------------------------------------------------------------------
C     Computational routine
      subroutine innerProd(x,y,c)
      implicit none

  real*8:: x,y,temp,c
  integer:: i,m

  do i=1,m
  temp=temp+x(i)*y(i)
  end do

  c = temp
  return
  end subroutine innerProd

我是第一次学习此内容,我将不胜感激任何建议.即使在哪里寻找解决方案.我已经在线查看了MATLAB mex Fortran辅助工具.那里没有任何帮助.我无法运行该函数,因此无法使用print语句,这是调试的一种好方法.我认为mex具有打印功能,我将尽力使其发挥作用.

I'm just learning this for the first time, and I would appreciate any suggestions. Even if it is where to look for solutions. I've looked through MATLAB mex Fortran aids online. There isn't any help there. I can't get the function to run, so I can't use print statements which is a good way to debug. I think mex has a print function, I will try to get that to work.

谢谢!

推荐答案

主要问题是您还没有在任何地方将innerProd的参数声明为数组.这适用于子例程mexFunction中的 actual 自变量xy以及innerProd自身中的 dummy 自变量xy.

The main problem is that you haven't anywhere declared the arguments of innerProd as arrays. That holds for the actual arguments x and y in the subroutine mexFunction and the dummy arguments x and y in innerProd itself.

因此,在innerProd中,表达式x(i)并不引用real*8数组x的第i个元素,而是函数real*8结果> x,参数为i.由于您传递的x不是函数(过程),因此是错误的.

So, in innerProd the expression x(i) isn't referencing the i-th element of the real*8 array x, but the real*8 result of the function x with argument i. As the x you've passed isn't a function (procedure), this is an error.

有多种方法可以解决此问题,但是所有方法都涉及将虚拟参数声明为数组.这又提出了另一点.

There are ways to solve this, but all involve declaring the dummy arguments as arrays. Which brings up another point.

您在innerProd

integer:: i,m

do i=1,m
  temp=temp+x(i)*y(i)
end do

其中未定义m.至关重要的是,您期望编译器从mexfunction知道m是数组xy的大小:这是不正确的. minnerProd本地的变量.相反,您可能希望将其作为参数传递给子例程,并使用该变量来确定数组的大小:

where m is not defined. Crucially, from mexfunction you're expecting the compiler to know that m is the size of the arrays x and y: this isn't true. m is a variable local to innerProd. Instead you may want to pass it as an argument to the subroutine and use that to dimension the arrays:

subroutine innerProd(x,y,c,m)
  implicit none

  integer :: m
  real*8:: x(m),y(m),temp,c
  ...
end subroutine

[您当然可以使用假定形状数组(和SIZE内在函数,但这是一个额外的复杂性,需要进行更大的更改.)您还需要考虑如何在mexfunction中适当地声明数组,请注意,对mxCopyPtrToReal8的调用也需要一个数组参数.

[You could, of course, use assumed-shape arrays (and the SIZE intrinsic), but that's an additional complication requiring more substantial changes.] You also need to think about how to declare arrays appropriately in mexfunction, noting that the call to mxCopyPtrToReal8 also requires an array argument.

这篇关于MATLAB,mex文件,Fortran,警告和错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆