[英]Fortran to Matlab confused to if statement
我必須將fortran程序轉換為matlab,我遇到了問題。 雖然當我運行matlab腳本時,fortran結果是正確的。 我認為問題出在第一個IF聲明中。 我錯過了matlab轉換的內容嗎? 提前致謝。
這是完整的程序,在Fortran和Matlab中都有結果。 最新版本是@Rotem的解決方案。 我也試圖將修復添加到f1和f2,因為@BenBarrowes提到但是程序再次陷入困境。 提前致謝 :)
Fortran版本
program asxm_2
implicit none
real(8) a,b, par1, sum,sum1,sum2, x,x1,x2, h, f,fa,fb,f1,f2,par2,e
integer n,j,y,k
real(8), allocatable, dimension (:) :: partitionS, valueS, errorS
a=0.
b=5.+85
par1=100*(atan(b)-atan(a))
fa=100/(1+a**2)
fb=100/(1+b**2)
print*, 'METHOD SIMPSON'
do n=1,1000000
h=(b-a)/n
sum1=0.
sum2=0.
x1=a
x2=a
do j=1,n-1
k=j
if(k/2/=j/2.) then
if(j==1) x1=x1+h
if(j>1) x1=x1+2*h
f1=100/(1+x1**2)
sum1=sum1+f1
else
x2=x2+2*h
f2=100/(1+x2**2)
sum2=sum2+f2
endif
enddo
par2= (h/3)*(fa+4*sum1+2*sum2+fb)
e=par1-par2
if(abs(e)<=0.001) exit
enddo
y=n
allocate(partitionS(y),valueS(y), errorS(y))
do n=1,y
h=(b-a)/n
sum1=0.
sum2=0.
x1=a
x2=a
do j=1,n-1
k=j
if(k/2==j/2.) then
x2=x2+2*h
f2=100/(1+x2**2)
sum2=sum2+f2
else
if(j==1) x1=x1+h
if(j>1) x1=x1+2*h
f1=100/(1+x1**2)
sum1=sum1+f1
endif
enddo
partitionS(n)=n
valueS(n)= (h/3)*(fa+4*sum1+2*sum2+fb)
errorS(n)=par1-valueS(n)
enddo
print*, 'Below are the results'
print*, partitionS(y), valueS(y), errorS(y)
deallocate(partitionS, valueS, errorS)
end
Fortran結果
Below are the results
332.00000000000000 155.96759681601489 9.7047371403391480E-004
Matlab版
a = 0;
b = 5.+85;
par1 = 100*(atan(b)-atan(a));
fa = 100/(1+a.^2);
fb = 100/(1+b.^2);
fprintf('METHOD SIMPSON\n');
for n = 1:1000000
h=(b-a)/n;
sum1=0;
sum2=0;
x1 = a;
x2 = a;
for j = 1:n-1
k = j;
if fix(k/2) ~= j/2
if j == 1
x1 = x1+h;
end
if j > 1
x1 = x1+2*h;
end
f1 = 100/(1+x1.^2);
sum1 = sum1 + f1;
else
x2 = x2+2*h;
f2 = 100/(1+x2.^2);
sum2 = sum2 + f2;
end
end
par2 = (h/3)*(fa+4*sum1+2*sum2+fb);
e = par1 - par2;
if abs(e)<0.001
break;
end
end
y=n;
partitionS = zeros (n);
valueS= zeros (n);
errorS = zeros (n);
for n = 1:y
h=(b-a)/n;
sum1=0;
sum2=0;
x1=a;
x2=a;
for j = 1:n-1
k = j;
if fix(k/2) == j/2
x2 = x2 + 2*h;
f2 = 100/(1+x2.^2);
sum2 = sum2 + f2;
else
if j == 1
x1 = x1 + h;
end
if j > 1
x1 = x1 + 2*h;
end
f1 = 100/(1+x2.^2);
sum1 = sum1 + f1;
end
end
partitionS(n) = n;
valueS(n)= (h/3)*(fa+4*sum1+2*sum2+fb);
errorS(n)=par1-valueS(n);
end
fprintf('Below are the results\n');
fprintf('%.25f\n',partitionS(n));
fprintf('%.25f\n',valueS(n));
fprintf('%.25f\n',errorS(n));
MATLAB結果
Below are the results
332.0000000000000000000000000
174.0415303853845900000000000
-18.0729630956556660000000000
就像francescalus評論的那樣,看起來問題與Fortran中的整數運算有關。
您可以在Matlab實現中修改第一個if
語句,如下所示:
if fix(k/2) ~= j/2
在第二部分中,Matlab代碼中存在拼寫錯誤。
你寫了x2
而不是x1
。
正確的代碼:
f1 = 100/(1+x1.^2); %Instead of f1 = 100/(1+x2.^2);
輕微缺陷:
if abs(e)<=0.001 %Instead of if abs(e)<0.001
我知道非常基本的Fortran,所以我並排執行了Matlab和Fortran代碼版本。
我使用調試器逐步執行代碼。
我使用了一些任意輸入值。
問題與第一個Fortran if
語句有關: (k/2/=j/2.)
當k
是整數時, k/2
評估為floor(k/2)
,並且j/2.
評估浮點(假設k
為正)。
(我使用修復 Matlab函數,如果k
也可以是負數)。
例:
integer j, k
j=3
k=3
print *, k/2
print *, j/2.
print *, k/2/=j/2.
結果:
1
1.500000
T
在Matlab中,默認類型是double。
j=3;
k=3;
disp(k/2)
disp(j/2)
disp(k/2 ~= j/2)
結果:
1.5000
1.5000
0
正如您所看到的,在Fortran條件中,計算結果為true ,而在Matlab中則為false 。
完整的Matlab代碼:
a = 0;
b = 5.+85;
par1 = 100*(atan(b)-atan(a));
fa = 100/(1+a.^2);
fb = 100/(1+b.^2);
fprintf('METHOD SIMPSON\n');
for n = 1:1000000
h=(b-a)/n;
sum1=0;
sum2=0;
x1 = a;
x2 = a;
for j = 1:n-1
k = j;
if fix(k/2) ~= j/2
if j == 1
x1 = x1+h;
end
if j > 1
x1 = x1+2*h;
end
f1 = 100/(1+x1.^2);
sum1 = sum1 + f1;
else
x2 = x2+2*h;
f2 = 100/(1+x2.^2);
sum2 = sum2 + f2;
end
end
par2 = (h/3)*(fa+4*sum1+2*sum2+fb);
e = par1 - par2;
if abs(e)<=0.001
break;
end
end
y=n;
partitionS = zeros (n);
valueS= zeros (n);
errorS = zeros (n);
for n = 1:y
h=(b-a)/n;
sum1=0;
sum2=0;
x1=a;
x2=a;
for j = 1:n-1
k = j;
if fix(k/2) == j/2
x2 = x2 + 2*h;
f2 = 100/(1+x2.^2);
sum2 = sum2 + f2;
else
if j == 1
x1 = x1 + h;
end
if j > 1
x1 = x1 + 2*h;
end
f1 = 100/(1+x1.^2);%f1 = 100/(1+x2.^2);
sum1 = sum1 + f1;
end
end
partitionS(n) = n;
valueS(n)= (h/3)*(fa+4*sum1+2*sum2+fb);
errorS(n)=par1-valueS(n);
end
fprintf('Below are the results\n');
fprintf('%.25f\n',partitionS(n));
fprintf('%.25f\n',valueS(n));
fprintf('%.25f\n',errorS(n));
Matlab輸出:
METHOD SIMPSON
Below are the results
332.0000000000000000000000000
155.9675968160148900000000000
0.0009704737140339148000000
我根據你的帖子做了一個小的fortran程序。 然后把它通過我的f2matlab fortran源碼到matlab源碼轉換器(matlab文件交換)。 這是fortran:
program kt_f
implicit none
integer j,n,k,f1,f2
real x1,x2,h,sum1,sum2
n=100
k=50
do j=1,n-1
k=j
if(k/2/=j/2.) then
if(j==1) x1=x1+h
if(j>1) x1=x1+2*h
f1=100/(1+x1**2)
sum1=sum1+f1
else
x2=x2+2*h
f2=100/(1+x2**2)
sum2=sum2+f2
endif
enddo
print *,'sum1=',sum1
print *,'sum2=',sum2
end program kt_f
當我編譯並運行它時,輸出是:
sum1= 5000.000
sum2= 4900.000
這是matlab源碼的產生。 請注意,除了if語句中的fix
之外,還需要在100 /行中進行另一個fix
,因為這也是一個整數除法。 這是matlab代碼:
function kt_f(varargin)
clear global; clear functions;
global GlobInArgs nargs
GlobInArgs={mfilename,varargin{:}}; nargs=nargin+1;
persistent f1 f2 h_fv j k n sum1 sum2 x1 x2 ;
if isempty(f1), f1=0; end;
if isempty(f2), f2=0; end;
if isempty(h_fv), h_fv=0; end;
if isempty(j), j=0; end;
if isempty(k), k=0; end;
if isempty(n), n=0; end;
if isempty(sum1), sum1=0; end;
if isempty(sum2), sum2=0; end;
if isempty(x1), x1=0; end;
if isempty(x2), x2=0; end;
n = 100;
k = 50;
for j = 1: n - 1;
k = fix(j);
if(fix(k./2) ~= (j./2.));
if(j == 1);
x1 = x1 + h_fv;
end;
if(j > 1);
x1 = x1 + 2.*h_fv;
end;
f1 = fix(100./(1+x1.^2));
sum1 = sum1 + f1;
else;
x2 = x2 + 2.*h_fv;
f2 = fix(100./(1+x2.^2));
sum2 = sum2 + f2;
end;
end;
'sum1=',sum1
'sum2=',sum2
end %program kt_f
這提供了與fortran相同的輸出。 請檢查並確定這是否解決了您的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.