Converting legacy FORTRAN code to MATLAB code

25 views (last 30 days)
I have found Ben Barrowes' f2matlab program for converting legacy FORTRAN to MATLAB.
Has anyone actually used this software successfully? When I try to run it from the command prompt:
f2matlab('myprogram.f90')
or
f2matlab('myprogram.f')
where myprogram.90 or myprogram.f are in the correct location and are found, the code blows up right away on a disp statement with the following error message. It looks like it tries to read the first statements of the .f90 or .f files as a filename:
************************************************************************************************************************************************************
-----------------------------------------------------------
| f2matlab -- Ben Barrowes, Barrowes Consulting |
-----------------------------------------------------------
Not enough input arguments.
Error in f2matlab (line 225)
disp(['Before includes ',filename,' (',num2str(cputime-tStart),' elapsed)']);
*************************************************************************************************************************************************************
Anyway, does anyone know what is going on?

Accepted Answer

Cris LaPierre
Cris LaPierre on 17 Aug 2022
Ben seems to be responsive to Discussion posts on the corresponding File Exchange page. You might try posting your question there.
  5 Comments
Ken Bannister
Ken Bannister on 18 Aug 2022
Ben: One further comment. Again, not at all an f2matlab problem. I keep having trouble in MATLAB with making sure everything needed is in the correct path so that it can be found. It could be I didn't do this correctly with f2matlab. Any advice you can render on this would be greatly appreciated. - Ken
Ben Barrowes
Ben Barrowes on 19 Aug 2022
Ken: your code has a couple of issues that the free fileexchange version of f2matlab can't handle. In the README file it says that the file needs to have all goto statements (including arithmetic if statements) refactored before f2matlab can work. This is an "arithmetic if" in your code:
if(w(j))5,10,10
And then you also have a goto statement "go to 15" in your code.
I have a more capable version of f2matlab, and here is the result for your code:
function [n1,w_fv,s,n2,nout]=print1(n1,w_fv,s,n2,nout,varargin);
persistent firstCall i j v1 format_25 format_30 format_35
if isempty(firstCall);
firstCall=1;
end;
if firstCall;
format_25=[ '\n' , '\n' , '\n' ,'%1x',' mode shapes'];
format_30=[ '\n' ,'%1x',' mode number','%3i',' ferquency ','%12.4e'];
format_35=['%1x',repmat('%12.4e',1,4)];
i=0;
j=0;
v1=0.0;
end
firstCall=0;
[s,s_orig,s_shape]=reshapeinout(s,[20,20]);
[writeErrFlag,wfso]=writeFmt(nout,[format_25]);
eval(wfso);
for j = 1: n1
if(w_fv(j) < 0)
v1 = -sqrt(-w_fv(j))./6.2831853;
else;
v1 = sqrt(w_fv(j))./6.2831853;
end
[writeErrFlag,wfso]=writeFmt(nout,[format_30],'j','v1');
eval(wfso);
[writeErrFlag,wfso]=writeFmt(nout,[format_35],{'s(i,j)','i',1,1,n2});
eval(wfso);
end
j = fix(n1+1);
s=reshapeinout(s,s_orig,s_shape);
end %subroutine print1
I have attached a zip file of some auxiliary functions that this routine will also need (writeFmt.m, reshapeinouts.m, etc.).
Some of these lines are probably overkill for your code (reshaping inputs and outputs), but fortran can do some things that matlab can't (and probably shouldn't) do. For example, in fortran, you could pass just a 1-D vector 400 values (or longer!) long into your 3rd input, s, and fortran would be fine with it. Not so in matlab. Thus the reshaping just in case. If I turn this functionaliy off, the code would look like this:
function [n1,w_fv,s,n2,nout]=print1(n1,w_fv,s,n2,nout,varargin);
persistent firstCall i j v1 format_25 format_30 format_35
if isempty(firstCall);
firstCall=1;
end;
if firstCall;
format_25=[ '\n' , '\n' , '\n' ,'%1x',' mode shapes'];
format_30=[ '\n' ,'%1x',' mode number','%3i',' ferquency ','%12.4e'];
format_35=['%1x',repmat('%12.4e',1,4)];
i=0;
j=0;
v1=0.0;
end
firstCall=0;
[writeErrFlag,wfso]=writeFmt(nout,[format_25]);
eval(wfso);
for j = 1: n1
if(w_fv(j) < 0)
v1 = -sqrt(-w_fv(j))./6.2831853;
else;
v1 = sqrt(w_fv(j))./6.2831853;
end
[writeErrFlag,wfso]=writeFmt(nout,[format_30],'j','v1');
eval(wfso);
[writeErrFlag,wfso]=writeFmt(nout,[format_35],{'s(i,j)','i',1,1,n2});
eval(wfso);
end
j = fix(n1+1);
end %subroutine print1

Sign in to comment.

More Answers (1)

Ken Bannister
Ken Bannister on 19 Aug 2022
Ben: Many thanks again on your help. You are right, I should have studied your README file much more carefully! I have always been ill-at-ease with FORTRAN if statements, and MATLAB's slightly different way of handling them has only added to my unease. I never used FORTRAN go to statements in my own programming work because I was told they represent bad programming practice. I remember at one time, in an early FORTRAN version, it was even possible to use a "computed go to" statement of the form "GO TO M" where "M" was a statement number your program could compute on the fly! Two other FORTRAN features I really hate are COMMON (labeled and unlabeled), and EQUIVALENCE. If you aren't careful, you can do serious damage to your data (and your psyche) using EQUIVALENCE statements. Computer memory (they called it "core storage" in the old days) used to be a very precious and costly commodity, so programmers would go to extremes to minimize memory use. FORTRAN developers accommodated this zealous pursuit.
Thanks also for sharing your MATLAB expertise and sharing the zip file of additional f2matlab routines. There is no way I could have figured out some of these solutions on my own. I see two new (to me) functions , "persistent" and "reshape" I need to learn about and understand how to use. The program that houses my "print1" routine does have some variables it needs to share with several other routines. It looks like the old MATLAB "global" statement is no longer recommended, so I need to figure out a good alternative. - Ken Bannister
  2 Comments
Ken Bannister
Ken Bannister on 24 Aug 2022
Ben: Just curious what this output means from f2matlab. I converted another f77 routine to f90 using an online British source, making sure all the "go to" statements were reprogrammed ("refactored"?). When I ran it through f2matlab, I got the messages below, followed by output that looks substantially like what I submitted. Perhaps conversions of some statements to MATLAB were indeed done, but maybe there too many other issues were present in the f90 file to go any further? There were several DIMENSION, COMMON, and EQUIVALENCE statements that remained in the f90 file, so perhaps all those have to converted by hand? :
V/R, Ken Bannister
">> f2matlab('MAIN_PROGRAMf90.f90')
-----------------------------------------------------------
| f2matlab -- Ben Barrowes, Barrowes Consulting |
-----------------------------------------------------------
Before includes MAIN_PROGRAMf90.f90 (0.03125 elapsed)
Read in the file MAIN_PROGRAMf90.f90 (0.09375 elapsed)
preliminary simple changes (set 1) (0.23438 elapsed)
preliminary simple changes (set 2) (0.4375 elapsed)
Done with preliminary simple changes (0.48438 elapsed)
********* Taking care of the modules (if there are any) *** "
Ken Bannister
Ken Bannister on 24 Aug 2022
Ben: My bad. After further testing using a much-reduced version of my converted f90 input, I discovered that it
helps to have a "program" statement at the top of the file, e.g., "program ken_test". Once I added a statement like that, f2matlab was able to do its processing. V/R, Ken

Sign in to comment.

Products


Release

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!