Julia转译Fortran77代码遇MethodError:Float64不可调用求助
Julia转译Fortran77代码时遇到MethodError问题
我正在学习Julia语言,尝试将Fortran77代码转译为Julia代码,但遇到了如下错误提示,无法定位问题所在:
using DelimitedFiles, DataFrames function diprcbk(iii,x,r) if iii==0 df = DataFrame(readdlm("dipgbw800hp.dat"), [:ya,:xa, :ra, :da]) ya1=[] xa1=[] for ix in 1:801:370863 YA1 = df.ya[ix] XA1 = df.xa[ix] append!(ya1, YA1) append!(xa1, XA1) end ya=[] xa=[] da=[] ra=[] ral=[] for ix in 1:1:463 XA=xa1[ix] YA=ya1[ix] append!(ya, YA) append!(xa, XA) DA=df[df.ya .== ya[ix], :da] push!(da, DA) for ir in 1:1:801 RA = df.ra[ir] RAL=log(RA) append!(ra, RA) append!(ral, RAL) end end end if iii==1 df = DataFrame(readdlm("dipmv800hp.dat"), [:ya,:xa, :ra, :da]) ya1=[] xa1=[] for ix in 1:801:370863 YA1 = df.ya[ix] XA1 = df.xa[ix] append!(ya1, YA1) append!(xa1, XA1) end end ya=[] xa=[] da=[] ra=[] ral=[] for ix in 1:1:463 XA=xa1[ix] YA=ya1[ix] append!(ya, YA) append!(xa, XA) DA=df[df.ya .== ya[ix], :da] push!(da, DA) for ir in 1:1:801 RA = df.ra[ir] RAL=log(RA) append!(ra, RA) append!(ral, RAL) end end if r < ra[1] return 0 #####Maybe the error is somewhere here?##### elseif r>= ra[1] && r<=ra[801] y = float(log((xa[1])/x)) for ix in 1:1:(length(ya)-1) if y>ya[ix] && y<ya[ix+1] indx=ix for ir in 1:1:(802-1) if r>ra[ir] && r<ra[ir + 1] indr=ir rl = log(r) function xlinter(x1,x2,y1,y2,x) xlinter = float((y2-y1)*(x-x1)/(x2-x1)+y1) return xlinter end dindr=xlinter(ya[indx],ya[indx+1],da[indx][indr],da[indx+1][indr],y) dindrp1=xlinter(ya[indx],ya[indx+1],da[indx][indr+1],da[indx+1][indr+1],y) diprcbk=xlinter(ral[indr],ral[indr+1],dindr,dindrp1,rl) return diprcbk end end end end ############################################ elseif r>ra[801] return 1 end end MV=[] GBW=[] R=[] for i in -90:1:20 r=10^((0.1)*i) aaa=diprcbk(0, 10^(-4), r) bbb=diprcbk(1, 10^(-4), r) append!(R, r) append!(GBW, aaa) append!(MV, bbb) end
错误提示:
MethodError: objects of type Float64 are not callable
Maybe you forgot to use an operator such as *, ^, %, / etc. ?
Stacktrace:
[1] diprcbk(iii::Int64, x::Float64, r::Float64)
@ Main .\In[25]:94
[2] top-level scope
@ .\In[26]:6
[3] eval
@ .\boot.jl:368 [inlined]
[4] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String,
filename::String)
@ Base .\loading.jl:1428
问题原因
错误根源在第94行的diprcbk=xlinter(...):你把当前函数的名称diprcbk赋值成了xlinter返回的浮点数(Float64类型)。当后续代码(比如循环的下一次迭代,或者第二次调用diprcbk函数)尝试执行函数调用逻辑时,Julia会误以为diprcbk是可调用的函数,但它已经变成了一个浮点数,因此抛出"Float64不可调用"的错误。
修复方案
- 避免使用函数名作为变量名:把
diprcbk=xlinter(...)改为其他变量名,比如result=xlinter(...),然后return result。 - 将辅助函数移到循环外部:
xlinter定义在嵌套循环内部会导致每次循环都重新编译,严重影响性能。建议把它移到diprcbk函数外部:
function xlinter(x1,x2,y1,y2,x) return float((y2-y1)*(x-x1)/(x2-x1)+y1) end function diprcbk(iii,x,r) # 原函数内容... end
- 初始化数组时指定类型:替换
ya1=[]这类空数组初始化方式,改为ya1=Float64[],减少类型不稳定带来的性能损耗。 - 修正数据索引问题:
df[df.ya .== ya[ix], :da]返回的是DataFrame的一列而非单个数值,后续da[indx][indr]会出现索引错误。需要改为first(df[df.ya .== ya[ix], :da])或df[df.ya .== ya[ix], :da][1]来获取单个值。
修复后的核心代码片段示例:
# 把xlinter移到外部 function xlinter(x1,x2,y1,y2,x) return float((y2-y1)*(x-x1)/(x2-x1)+y1) end function diprcbk(iii,x,r) # 原代码的初始化部分... elseif r>= ra[1] && r<=ra[801] y = float(log((xa[1])/x)) for ix in 1:(length(ya)-1) if y>ya[ix] && y<ya[ix+1] indx=ix for ir in 1:(801) if r>ra[ir] && r<ra[ir + 1] indr=ir rl = log(r) dindr=xlinter(ya[indx],ya[indx+1],da[indx][indr],da[indx+1][indr],y) dindrp1=xlinter(ya[indx],ya[indx+1],da[indx][indr+1],da[indx+1][indr+1],y) result=xlinter(ral[indr],ral[indr+1],dindr,dindrp1,rl) return result end end end end end # 其余代码... end
内容的提问来源于stack exchange,提问作者Henrique
相关产品推荐
相关产品推荐

