make_mex_gateway.m

来自「student teacher and proferssor llove thi」· M 代码 · 共 349 行

M
349
字号
function filestr=make_mex_gateway(filename,inoutother,cw,vararginout,localvartype,want_fb,want_kb,alpha)% This function will write filename to contain the appropriate mex gateway.%   filestr=make_mex_gateway(filename,inoutother,cw,vararginout,localvartype,varargin)%%   filename should be without the .f extensioninnum=length(inoutother{1});outnum=length(inoutother{2});othernum=length(inoutother{3});fid=fopen([filename,'.f90'],'w');r=char(10);% Header comes firstfilestr=['subroutine mexfunction(nlhs, plhs, nrhs, prhs)',r,...	 '!--------------------------------------------------------------------',r];if ~alpha filestr=[filestr,'integer plhs(*), prhs(*)',r];else filestr=[filestr,'integer*8 plhs(*), prhs(*)',r];endfilestr=[filestr,'integer nlhs, nrhs      ',r,...	 '!--------------------------------------------------------------------',r,...	 '!     Create pointers for calling the computational subroutine.',r];% Now declare all the pointersfilestr=[filestr,'!     inputs',r];if ~alpha filestr=[filestr,'integer :: '];else filestr=[filestr,'integer*8 :: '];endcountimag=0;imags=[];reals=[];for i=1:innum if i~=innum  if isreal(getfield(cw,inoutother{1}{i}))   filestr=[filestr,inoutother{1}{i},'_ptr,'];   reals=[reals i];  else   filestr=[filestr,inoutother{1}{i},'_ptr_r,',inoutother{1}{i},'_ptr_i, '];   countimag=countimag+1;imags=[imags i];  end else  if isreal(getfield(cw,inoutother{1}{i}))   filestr=[filestr,inoutother{1}{i},'_ptr',r];   reals=[reals i];  else   filestr=[filestr,inoutother{1}{i},'_ptr_r,',inoutother{1}{i},'_ptr_i',r];   countimag=countimag+1;imags=[imags i];  end endendif ~isempty(reals) filestr=[filestr,'real, allocatable :: ']; for i=reals  if i~=reals(end)   filestr=[filestr,inoutother{1}{i},'(:,:),'];  else   filestr=[filestr,inoutother{1}{i},'(:,:)',r];  end endendif countimag>0 filestr=[filestr,'complex, allocatable :: ']; for i=imags  if i~=imags(end)   filestr=[filestr,inoutother{1}{i},'(:,:),'];  else   filestr=[filestr,inoutother{1}{i},'(:,:)',r];  end endend%Let's assign a vararginout for those outputs who have no associationfor i=(length(vararginout)+1):outnum temp3=[0 0]; for j=1:length(inoutother{1})  if ((size(getfield(cw,inoutother{2}{i}),1)==size(getfield(cw,inoutother{1}{j}),1))&(size(getfield(cw,inoutother{2}{i}),2)==size(getfield(cw,inoutother{1}{j}),2)))   temp3(1)=j;temp3(2)=j;temp5{i}{1}='_m';temp5{i}{2}='_n';   if want_fb|want_kb    if i<11     disp(['  Setting the size of output var ',inoutother{2}{i},' equal to the input var ',inoutother{1}{j},'.']);    end   end   break  end  if size(getfield(cw,inoutother{2}{i}),1)==size(getfield(cw,inoutother{1}{j}),1)   temp3(1)=j;temp5{i}{1}='_m';  end  if size(getfield(cw,inoutother{2}{i}),1)==size(getfield(cw,inoutother{1}{j}),2)   temp3(1)=j;temp5{i}{1}='_n';  end  if size(getfield(cw,inoutother{2}{i}),2)==size(getfield(cw,inoutother{1}{j}),1)   temp3(2)=j;temp5{i}{2}='_m';  end  if size(getfield(cw,inoutother{2}{i}),2)==size(getfield(cw,inoutother{1}{j}),2)   temp3(2)=j;temp5{i}{2}='_n';  end end if all(temp3)  vararginout{i}{1}{1}=inoutother{1}{temp3(1)};  if ~isreal(getfield(cw,vararginout{i}{1}{1}))   temp4{i}{1}='_r';else,temp4{i}{1}='';  end  vararginout{i}{1}{2}=inoutother{1}{temp3(2)};  if ~isreal(getfield(cw,vararginout{i}{1}{2}))   temp4{i}{2}='_r';else,temp4{i}{2}='';  end  vararginout{i}{2}=~isreal(getfield(cw,inoutother{2}{i})); else  error(['output variable ',inoutother{2}{i},'''s size does not match any input variable.',r,'Make an input variable the same size as ',inoutother{2}{i},' (in this case ',num2str(size(getfield(cw,inoutother{2}{i}),1)),',',num2str(size(getfield(cw,inoutother{2}{i}),2)),').']); endend%Now for the outputsfilestr=[filestr,'!     outputs',r];if ~alpha filestr=[filestr,'integer :: '];else filestr=[filestr,'integer*8 :: '];endcountimag=0;imags=[];reals=[];for i=1:outnum if i~=outnum  if vararginout{i}{2}==0   filestr=[filestr,inoutother{2}{i},'_ptr,'];   reals=[reals i];  else   filestr=[filestr,inoutother{2}{i},'_ptr_r,',inoutother{2}{i},'_ptr_i,'];   countimag=countimag+1;imags=[imags i];  end else  if vararginout{i}{2}==0   filestr=[filestr,inoutother{2}{i},'_ptr',r];   reals=[reals i];  else   filestr=[filestr,inoutother{2}{i},'_ptr_r,',inoutother{2}{i},'_ptr_i',r];   countimag=countimag+1;imags=[imags i];  end endendif ~isempty(reals) filestr=[filestr,'real, allocatable :: ']; for i=reals  if i~=reals(end)   filestr=[filestr,inoutother{2}{i},'(:,:),'];  else   filestr=[filestr,inoutother{2}{i},'(:,:)',r];  end endendif countimag>0 filestr=[filestr,'complex, allocatable :: ']; for i=imags  if i~=imags(end)   filestr=[filestr,inoutother{2}{i},'(:,:),'];  else   filestr=[filestr,inoutother{2}{i},'(:,:)',r];  end endend% Now let's pass the sizes of all the input vars.filestr=[filestr,'!     Any other variables needed',r];filestr=[filestr,'integer '];for i=1:innum if i~=innum  filestr=[filestr,inoutother{1}{i},'_m,',inoutother{1}{i},'_n,']; else  filestr=[filestr,inoutother{1}{i},'_m,',inoutother{1}{i},'_n',r]; endend% Check for the proper number of inputs and outputs.filestr=[filestr,...	 '!---------------------------------------------------------------------',r,...	 '!     CHECK FOR PROPER NUMBER OF ARGUMENTS',r,...	 'if (nrhs .ne. ',num2str(innum),') then',r,...	 '  call mexerrmsgtxt(''',filename,' requires ',num2str(innum),' input arguments',char(39),')',r,...	 'elseif (nlhs .ne. ',num2str(outnum),') then',r,...	 '  call mexerrmsgtxt(''',filename,' requires ',num2str(outnum),' output arguments',char(39),')',r,...	 'endif',r];% OK, let's get the sizes of all the inputsfilestr=[filestr,'!---------------------------------------------------------------------',r];filestr=[filestr,'!     Get the sizes of all the input variables',r];count=1;for i=1:innum filestr=[filestr,'',inoutother{1}{i},'_m=mxGetm(prhs(',num2str(count),'));',inoutother{1}{i},'_n=mxGetn(prhs(',num2str(count),'))',r]; count=count+1;end% Return argumnets, allocation, and sizing.filestr=[filestr,'!     Create matrices for the return argument',r];count=1;for i=1:outnum if vararginout{i}{2}==0  filestr=[filestr,'plhs(',num2str(count),')=mxCreateFull(',vararginout{i}{1}{1},temp5{i}{1},',',vararginout{i}{1}{2},temp5{i}{2},',0)',r]; else  filestr=[filestr,'plhs(',num2str(count),')=mxCreateFull(',vararginout{i}{1}{1},temp5{i}{1},',',vararginout{i}{1}{2},temp5{i}{2},',1)',r];  end count=count+1;endcount=1;for i=1:outnum if vararginout{i}{2}==0  filestr=[filestr,'',inoutother{2}{i},'_ptr=mxGetPr(plhs(',num2str(count),'))',r]; else  filestr=[filestr,'',inoutother{2}{i},'_ptr_r=mxGetPr(plhs(',num2str(count),'));'];  filestr=[filestr,'',inoutother{2}{i},'_ptr_i=mxGetPi(plhs(',num2str(count),'))',r];  end count=count+1;end% Right hand side argumentsfilestr=[filestr,'!     Copy right hand arguments to local arrays',r];count=1;for i=1:innum if isreal(getfield(cw,inoutother{1}{i}))  filestr=[filestr,'',inoutother{1}{i},'_ptr=mxGetPr(prhs(',num2str(count),'))',r]; else  filestr=[filestr,'',inoutother{1}{i},'_ptr_r=mxGetPr(prhs(',num2str(count),'));'];  filestr=[filestr,'',inoutother{1}{i},'_ptr_i=mxGetPi(prhs(',num2str(count),'))',r]; end count=count+1;  end% Allocate arraysfilestr=[filestr,'!     Allocate and copy data to arrays',r];filestr=[filestr,'allocate('];for i=1:innum if i~=innum  filestr=[filestr,inoutother{1}{i},'(',inoutother{1}{i},'_m,',inoutother{1}{i},'_n),']; else  filestr=[filestr,inoutother{1}{i},'(',inoutother{1}{i},'_m,',inoutother{1}{i},'_n))',r]; endendfilestr=[filestr,'allocate('];for i=1:outnum if i~=outnum  filestr=[filestr,inoutother{2}{i},'(',vararginout{i}{1}{1},temp5{i}{1},',',vararginout{i}{1}{2},temp5{i}{2},'),']; else  filestr=[filestr,inoutother{2}{i},'(',vararginout{i}{1}{1},temp5{i}{1},',',vararginout{i}{1}{2},temp5{i}{2},'))',r];  endendfor i=1:innum if isreal(getfield(cw,inoutother{1}{i}))  filestr=[filestr,'call mxCopyPtrToReal8(',inoutother{1}{i},'_ptr,',inoutother{1}{i},',',inoutother{1}{i},'_m*',inoutother{1}{i},'_n)',r]; else  filestr=[filestr,'call mxCopyPtrToComplex16(',inoutother{1}{i},'_ptr_r,',inoutother{1}{i},'_ptr_i,',inoutother{1}{i},',',inoutother{1}{i},'_m*',inoutother{1}{i},'_n)',r]; endend% Call the actual computational subroutinefilestr=[filestr,'!---------------------------------------------------------------------',r];filestr=[filestr,'!     Do the actual computations in a subroutine',r];filestr=[filestr,'call ',filename,'('];for i=1:outnum filestr=[filestr,inoutother{2}{i},','];endfor i=1:innum filestr=[filestr,inoutother{1}{i},','];endfor i=1:innum if i~=innum  filestr=[filestr,inoutother{1}{i},'_m,',inoutother{1}{i},'_n,']; else  filestr=[filestr,inoutother{1}{i},'_m,',inoutother{1}{i},'_n)',r]; endend% End up the gatewayfilestr=[filestr,'!---------------------------------------------------------------------',r];for i=1:outnum if vararginout{i}{2}==0  filestr=[filestr,'call mxCopyReal8ToPtr(',inoutother{2}{i},',',inoutother{2}{i},'_ptr,',vararginout{i}{1}{1},temp5{i}{1},'*',vararginout{i}{1}{2},temp5{i}{2},')',r]; else  filestr=[filestr,'call mxCopyComplex16ToPtr(',inoutother{2}{i},',',inoutother{2}{i},'_ptr_r,',inoutother{2}{i},'_ptr_i,',vararginout{i}{1}{1},temp5{i}{1},'*',vararginout{i}{1}{2},temp5{i}{2},')',r];  endend% Deallocate complex array mirrorsfilestr=[filestr,'deallocate('];for i=1:outnum filestr=[filestr,inoutother{2}{i},','];endfor i=1:innum if i~=innum  filestr=[filestr,inoutother{1}{i},',']; else  filestr=[filestr,inoutother{1}{i},')',r]; endendfilestr=[filestr,'return',r];filestr=[filestr,'end subroutine mexfunction',r];%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Now move on to the computational routine.filestr=[filestr,'!---------------------------------------------------------------------',r];filestr=[filestr,'!---------------------------------------------------------------------',r];filestr=[filestr,r];filestr=[filestr,r];filestr=[filestr,'!     COMPUTATIONAL SUBROUTINE',r];filestr=[filestr,'subroutine ',filename,'('];for i=1:outnum filestr=[filestr,inoutother{2}{i},','];endfor i=1:innum filestr=[filestr,inoutother{1}{i},','];endfor i=1:innum if i~=innum  filestr=[filestr,inoutother{1}{i},'_m,',inoutother{1}{i},'_n,']; else  filestr=[filestr,inoutother{1}{i},'_m,',inoutother{1}{i},'_n)',r]; endendfilestr=[filestr,'!---------------------------------------------------------------------',r];% Create calling variablesfilestr=[filestr,'!     size variables',r];filestr=[filestr,'integer '];for i=1:innum if i~=innum  filestr=[filestr,inoutother{1}{i},'_m,',inoutother{1}{i},'_n,']; else  filestr=[filestr,inoutother{1}{i},'_m,',inoutother{1}{i},'_n',r]; endend%filestr=[filestr,'!     First create all the calling variables. ',r];%filestr=[filestr,'!     REM*** The changes are returned to the caller.',r];filestr=[filestr,'!     All other local variables',r];% Create local mirrorsfilestr=[filestr,'!     Input/Output local mirrors',r];for i=1:length(inoutother{1}) if prod(size(getfield(cw,inoutother{1}{i})))==1  if isreal(getfield(cw,inoutother{1}{i}))   filestr=[filestr,'real ',inoutother{1}{i},'',r];  else   filestr=[filestr,'complex ',inoutother{1}{i},'',r];  end else  if isreal(getfield(cw,inoutother{1}{i}))   filestr=[filestr,'real ',inoutother{1}{i},'(',inoutother{1}{i},'_m,',inoutother{1}{i},'_n)',r];  else   filestr=[filestr,'complex ',inoutother{1}{i},'(',inoutother{1}{i},'_m,',inoutother{1}{i},'_n)',r];  end endendfor i=1:length(inoutother{2}) if isreal(getfield(cw,inoutother{2}{i}))  filestr=[filestr,'real ',inoutother{2}{i},'(',vararginout{i}{1}{1},temp5{i}{1},',',vararginout{i}{1}{2},temp5{i}{2},')',r]; else  filestr=[filestr,'complex ',inoutother{2}{i},'(',vararginout{i}{1}{1},temp5{i}{1},',',vararginout{i}{1}{2},temp5{i}{2},')',r]; endendfilestr=[filestr,'!     Fill in vars going in and out',r];filestr=[filestr,'! --- Main computational routine. --------------------------------------',r];filestr=[filestr,r];filestr=[filestr,'return',r];filestr=[filestr,'end subroutine ',filename,r];filestr=[filestr,'!---------------------------------------------------------------------',r];fprintf(fid,'%s',filestr);fclose(fid);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?