Looking for the latest version? Download f2matlab_4.1.zip (1.4 MB)
Home
Name Modified Size Downloads / Week Status
f2matlab 2017-04-04 88 weekly downloads
README 2017-04-04 19.5 kB 0
Totals: 2 Items   19.5 kB 8
README file for f2matlab.m CONTENTS: -1. SUPPORT f2matlab AND CONSULTING 0. DISCLAIMER 1. OBJECTIVE 2. MOTIVATION 3. BUG REPORTS and WISH LIST 4. F2MATLAB CAPABILITIES 5. F2MATLAB LIMITATIONS 6. HOW TO USE F2MATLAB 7. EXAMPLES 8. REVISION HISTORY -1.SUPPORT f2matlab. I now also do conversion/translation/validation/optimization consulting. Please refer to my webpage: http://engineering.dartmouth.edu/~d30574x/consulting/consultingIndex.html Even though f2matlab is free (under GPL) for the using, I would like to ask that those who find it useful, wish to support the project, and are able to make a contribution to please do so commesurate with use (especially corporations). *** Important - Please donate using your PayPal account and not a credit card so as to avoid fees at PayPal. Thank you! PayPal email ID: barrowes@users.sourceforge.net 0. DISCLAIMER: Matlab is a trademark of the Mathworks company and is owned by them. The author makes no guarantee express or implied of any kind as to the applicability, usefulness, efficacy, bug-freeness, or the accuracy of the ensuing results from using f2matlab. The author bears no responsibility for any unwanted effect resulting from the use of this program. The author is not affiliated with the Mathworks. The source code is given in full in the hopes that it will prove useful. Devlopment is done through sourceforge at f2matlab.sourceforge.net. 1. OBJECTIVE: f2matlab.m is a small translator which aims to convert Fortran90 files to Matlab m-files. 2. MOTIVATION: 1) Matlab is becoming ubiquitous in the engineering and scientific communities for its ease of use coupled with its powerful libraries. Yet the fact remains that a large number of stable and dependable programs exist in the fortran77/90 corpus. 2) Many times, often amidst the porting of fortran programs to Matlab, an automated converter of fortran90 code to Matlab code would be useful. 3) Having written matlab2fmex.m, a matlab to fortran90 mex file converter, the writing of f2matlab, which performs the reverse conversion, was substantially simplified. 3. BUG REPORTS and WISH LIST: For all bug reports, a wish list for f2matlab, and suggestions, see http://f2matlab.sourceforge.net/ or email barrowes@users.sourceforge.net 4. F2MATLAB CAPABILITIES: f2matlab is aimed at converting Fortran90 code to Matlab m-files. Accordingly, only basic data types and constructions are recommended. f2matlab can handle: all numeric types (handled by Matlab interpreter) most string functions comparisons, branches, loops, etc. basic read/write/print statements (if it's not too fancy...) modules 5. F2MATLAB LIMITATIONS: f2matlab can not handle some features of fortran90 yet. These include: can't handle complex read and write statements derived-typed variables equivalence ... 6. HOW TO USE F2MATLAB: f2matlab expects a single fortran90 fortran file to convert. If you have fortran77 code, use some free converter (e.g. to_f90 by Alan Miller) before running f2matlab. Then simply call f2matlab by using the full filename: f2matlab('filename.f90'); The output will be filename.m in the same directory. A few flags are available that effect conversion: % want_kb=0; 1 ==> if keyboard mode is desired after some conversion steps % want_ze=0; 1 ==> direct f2matlab to zero all array variables. % want_fi=0; 1 ==> direct f2matlab to try to put fix()'s around declared integers. Multiple subroutines and functions can and should be in the same fortran90 file. 7. EXAMPLES: Below are some specific examples. Other tests and examples include: Running the script TESTING_cfs in the comp_spec_func directory converts all of the f90 code from Shanjie Zhang and Jianming Jin's book. These converted m-files can also be found at: http://ceta.mit.edu/comp_spec_func/ For some larger examples (>=10000 lines), see the examples directory. The following fortran packages were downloaded (most from John Burkardt at FSU) and converted: - fempack routines for finite element analysis: f2matlab('femprb.f90'); - quadrule f2matlab('quadrule_prb.f90'); - quadrature integration routines by Arthur Stroud: f2matlab('stroud_prb.f90'); Run the script TESTING_ex in the examples directory to convert and test all the examples there. The following f77 program, lpmns.f, calculates the associated legendre function for degree m, order n, and parameter x. The output is the function value pm and the value of the derivative pd. This function is from the book "Computation of Special Functions." by Shanjie Zhang, and Jianming Jin, New York : Wiley, c1996. These examples are in the examples directory. SUBROUTINE LPMNS(M,N,X,PM,PD) c************************************************************** C C ======================================================== C Purpose: Compute associated Legendre functions Pmn(x) C and Pmn'(x) for a given order C Input : x --- Argument of Pmn(x) C m --- Order of Pmn(x), m = 0,1,2,...,n C n --- Degree of Pmn(x), n = 0,1,2,...,N C Output: PM(n) --- Pmn(x) C PD(n) --- Pmn'(x) C ======================================================== C IMPLICIT DOUBLE PRECISION (A-H,O-Z) DIMENSION PM(0:N),PD(0:N) DO 10 K=0,N PM(K)=0.0D0 10 PD(K)=0.0D0 IF (DABS(X).EQ.1.0D0) THEN DO 15 K=0,N IF (M.EQ.0) THEN PM(K)=1.0D0 PD(K)=0.5D0*K*(K+1.0) IF (X.LT.0.0) THEN PM(K)=(-1)**K*PM(K) PD(K)=(-1)**(K+1)*PD(K) ENDIF ELSE IF (M.EQ.1) THEN PD(K)=1.0D+300 ELSE IF (M.EQ.2) THEN PD(K)=-0.25D0*(K+2.0)*(K+1.0)*K*(K-1.0) IF (X.LT.0.0) PD(K)=(-1)**(K+1)*PD(K) ENDIF 15 CONTINUE RETURN ENDIF X0=DABS(1.0D0-X*X) PM0=1.0D0 PMK=PM0 DO 20 K=1,M PMK=(2.0D0*K-1.0D0)*DSQRT(X0)*PM0 20 PM0=PMK PM1=(2.0D0*M+1.0D0)*X*PM0 PM(M)=PMK PM(M+1)=PM1 DO 25 K=M+2,N PM2=((2.0D0*K-1.0D0)*X*PM1-(K+M-1.0D0)*PMK)/(K-M) PM(K)=PM2 PMK=PM1 25 PM1=PM2 PD(0)=((1.0D0-M)*PM(1)-X*PM(0))/(X*X-1.0) DO 30 K=1,N 30 PD(K)=(K*X*PM(K)-(K+M)*PM(K-1))/(X*X-1.0D0) RETURN END As this is fortran77, we use to_f90 to get lpmns.f90: SUBROUTINE lpmns(m,n,x,pm,pd) ! Code converted using TO_F90 by Alan Miller ! Date: 2002-05-14 Time: 13:32:33 !************************************************************** ! ======================================================== ! Purpose: Compute associated Legendre functions Pmn(x) ! and Pmn'(x) for a given order ! Input : x --- Argument of Pmn(x) ! m --- Order of Pmn(x), m = 0,1,2,...,n ! n --- Degree of Pmn(x), n = 0,1,2,...,N ! Output: PM(n) --- Pmn(x) ! PD(n) --- Pmn'(x) ! ======================================================== INTEGER, INTENT(IN) :: m INTEGER, INTENT(IN) :: n DOUBLE PRECISION, INTENT(IN) :: x DOUBLE PRECISION, INTENT(OUT) :: pm(0:n) DOUBLE PRECISION, INTENT(OUT) :: pd(0:n) IMPLICIT DOUBLE PRECISION (a-h,o-z) DO k=0,n pm(k)=0.0D0 pd(k)=0.0D0 END DO IF (DABS(x) == 1.0D0) THEN DO k=0,n IF (m == 0) THEN pm(k)=1.0D0 pd(k)=0.5D0*k*(k+1.0) IF (x < 0.0) THEN pm(k)=(-1)**k*pm(k) pd(k)=(-1)**(k+1)*pd(k) END IF ELSE IF (m == 1) THEN pd(k)=1.0D+300 ELSE IF (m == 2) THEN pd(k)=-0.25D0*(k+2.0)*(k+1.0)*k*(k-1.0) IF (x < 0.0) pd(k)=(-1)**(k+1)*pd(k) END IF END DO RETURN END IF x0=DABS(1.0D0-x*x) pm0=1.0D0 pmk=pm0 DO k=1,m pmk=(2.0D0*k-1.0D0)*DSQRT(x0)*pm0 pm0=pmk END DO pm1=(2.0D0*m+1.0D0)*x*pm0 pm(m)=pmk pm(m+1)=pm1 DO k=m+2,n pm2=((2.0D0*k-1.0D0)*x*pm1-(k+m-1.0D0)*pmk)/(k-m) pm(k)=pm2 pmk=pm1 pm1=pm2 END DO pd(0)=((1.0D0-m)*pm(1)-x*pm(0))/(x*x-1.0) DO k=1,n pd(k)=(k*x*pm(k)-(k+m)*pm(k-1))/(x*x-1.0D0) END DO RETURN END SUBROUTINE lpmns Now we convert this to a Matlab function lpmns.m: >> f2matlab('lpmns.f90'); subroutine lpmns(m,n,x,pm,pd) Number of lines: 70 Writing file: lpmns.m ... completed Total time: 0.58333 >> Resulting in lpmns.m: function [m,n,x,pm,pd]=lpmns(m,n,x,pm,pd); %************************************************************** % ======================================================== % Purpose: Compute associated Legendre functions Pmn(x) % and Pmn'(x) for a given order % Input : x --- Argument of Pmn(x) % m --- Order of Pmn(x), m = 0,1,2,...,n % n --- Degree of Pmn(x), n = 0,1,2,...,N % Output: PM(n) --- Pmn(x) % PD(n) --- Pmn'(x) % ======================================================== for k=0:n; pm(k+1)=0.0d0; pd(k+1)=0.0d0; end; if (abs(x) == 1.0d0); for k=0:n; if (m == 0); pm(k+1)=1.0d0; pd(k+1)=0.5d0.*k.*(k+1.0); if (x < 0.0); pm(k+1)=(-1).^k.*pm(k+1); pd(k+1)=(-1).^(k+1).*pd(k+1); end; elseif (m == 1); pd(k+1)=1.0d+300; elseif (m == 2); pd(k+1)=-0.25d0.*(k+2.0).*(k+1.0).*k.*(k-1.0); if (x < 0.0) pd(k+1)=(-1).^(k+1).*pd(k+1); end; end; end; return; end; x0=abs(1.0d0-x.*x); pm0=1.0d0; pmk=pm0; for k=1:m; pmk=(2.0d0.*k-1.0d0).*sqrt(x0).*pm0; pm0=pmk; end; pm1=(2.0d0.*m+1.0d0).*x.*pm0; pm(m+1)=pmk; pm(m+1+1)=pm1; for k=m+2:n; pm2=((2.0d0.*k-1.0d0).*x.*pm1-(k+m-1.0d0).*pmk)./(k-m); pm(k+1)=pm2; pmk=pm1; pm1=pm2; end; pd(0+1)=((1.0d0-m).*pm(1+1)-x.*pm(0+1))./(x.*x-1.0); for k=1:n; pd(k+1)=(k.*x.*pm(k+1)-(k+m).*pm(k-1+1))./(x.*x-1.0d0); end; Now we can run lpmns.m: >> [a1,a2,a3,pm,pd]=lpmns(0,10,.5) a1 = 0 a2 = 10 a3 = 0.5 pm = Columns 1 through 4 1 0.5 -0.125 -0.4375 Columns 5 through 8 -0.2890625 0.08984375 0.3232421875 0.22314453125 Columns 9 through 11 -0.073638916015625 -0.267898559570312 -0.188228607177734 pd = Columns 1 through 4 0 1 1.5 0.375 Columns 5 through 8 -1.5625 -2.2265625 -0.57421875 1.9755859375 Columns 9 through 11 2.77294921875 0.723724365234375 -2.31712341308594 >> Incidentally, it is now possible to convert lpmns.m into a fortran90 mex file callable from Matlab using matlab2fmex.m. (See http://matlab2fmex.sourceforge.net/ ) First, construct another input which is the same size as the output. Here is the modified lpmns2.m function [pm,pd]=lpmns(m,n,x,outsize) %************************************************************** % ======================================================== % Purpose: Compute associated Legendre functions Pmn(x) % and Pmn'(x) for a given order % Input : x --- Argument of Pmn(x) % m --- Order of Pmn(x), m = 0,1,2,...,n % n --- Degree of Pmn(x), n = 0,1,2,...,N % Output: PM(n) --- Pmn(x) % PD(n) --- Pmn'(x) % ======================================================== for k=0:n; pm(k+1)=0.0d0; pd(k+1)=0.0d0; end; if (abs(x) == 1.0d0); for k=0:n; if (m == 0); pm(k+1)=1.0d0; pd(k+1)=0.5d0.*k.*(k+1.0); if (x < 0.0); pm(k+1)=(-1).^k.*pm(k+1); pd(k+1)=(-1).^(k+1).*pd(k+1); end; elseif (m == 1); pd(k+1)=1.0d+300; elseif (m == 2); pd(k+1)=-0.25d0.*(k+2.0).*(k+1.0).*k.*(k-1.0); if (x < 0.0) pd(k+1)=(-1).^(k+1).*pd(k+1); end; end; end; return; end; x0=abs(1.0d0-x.*x); pm0=1.0d0; pmk=pm0; for k=1:m; pmk=(2.0d0.*k-1.0d0).*sqrt(x0).*pm0; pm0=pmk; end; pm1=(2.0d0.*m+1.0d0).*x.*pm0; pm(m+1)=pmk; pm(m+1+1)=pm1; for k=m+2:n; pm2=((2.0d0.*k-1.0d0).*x.*pm1-(k+m-1.0d0).*pmk)./(k-m); pm(k+1)=pm2; pmk=pm1; pm1=pm2; end; pd(0+1)=((1.0d0-m).*pm(1+1)-x.*pm(0+1))./(x.*x-1.0); for k=1:n; pd(k+1)=(k.*x.*pm(k+1)-(k+m).*pm(k-1+1))./(x.*x-1.0d0); end; Now create a lpmns.mat file using matlab2fmex_save: >> n=10;matlab2fmex_save('[x,w]=lpmns2(0,n,.5,zeros(1,n+1));'); And now convert lpmns.m to a fortran90 mex file: >> matlab2fmex('lpmns2'); Converting --- lpmns2.m ==> lpmns2.f ==> lpmns2.mex matlab2fmex. ==> mex lpmns2.f mexfunctions.f mexoperators.f mexcallback.f >> Finally, we can call lpmns2 as a mex file from the Matlab command prompt: >> [pm,pd]=lpmns2(0,n,.5,zeros(1,n+1)) pm = Columns 1 through 3 1 0.5 -0.125 Columns 4 through 6 -0.4375 -0.2890625 0.08984375 Columns 7 through 9 0.3232421875 0.22314453125 -0.073638916015625 Columns 10 through 11 -0.267898559570312 -0.188228607177734 pd = Columns 1 through 3 0 1 1.5 Columns 4 through 6 0.375 -1.5625 -2.2265625 Columns 7 through 9 -0.57421875 1.9755859375 2.77294921875 Columns 10 through 11 0.723724365234375 -2.31712341308594 >> >> which lpmns2 /home/barrowes/compiler/f2matlab/examples/lpmns2.mexaxp >> We have just converted a native fortran77 subroutine into a fortran90 mex file usable (with variable sized inputs) in Matlab. lqmns.f in the examples directory can be handles similarly. As another example, let's follow the same procedure with dgauleg.f, a subroutine which calculates gaussian quadrature coefficients. SUBROUTINE dgauleg(x1,x2,x,w,n) c---------------------------------------------------------------- INTEGER n real*8 x1,x2,x(n),w(n) real*8 EPS PARAMETER (EPS=3.d-14) INTEGER i,j,m real*8 p1,p2,p3,pp,xl,xm,z,z1 m=(n+1)/2 z1=huge(1.0) xm=0.5d0*(x2+x1) xl=0.5d0*(x2-x1) do 12 i=1,m z=cos(3.141592654d0*(i-.25d0)/ & (n+.5d0)) do while (abs(z-z1).gt.EPS) p1=1.d0 p2=0.d0 do 11 j=1,n p3=p2 p2=p1 p1=((2.d0*j-1.d0)*z*p2-(j-1.d0)*p3)/j 11 continue pp=n*(z*p1-p2)/(z*z-1.d0) z1=z z=z1-p1/pp end do x(i)=xm-xl*z x(n+1-i)=xm+xl*z w(i)=2.d0*xl/((1.d0-z*z)*pp*pp) w(n+1-i)=w(i) 12 continue return end Now convert to fortran90 SUBROUTINE dgauleg(x1,x2,x,w,n) ! Code converted using TO_F90 by Alan Miller ! Date: 2002-05-14 Time: 13:40:52 !---------------------------------------------------------------- REAL*8, INTENT(IN OUT) :: x1 REAL*8, INTENT(IN OUT) :: x2 REAL*8, INTENT(OUT) :: x(n) REAL*8, INTENT(OUT) :: w(n) INTEGER, INTENT(IN) :: n REAL*8 REAL*8, PARAMETER :: eps=3.d-14 INTEGER :: i,j,m REAL*8 p1,p2,p3,pp,xl,xm,z,z1 m=(n+1)/2 z1=huge(1.0) xm=0.5D0*(x2+x1) xl=0.5D0*(x2-x1) DO i=1,m z=COS(3.141592654D0*(i-.25D0)/ (n+.5D0)) DO WHILE (ABS(z-z1) > eps) p1=1.d0 p2=0.d0 DO j=1,n p3=p2 p2=p1 p1=((2.d0*j-1.d0)*z*p2-(j-1.d0)*p3)/j END DO pp=n*(z*p1-p2)/(z*z-1.d0) z1=z z=z1-p1/pp END DO x(i)=xm-xl*z x(n+1-i)=xm+xl*z w(i)=2.d0*xl/((1.d0-z*z)*pp*pp) w(n+1-i)=w(i) END DO RETURN END SUBROUTINE dgauleg And now to dgauleg.m >> f2matlab('dgauleg.f90'); subroutine dgauleg(x1,x2,x,w,n) Number of lines: 44 No Matlab function for 'huge' except replacing with 'realmax' in Matlab Writing file: dgauleg.m ... completed Total time: 0.35 >> Resulting dgauleg.m: function [x1,x2,x,w,n]=dgauleg(x1,x2,x,w,n); %---------------------------------------------------------------- eps=3.d-14; m=(n+1)./2; z1=realmax(1.0); xm=0.5d0.*(x2+x1); xl=0.5d0.*(x2-x1); for i=1:m; z=cos(3.141592654d0.*(i-.25d0)./ (n+.5d0)); while (abs(z-z1) > eps); p1=1.d0; p2=0.d0; for j=1:n; p3=p2; p2=p1; p1=((2.d0.*j-1.d0).*z.*p2-(j-1.d0).*p3)./j; end; pp=n.*(z.*p1-p2)./(z.*z-1.d0); z1=z; z=z1-p1./pp; end; x(i)=xm-xl.*z; x(n+1-i)=xm+xl.*z; w(i)=2.d0.*xl./((1.d0-z.*z).*pp.*pp); w(n+1-i)=w(i); end; And now we can call it from Matlab: >> [x,w]=dgauleg(0,1,0,1,10) x = 0 w = 1 >> [x1,x2,x,w,n]=dgauleg(0,1,0,1,10) x1 = 0 x2 = 1 x = Columns 1 through 4 0.0130467357414142 0.0674683166555077 0.160295215850488 0.283302302935376 Columns 5 through 8 0.425562830509184 0.574437169490816 0.716697697064624 0.839704784149512 Columns 9 through 10 0.932531683344492 0.986953264258586 w = Columns 1 through 4 0.0333356721543414 0.0747256745752903 0.109543181257991 0.134633359654996 Columns 5 through 8 0.147762112357376 0.147762112357376 0.134633359654996 0.109543181257991 Columns 9 through 10 0.0747256745752903 0.0333356721543414 n = 10 >> Finally, here is an example which converts a fortran90 program with subroutines into Matlab. The program is MCPBDN.for from the book "Computation of Special Functions." by Shanjie Zhang, and Jianming Jin, New York : Wiley, c1996. After using to_f90 on this file, the only alteration was to specify the inputs x and y in the code instead of using a read statement. See the /examples directory. Converting: >> f2matlab('mcpbdn.f90'); program mcpbdn Number of lines: 61 subroutine cpbdn(n,z,cpb,cpd) Number of lines: 103 subroutine cpdsa(n,z,cdn) Number of lines: 57 subroutine cpdla(n,z,cdn) Number of lines: 30 subroutine gaih(x,ga) Number of lines: 29 Writing file: mcpbdn.m ... completed Total time: 2.75 >> We can now try it out: >> mcpbdn ans = please enter n, x and y ans = n re[dn(z)] im[dn(z)] ans = re[dn'(z)] im[dn'(z)] ans = ------------------------------------------- ans = ------------------------- i = 0 ans = 0.997798279178581 + 0.0663218973512007i ans = -2.32869095456845 - 2.66030044132445i i = 1 ans = 4.6573819091369 + 5.32060088264891i ans = 2.6558457129586 - 24.8786350821133i i = 2 ans = -4.31389314673862 + 49.8235920615778i ans = 144.658476839065 - 103.1330455218i i = 3 ans = -280.002189859856 + 216.907292808898i ans = 1229.33202723167 + 307.208018812128i i = 4 ans = -2471.60573390356 - 464.945261439523i ans = 3896.64242172066 + 8209.00665959329i i = 5 ans = -8913.29360288074 - 15550.384147951i ans = -28950.7550321934 + 58834.4680698817i >> Which agrees with the values produced by the original code. 8. REVISION HISTORY: See changelog
Source: README, updated 2017-04-04

Thanks for helping keep SourceForge clean.

Screenshot instructions:
Windows
Mac
Red Hat Linux   Ubuntu

Click URL instructions:
Right-click on ad, choose "Copy Link", then paste here →
(This may not be possible with some types of ads)

More information about our ad policies
X

Briefly describe the problem (required):

Upload screenshot of ad (required):
Select a file, or drag & drop file here.

Please provide the ad click URL, if possible:

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.

No, thanks