MEX MATLAB / FORTRAN:整数作为一个非常高的数字传递

时间:2018-08-04 15:36:13

标签: matlab fortran integer mex

我正在为Matlab / Fortran界面编写一个简单的MEX文件。该代码正在编译中,但是整数n(例如5)作为一个巨大的数字(O(14))通过。当n为整数* 4时,它将作为0传递。

用户以[z,w] = smmat(c,e,eps,n)运行已编译的mex文件,其中 c 是大小为20xnl的复杂矩阵, e < / strong>是大小为8xnl的实数矩阵, eps 是大小为5xnl的实数矩阵, n 以整数标量。 z 是输出复数矩阵, w 应该是输出实数矩阵。

有人可以提供他们的专业知识吗?谢谢:)这是代码:

#include "fintrf.h"      
C     Gateway routine
      subroutine mexFunction(nlhs, plhs, nrhs, prhs)

C     Declarations
      implicit none

C mexFunction arguments: plhs - left (output) pointers of unknown (*) size
C                        prhs - right (input) pointers of unknown (*) size
C                        nlhs - number (integer) of left (output) arguments
C                        nrhs - number (integer) of right (input) arguments
      mwPointer plhs(*), prhs(*)
      integer nlhs, nrhs

C     Function declarations:
      mwPointer mxGetPr, mxGetPi  
      mwPointer mxCreateDoubleMatrix
      mwPointer mxGetM, mxGetN
      integer mxIsComplex, mexEvalString

C     Array information:
      mwPointer mc, nc, me, ne, mep, nep, mn, nn, nz, nw, elc, ele, elep

      integer*8 n
      real*8 e(80), eps(50), w(5000000)
      complex*16 c(200), z(5000000)

C-----------------------------------------------------------------------
C     Check for proper number of arguments. 
      if (nrhs .ne. 4) then
         call mexErrMsgIdAndTxt ('MATLAB:smmat:nInput',
     +                           'Four inputs required.')
      elseif (nlhs .gt. 2) then
         call mexErrMsgIdAndTxt ('MATLAB:convec:nOutput',
     +                           'Too many output arguments.')
      endif

C     Validate inputs
      mc = mxGetM(prhs(1))
      nc = mxGetN(prhs(1))
      me = mxGetM(prhs(2))
      ne = mxGetN(prhs(2))
      mep = mxGetM(prhs(3))
      nep = mxGetN(prhs(3))
      mn = mxGetM(prhs(4))
      nn = mxGetN(prhs(4))

C     Size of inputs
      elc = mc*nc
      ele = me*ne
      elep = mep*nep

C     Check number of lines of cij, eij, epsij
      if(mc .ne. 20 .or. me .ne. 8 .or. mep .ne. 5) then
         call mexErrMsgIdAndTxt ('Matlab:smmat:NotEnoConst',
     +            'Inputs must have correct number of constants.')
C     Check that inputs are scalar.
      elseif(mn .ne. 1 .or. nn .ne. 1) then
         call mexErrMsgIdAndTxt ('MATLAB:smmat:NonScalar',
     +                           'Inputs must be a scalar.')
C     Check size of the inputs.
      elseif(elc .gt. 200 .or. ele .gt. 80 .or. elep .gt. 50) then
         call mexErrMsgIdAndTxt ('MATLAB:smmat:nLayer',
     +                 'Maximum number of layers is 10.')
C     Check if cij is complex.
      elseif(mxIsComplex(prhs(1)) .ne. 1) then
         call mexErrMsgIdAndTxt ('MATLAB:smmat:NonComplex',
     +                           'Cij must be complex.')
C     Check if number of layers is correct for every constant.
      elseif(nc .ne. ne .or. nc .ne. nep .or. ne .ne. nep) then
         call mexErrMsgIdAndTxt ('MATLAB:smmat:nLayer',
     +           'Number of layers of constants must be equal.')      
      endif

C     Create the output array.
      nz = mc*me
      nw = mc*mep
      plhs(1) = mxCreateDoubleMatrix(mc, me, 1)
      plhs(2) = mxCreateDoubleMatrix(mc, mep, 0)

C     Load the data into Fortran arrays(native COMPLEX data).
      call mxCopyPtrToComplex16(mxGetPr(prhs(1)),
     +                          mxGetPi(prhs(1)),c,elc)
      call mxCopyPtrToReal8(mxGetPr(prhs(2)),e,ele)
      call mxCopyPtrToReal8(mxGetPr(prhs(3)),eps,elep)
      call mxCopyPtrToInteger4(mxGetPr(prhs(4)),n,1)

C     Call the computational subroutine.
      call smmat(c,e,eps,n,z,w,mc,me,mep,nc)

C     Load the output into a MATLAB array.
      call mxCopyComplex16ToPtr(z,mxGetPr(plhs(1)),
     +                          mxGetPi(plhs(1)),nz)
      call mxCopyReal8ToPtr(w,mxGetPr(plhs(2)),nw)

      return
      end

C-----------------------------------------------------------------------
C     Computational subroutine
      subroutine smmat(c,e,eps,n,z,w,mc,me,mep)

      implicit none

      integer*8 n
      real*8 e(8,*), eps(5,*), w(mc,mep)
      complex*16 c(20,*), z(mc,me)
      mwSize mc, nc, me, mep, i, j

C     Determine size of stiff and mass matrices
C     Initialize the output arrays
      w = 0.0_8

      do 20 i=1,mc
         do 10 j=1,me
             z(i,j) = (0.0,0.0)
 10      continue
 20   continue

      do 40 i=1,mc
         do 30 j=1,me
            z(i,j) = z(i,j) + e(j,1) * c(i,1)
 30      continue
 40   continue

      do 60 i=1,mc
          do 50 j=1,mep
              w(i,j) = w(i,j) + real(n)
 50       continue
 60   continue
      return
      end
C-----------------------------------------------------------------------

1 个答案:

答案 0 :(得分:1)

键入时

n=5;
smmat(c,e,eps,n)

在MATLAB中,n是双精度型,即使它具有整数值。在您的MEX文件中,您需要将其阅读为双份。您不能将mxArray数据解释为任何方便的类型。在从数组中读取数据之前,请始终使用诸如mxIsDouble之类的函数来验证数组的类型。

如果期望整数值,则可能仍应将其读取为double,然后转换为整数。