## How can I transfer the size of the array to mexFunction

Igor Arkhandeev

### Igor Arkhandeev (view profile)

さんによって質問されました 2019 年 5 月 8 日

### Igor Arkhandeev (view profile)

さんによって 編集されました 2019 年 5 月 11 日
James Tursa

### James Tursa (view profile)

さんの 回答が採用されました
#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?

Igor Arkhandeev

### Igor Arkhandeev (view profile)

2019 年 5 月 9 日
Hello! Thank you for your answer! The goal of my mexFunction is the following: 2 input arguments are given to the input of the function: an array (M, 1) and a number whose value is M. The output parameter is an array (M-2, 11). The fact is that the number M is changing and there is definitely no possibility to set it. I also corrected the code, it is given as an example. Let the name of the program - programName
James Tursa

### James Tursa (view profile)

2019 年 5 月 9 日
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 (view profile)

2019 年 5 月 9 日
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

サインイン to comment.

## 2 件の回答

### James Tursa (view profile)

2019 年 5 月 9 日
採用された回答

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

Igor Arkhandeev

### Igor Arkhandeev (view profile)

2019 年 5 月 10 日
James, thank you very much! The error was as follows: I confused the columns and rows, so M = -1 in my code. Unfortunately, my knowledge of FORTRAN is not enough, but thanks to such a specialist as you, everything turned out! Thank you so much!
In a separate comment, I will give a final decision so that others can rely on it in the future.
James Tursa

### James Tursa (view profile)

2019 年 5 月 10 日
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! :)
Igor Arkhandeev

### Igor Arkhandeev (view profile)

2019 年 5 月 11 日
You're damn right!

サインイン to comment.

2019 年 5 月 10 日

### Igor Arkhandeev (view profile)

2019 年 5 月 11 日

#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

#### 0 件のコメント

サインイン to comment.

Translated by