How can I transfer the size of the array to mexFunction

1 view (last 30 days)
#include "fintrf.h"
SUBROUTINE mexFunction(nlhs, plhs, nrhs, prhs)
IMPLICIT NONE
mwPointer plhs(*), prhs(*)
integer nlhs, nrhs
mwPointer mxGetPr
mwPointer mxGetM
mwPointer mxCreateDoubleMatrix
mwPointer P1,P2,P3
REAL*8 R1,R2,R3
%R1 is integer number
%R2(R1,1) - size of R2
%R3(R1-2,11) - size of R3
P1 = mxGetPr(prhs(1))
P2 = mxGetPr(prhs(2))
CALL mxCopyPtrToREAL8(P1,R1,1)
CALL mxCopyPtrToREAL8(P2,R2,1)
plhs(1) = mxCreateDoubleMatrix(M-2,11,0)
P3 = mxGetPr(plhs(1))
CALL ProgramName(R1,R2,R3)
CALL mxCopyREAL8ToPtr(R3,P3,(M-2)*11)
return
end
This program has 2 input parameters: R1 and R2. Dimensions R2 = R2 (R1). Output parameter R3 has dimensions R3 (R1-2, 11). How can I implement this?
  4 Comments
James Tursa
James Tursa on 9 May 2019
Edited: James Tursa on 9 May 2019
So, you still haven't answered my request to see the full signature of the programname subroutine, and identify which are inputs and which are outputs.
Igor Arkhandeev
Igor Arkhandeev on 9 May 2019
Edited: Igor Arkhandeev on 9 May 2019
SUBROUTINE ProgramName(A,B,C)
integer B
Real*8 A(B), C(B-2,11)
!some operations, filling data in array C
end subroutine ProgramName

Sign in to comment.

Accepted Answer

James Tursa
James Tursa on 9 May 2019
Try this (caveat, untested). Don't pass in the row size of the matrix ... just pass in the matrix only. Let the code figure out the row size via mxGetM. I highly advise you add some argument checking into this as well. E.g., make sure you have exactly one full double 2D real input, and that nlhs <= 1.
#include "fintrf.h"
SUBROUTINE mexFunction(nlhs, plhs, nrhs, prhs)
IMPLICIT NONE
mwPointer plhs(*), prhs(*)
integer nlhs, nrhs
mwPointer mxGetPr
mwPointer mxGetM
mwPointer mxCreateDoubleMatrix
mwPointer P1, P3
integer M
mwSize Cm, Cn
integer*4 ComplexFlag
P1 = mxGetPr(prhs(1))
M = mxGetM(prhs(1))
if( M <= 2 ) then
call mexErrMsgTxt("Input size is too small")
endif
Cm = M - 2
Cn = 11
ComplexFlag = 0
plhs(1) = mxCreateDoubleMatrix(Cm,Cn,ComplexFlag)
P3 = mxGetPr(plhs(1))
CALL ProgramName( %val(P1), M, %val(P3) )
return
end
  17 Comments
James Tursa
James Tursa on 10 May 2019
So, I need to gently slap you on the wrist at this point. As you recall, I had put this in my original code for you:
if( M <= 2 ) then
call mexErrMsgTxt("Input size is too small")
endif
You chose not to implement this check, and it cost a lot of wasted time in tracking down the error. So ... I would strongly advise again to put in LOTS of argument checks in your mex routines in the future! :)

Sign in to comment.

More Answers (1)

Igor Arkhandeev
Igor Arkhandeev on 10 May 2019
Edited: Igor Arkhandeev on 11 May 2019
#include "fintrf.h"
SUBROUTINE mexFunction(nlhs, plhs, nrhs, prhs)
IMPLICIT NONE
mwPointer plhs(*), prhs(*)
integer nlhs, nrhs
mwPointer mxGetPr
mwPointer mxGetN
mwPointer mxCreateDoubleMatrix
mwPointer P11,P12,P13!P1,P2,P3,P4,P5,P6,P7,P8,P9,P11,P12,P13
mwSize Cm, Cn
mwSize Dm, Dn
REAL*8 R1,R2,R3,R4,R5,R6,R7,R8,R9,M,R12(3)
integer*4 ComplexFlag
real*8, external :: mxGetScalar
integer*4, external :: mexPrintf
integer*4 k
character*50 line
M = mxGetN(prhs(11))
Cm = M - 2
Cn = 11
Dm = 1
Dn = 3
ComplexFlag = 0
if( M <= 2 ) then
call mexErrMsgTxt("Input size is too small")
endif
R1 = mxGetScalar(prhs(1))
R2 = mxGetScalar(prhs(2))
R3 = mxGetScalar(prhs(3))
R4 = mxGetScalar(prhs(4))
R5 = mxGetScalar(prhs(5))
R6 = mxGetScalar(prhs(6))
R7 = mxGetScalar(prhs(7))
R8 = mxGetScalar(prhs(8))
R9 = mxGetScalar(prhs(9))
P11 = mxGetPr(prhs(11))
plhs(1) = mxCreateDoubleMatrix(Dm,Dn,ComplexFlag)
P12 = mxGetPr(plhs(1))
plhs(2) = mxCreateDoubleMatrix(Cm,Cn,ComplexFlag)
P13 = mxGetPr(plhs(2))
CALL Kramers(R1,R2,R3,R4,R5,R6,R7,R8,R9,M,%val(P11),R12,%val(P13))
CALL mxCopyREAL8ToPtr(R12,P12,Dn)
return
end

Categories

Find more on Matrices and Arrays in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!