matlab和fortran混合编程
matlab2016b+vs2010+ivf2013+f90
其实默认是f77语法,但通过配置可以改变为自由格式。
默认只能f77代码,怎样修改:
找到:mex_FORTRAN_win64,删掉fixed就可以用f90了。
大体过程:
1.在matlab中配置fortran编译环境: mex -setup FORTRAN
2.写好源代码,自定义子函数仍可以像往常一样调用别的子函数
3.将matlab当前路径调整到当前源代码文档所在路径
4.在matlab命令行输入编译命令:mex csuherror.f90
5.像使用matlab内置函数一样使用此函数,error=csuherror(X),其中X为csuh的9个参数(包括C),输出的为计算误差
6.若需要调试,需要这样编译:mex -g csuherror.f90 ,之后通过vs附加matlab到进程,并打开源代码加断点,在matlab运行时就可以调试了,具体请参考帮助文档。
下面是一个例子:
先写fortran代码:传入一个数组和一个数字,输出一个数组
Add.f90 ,注意此文档名为将来matlab调用的函数名,调用函数名时与其内的子函数名称Add无关。
1 #include "fintrf.h" !必须有的头文件,里面有mxGetPr, mxGetM, mxGetN,mxCreateDoubleMatrix等函数的申明 http://yuehongliang2000.lofter.com/post/1d001431_ab72071 2 3 4 subroutine mexFunction(OutSum,OutVar,InSum,InVar)!函数接口名称必须为mexFunction, 5 6 7 !OutSum:输出参数个数 8 9 10 !OutVar:输出参数数组指针 11 12 13 !InSum:输入参数个数 14 15 16 !InVar:输入参数数组指针 17 18 19 !参数顺序不能随意更改 20 Integer InSum,OutSum 21 22 23 mwPointer InVar(*),OutVar(*) !mwPointer专门用于表示指针变量,这个不能随意用Integer代替 24 25 26 mwPointer mxGetPr, mxGetM, mxGetN,mxCreateDoubleMatrix !这个对返回指针函数的再次申明, 27 integer, parameter :: fp = selected_real_kind(15,300) 28 Integer , parameter :: myINT = SELECTED_INT_KIND( 8 ) 29 30 31 Real(fp),Allocatable::x(:,:),y(:,:) 32 real(fp)::z 33 34 35 Integer m,n 36 37 38 39 40 41 If(InSum/=2)Then 42 43 44 call mexErrMsgIdAndTxt('MATLAB:InputTooBig','输入参数个数必须为2个') 45 46 47 Return 48 49 50 EndIf 51 52 53 54 55 56 m=mxGetM(InVar(1))!获取第1个输入参数的行数 57 58 59 n=mxGetN(InVar(1))!获取第1个输入参数的列数 60 61 62 Allocate(x(m,n),y(m,n)) 63 64 65 Call mxCopyPtrToReal8(mxGetPr(InVar(1)),x,m*n)!将第1个参数数组赋值给x变量 66 67 68 Call mxCopyPtrToReal8(mxGetPr(InVar(2)),z,1)!将第2个整数变量赋值给z 69 70 71 72 73 Call Add(x,y,z,m,n)!调用内部函数 74 75 76 77 78 79 OutVar(1)=mxCreateDoubleMatrix(m,n,0)!给返回参数分配内存 80 81 82 Call mxCopyReal8ToPtr(y,mxGetPr(OutVar(1)),m*n)!将返回参数赋值给分配的内存 83 84 85 86 87 88 DeAllocate(x,y)!释放临时分配的内存 89 90 91 Return 92 93 94 End SubRoutine 95 96 97 98 99 ! SubRoutine Add(x,y,z,m,n) 100 ! 101 ! Integer,Intent(In)::m,n 102 ! integer, parameter :: fp = selected_real_kind(15,300) 103 ! 104 ! Real(fp),Intent(In)::x(m,n),z 105 ! 106 ! Real(fp),Intent(Out)::y(m,n) 107 ! 108 ! Integer i,j 109 ! 110 ! Do i=1,m 111 ! 112 ! Do j=1,n 113 ! 114 ! y(i,j)=x(i,j)+z 115 ! 116 ! EndDo 117 ! 118 ! EndDo 119 ! 120 ! Return 121 ! 122 !End SubRoutine 123 124 SubRoutine Add(x,y,z,m,n) 125 126 127 Integer,Intent(In)::m,n 128 integer, parameter :: fp = selected_real_kind(15,300) 129 130 131 Real(fp),Intent(In)::x(m,n),z 132 133 134 Real(fp),Intent(Out)::y(m,n) 135 136 137 Integer i,j 138 139 140 Do i=1,m 141 142 143 Do j=1,n 144 145 146 y(i,j)=x(i,j)+z 147 148 149 EndDo 150 151 152 EndDo 153 154 155 Return 156 157 158 End SubRoutine
将matlab当前路径改为Add.f90同目录路径,然后 : mex Add.f90 ,之后会生成Add.mex64
在matlab命令行窗口输入:
x=[1 2 3];
a=2;
y=Add(x,a)
---
我把Add.f90改为multiple.f90的话:
效果一样。
同样的功能的m文档,会优先调用.mexw64,且速度很快。所以可以写一个同名的m文档,只有函数名,之后全是注释文档,用以查阅。