2015-10-19 61 views
2

我正在寫這個F90程序來計算Fortran中的一個函數,它從.mat文件獲取輸入並將結果保存在另一個.mat文件中。在Fortran中導入.mat文件 - 分段錯誤錯誤

我跟着this的答案,以獲得代碼編譯和正確鏈接。這是我的makefile命令:

gfortran -g -fcheck=all binhkorn_mat.F90 -I/usr/local/MATLAB/R2015b/extern/include/ -L/usr/local/MATLAB/R2015b/bin/glnxa64 -cpp -o binhkorn_mat -lmat -lmx -Wl,-rpath /usr/local/MATLAB/R2015b/bin/glnxa64/ 

輸出文件顯然是正確編譯,但那麼一旦我運行程序如下SF出現(我工作的Linux操作系統Ubuntu 14.04 LTS):

Program received signal SIGSEGV: Segmentation fault - invalid memory reference. 

Backtrace for this error: 
#0 0x7FD650063F27 
#1 0x7FD6500644F4 
#2 0x7FD64FCBCD3F 
#3 0x7FD64FDD7AF6 
#4 0x400A3F in binhkorn_mat at binhkorn_mat.F90:17 (discriminator 2) 
./binhkorn_mat: Segmentation fault 

我無法弄清楚編譯器是否有錯誤,或者如果我在指針/函數定義上做了錯誤。下面的代碼(binhkorn_mat.F90):

#include "fintrf.h" 
PROGRAM binhkorn_mat 
IMPLICIT NONE 
mwPointer matOpen, matGetVariable, matPutVariable 
mwPointer mpin, mpX, mpout, mpcf 
INTEGER :: i,j 
REAL*8, DIMENSION(2) :: x 
REAL*8, DIMENSION(4) :: cf 

!input/output through .mat f 
mpin = matOpen('X.mat', 'u') 
mpX = matGetVariable(mpin, 'X') 
CALL mxCopyPtrToReal8(mpX, x, 2) 
CALL matClose(mpin) 

!fitness functions 
cf(1) = ((x(1)-2)**2 + (x(2)-1)**2 + 2) 
cf(2) = (9*x(1) + (x(2)-1)**2) 

!constraints 
cf(3) = x(1)*x(1) + x(2)*x(2) - 225 
cf(4) = x(1) - 3*x(2) + 10 

!output file created 
CALL mxCopyReal8ToPtr(cf, mpcf, 4) 
mpout = matOpen('cf.mat', 'w') 
mpcf = matPutVariable(mpout, 'cf', mpcf) 
CALL matClose(mpout) 

END PROGRAM 

的X.mat文件正確由外部MATLAB腳本創建幷包含一個名爲X變量,它是一個2元素行向量。

+0

哇。在Fortran 90中寫入的人不多... – GameOfThrows

+1

@GameOfThrows是的,Fortran 90來自上個世紀,今天我們使用Fortran 2008。 –

+0

您可以打印'matGetVariable(mpin,'X')'返回的值並檢查它是否爲零? – credondo

回答

1

我基本上誤解了如何使用許多函數。我作爲輸入提供給他們的指針不是正確的。我在這裏發佈工作解決方案:

#include "fintrf.h" 
PROGRAM binhkorn_mat 
IMPLICIT NONE 
mwPointer matOpen, matGetVariable!, matPutVariable 
mwPointer mxGetData, mxGetNumberOfElements, mxCreateNumericArray 
mwPointer mpin, mpX, mpout, mpcf 
mwSize ndim 
mwSize dims(2) 
INTEGER :: s 
INTEGER*4 mxClassIDFromClassName 
CHARACTER (LEN = 6) :: classname 
REAL*8, DIMENSION(2) :: x 
REAL*8, DIMENSION(4) :: cf 

!input/output through .mat f 
mpin = matOpen('X.mat', 'r') 
mpX = matGetVariable(mpin, 'X') 
CALL mxCopyPtrToReal8(mxGetData(mpX), x, mxGetNumberOfElements(mpX)) 
!CALL matClose(mpin) 

!fitness functions 
cf(1) = ((x(1)-2)**2 + (x(2)-1)**2 + 2) 
cf(2) = (9*x(1) + (x(2)-1)**2) 

!constraints 
cf(3) = x(1)*x(1) + x(2)*x(2) - 225 
cf(4) = x(1) - 3*x(2) + 10 

!output .mat file created and filled 
s = size(cf) 
ndim = 2 
classname = 'double' 
dims(1) = 1 
dims(2) = s 
mpcf = mxCreateNumericArray(ndim, dims, mxClassIDFromClassName(classname), 0) 
CALL mxCopyReal8ToPtr(cf, mxGetData(mpcf), mxGetNumberOfElements(mpcf)) 
mpout = matOpen('cf.mat', 'w') 
CALL matPutVariable(mpout, 'cf', mpcf) 
!CALL matClose(mpout) 

END PROGRAM