現在この質問をフォロー中です
- フォローしているコンテンツ フィードに更新が表示されます。
- コミュニケーション基本設定に応じて電子メールを受け取ることができます。
エラーが発生しました
ページに変更が加えられたため、アクションを完了できません。ページを再度読み込み、更新された状態を確認してください。
古いコメントを表示
0 投票
Hello,
Is it possible to pass from matlab data labeled as follows and if so what would be the efficient way to do it?
AeroConfig_Hub_position %a (3*1) vector
AeroConfig_Hub_orientation %a (3*3) matrix
AeroConfig_Hub_translationvel %a (3*1)vector
AeroConfig_Hub_rotationvel %a (3*1) vector
through a mex interface that will format them to be read by the fortan code as:
Aeroconfig%Hub%position
Aeroconfig%Hub%orientation
AeroConfig%Hub%rotationvel
AeroConfig%Hub%translationvel
any help is greatly appreciated.
採用された回答
James Tursa
2012 年 6 月 26 日
Download this package from the FEX:
Follow the instructions to compile the modules. Then you can do stuff like this:
m-code:
myFortranMexRoutine(AeroConfig_Hub_position,...
AeroConfig_Hub_orientation,...
AeroConfig_Hub_translationvel,...
AeroConfig_Hub_rotationvel);
Fortran code:
#include "fintrf.h"
subroutine mexFunction(nlhs,plhs,nrhs,prhs)
use MatlabAPImx
implicit none
integer nlhs, nrhs
mwPointer plhs(*), prhs(*)
__yourtype__ Aeroconfig
AeroConfig%Hub%position = fpGetPr1(prhs(1))
AeroConfig%Hub%orientation = fpGetPr(prhs(2))
AeroConfig%Hub%translationvel = fpGetPr1(prhs(3))
AeroConfig%Hub%rotationvel = fpGetPr1(prhs(4))
Caution: The above is just an outline with no error checking. In production code you would need to check nrhs and nlhs to see if there are the correct number of inputs & outputs. And you would have to retrieve the data pointers via fpGetPr1 and fpGetPr into separate variables and examine if they are associated prior to using them. Etc.
13 件のコメント
Chris
2012 年 6 月 26 日
Hi James,
Thanks for the response. The package will help a lot. I get the following errors using it and wondered if you could tell me what is wrong.:
aerodyngateway.f90(32): error #6404: This name does not have a type, and must have an explicit type. [TURBINECOMPONENTS_HUB_POSITION]
TurbineComponents_Hub_position = fpGetPr1(plhs(1))
^
aerodyngateway.f90(32): error #6366: The shapes of the array expressions do not conform. [TURBINECOMPONENTS_HUB_POSITION]
TurbineComponents_Hub_position = fpGetPr1(plhs(1))
^
Declarations as follows:
TYPE :: Marker
REAL(8) :: Position(3)
REAL(8) :: Orientation(3,3)
REAL(8) :: TranslationVel(3)
REAL(8) :: RotationVel(3)
END TYPE Marker
TYPE :: AeroConfig
TYPE(Marker) :: Hub
END TYPE AeroConfig
Type(AeroConfig) :: TurbineComponents
James Tursa
2012 年 6 月 26 日
You are using the MATLAB variable names with underscores on the Fortran side. Use the percent signs (%) as shown above and as shown in your original code to get at the structure components in Fortran. E.g.,
TurbineComponents%Hub%position = fpGetPr1(prhs(1))
TurbineComponents%Hub%orientation = fpGetPr(prhs(2))
TurbineComponents%Hub%translationvel = fpGetPr1(prhs(3))
TurbineComponents%Hub%rotationvel = fpGetPr1(prhs(4))
Chris
2012 年 6 月 26 日
Thanks James. My mex file is now done correctly but I get the following link problems:
aerodyngateway.obj : error LNK2019: unresolved external symbol MATLABAPIMX_mp_FPGETPR1DOUBLE referenced in function MEXFUNCTION
aerodyngateway.obj : error LNK2019: unresolved external symbol MATLABAPIMX_mp_FPGETPR2DOUBLE referenced in function MEXFUNCTION
aerodyngateway.mexw64 : fatal error LNK1120: 3 unresolved externals
are these due to the modules not being compiled correctly?
Also am I correct in thinking that all I need to change the matlab compile programs to match it with my compiler/VS studio edition is the following :
options = [matlabroot '\bin\win32\mexopts\intelf91msvs2005engmatopts.bat']
James Tursa
2012 年 6 月 26 日
You need to include the pre-compiled module object modules in the mex command line. E.g.,
% Do this once to get the module compiled
mex -c MatlabAPImx.f
% Then do this to compile your mex function
mex myFortranMexFunction.f MatlabAPImx.obj
James Tursa
2012 年 6 月 26 日
Regarding the mex options, did you use mex -setup to select the compiler?
Chris
2012 年 6 月 26 日
yes i selected the compiler using mex - setup. It works when I include the .obj. Thanks alot for the help.
A theoretical question: Is there a way to use the derived data types in fortran in a matlab code? So if say matlab calculated each component thats in type aeronconfig ( like hub, blade, tower) with each of those components having position, orientation, translationvel, rotationvel vectors then passed it via mex file to a function in fortran:
%Type(aeroconfig) :: turbinecomponents
%function(turbinecomponents).
So instead of passing each component individually, have it included in one large array that is passed once.
James Tursa
2012 年 6 月 26 日
On the MATLAB side you can have a struct with the same component naming convention as on the Fortran side. E.g.,
TurbineComponents.Hub.Position = whatever;
TurbineComponents.Hub.Orientation = whatever;
:
etc.
Then you only have to pass in the one MATLAB struct variable. Inside the mex routine you can use mxGetField to pick off the desired components and then use the fpGetPr1 etc functions on the mxGetField results to get at the data and one-by-one copy them into their Fortran counterparts. There is no magic bullet to do the copying all in one fell swoop ... you have to write the component copying for each individual component since the actual storage of the data in memory is different on both sides.
James Tursa
2012 年 6 月 27 日
Another alternative is to have your Fortran user defined data type contain pointers instead of arrays, and then just point them to the incoming MATLAB variable data. Works as long as you treat the input as read-only.
Chris
2012 年 7 月 2 日
編集済み: Walter Roberson
2012 年 7 月 3 日
Hi James,
I'm trying to follow your instructions with the struct command. I have TurbineComponents=struct('Hub',hub,'Tower',tower) with hub = struct('position',turbinecomponents.hub.position, 'orientation'...etc)
Is this the correct way for passing the array?
I also get the following errors when trying to compile my mex file and wanted to see if you knew what was wrong:
>> mex aerotest.f90 aerodyntest.obj
aerotest.f90(75): error #5082: Syntax error, found END-OF-STATEMENT when expecting one of: ( % [ . = =>
Two(TurbineComponents,A,B,C,D)
------------------------------------^
aerotest.f90(58): error #6303: The assignment operation or the binary expression operation is invalid for the data types of the two operands. [MXGETARRAY]
TurbineComponents = mxGetArray(turbine_ptr)
--------------------------^
compilation aborted for aerotest.f90 (code 1)
James Tursa
2012 年 7 月 2 日
Chris, go ahead and post your m-code snippet for constructing the input and calling the mex routine, and also the mex routine itself and I can look at it.
Chris
2012 年 7 月 4 日
Ignore the previous code, I think I figured it out and saw how poor the code was.
I'm only having a little trouble understanding how to use the mxGetField. Do you know of any examples of this used with Fortran? The only examples I've seen are with C
James Tursa
2012 年 7 月 4 日
mxGetField returns a pointer to an mxArray, which you can then use just like any other pointer to an mxArray. E.g., if on the MATLAB side you did this:
myvar.myfield = 1:3
mymexroutine(myvar)
And if mymexroutine was the Fortran mex routine, then inside this mex routine you could have code like this to get at the data:
use MatlabAPImx
mwPointer mx
mwIndex i
real*8, pointer :: x(:)
i = 1
mx = mxGetField(prhs(1),i,"myfield")
x => fpGetPr1(mx)
The Fortran variable x will point to the 1:3 double data.
Thanks James, so for a nested struct like turbinecomponents.hub.position, I would need to use the mxGetField twice, something like:
use MatlabAPImx
mwPointer mx, dx
mwIndex i
real*8, pointer :: x(:), (y:)
i= 1
mx = mxGetField(prhs(1),i,"Hub")
x = fpGetPr1(mx)
dx = mxGetField(prhs(1),i,"Position")
y = fpGetPr1(dx)
その他の回答 (0 件)
カテゴリ
ヘルプ センター および File Exchange で Write C Functions Callable from MATLAB (MEX Files) についてさらに検索
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
