编译 NLopt Fortran 示例代码时出现语法错误
Syntax error in compiling NLopt Fortran example code
我正在使用 Simply Fortran(gfortran 编译器)练习来自 http://ab-initio.mit.edu/wiki/index.php/NLopt_Tutorial 的 NLopt 示例。
NLopt 库包含 libnlopt-0.def、linlopt-0.dll(用 c 编写)和 nlopt.f。这是我的主程序 test.f
program main
external myfunc, myconstraint
double precision lb(2)
integer*8 opt
double precision d1(2), d2(2)
double precision x(2), minf
integer ires
include 'nlopt.f'
opt=0
call nlo_create(opt, NLOPT_LD_MMA, 2)
call nlo_get_lower_bounds(ires, opt, lb)
lb(2) = 0.0
call nlo_set_lower_bounds(ires, opt, lb)
call nlo_set_min_objective(ires, opt, myfunc, 0)
d1(1) = 2.
d1(2) = 0.
call nlo_add_inequality_constraint(ires, opt, myconstraint,
$ d1, 1.D-8)
d2(1) = -1.
d2(2) = 1.
call nlo_add_inequality_constraint(ires, opt, myconstraint,
$ d2, 1.D-8)
call nlo_set_xtol_rel(ires, opt, 1.D-4)
x(1) = 1.234
x(2) = 5.678
call nlo_optimize(ires, opt, x, minf)
if (ires.lt.0) then
write(*,*) 'nlopt failed!'
else
write(*,*) 'found min at ', x(1), x(2)
write(*,*) 'min val = ', minf
endif
call nlo_destroy(opt)
end
subroutine myfunc(val, n, x, grad, need_gradient, f_data)
double precision val, x(n), grad(n)
integer n, need_gradient
if (need_gradient.ne.0) then
grad(1) = 0.0
grad(2) = 0.5 / dsqrt(x(2))
endif
val = dsqrt(x(2))
end
subroutine myconstraint(val, n, x, grad, need_gradient, d)
integer need_gradient
double precision val, x(n), grad(n), d(2), a, b
a = d(1)
b = d(2)
if (need_gradient.ne.0) then
grad(1) = 3. * a * (a*x(1) + b)**2
grad(2) = -1.0
endif
val = (a*x(1) + b)**3 - x(2)
end
它是用 Fortran 77 编写的,每行有 6 个缩进。构建文件出现此错误:
"C:\Program Files (x86)\Simply Fortran\mingw-w64\bin\gfortran.exe" -c -o "build\test.o" -g -m32 -Jmodules ".\test.f"
.\test.f:19.72:
call nlo_add_inequality_constraint(ires, opt, myconstraint, d1, 1.
1
Error: Syntax error in argument list at (1)
.\test.f:22.72:
call nlo_add_inequality_constraint(ires, opt, myconstraint, d2, 1.
1
Error: Syntax error in argument list at (1)
Error(E42): Last command making (build\test.o) returned a bad status
Error(E02): Make execution terminated
但是,调用 nlo_add_inequality_constraint 具有正确的参数数量,由 NLopt 引用指示:
call nlo_add_inequality_constraint(ires, opt, fc, fc_data, tol)
谁能知道这是怎么回事?非常感谢!
该错误表明参数列表中存在语法错误,而不是过程调用中的不匹配。原因是您的行跨越了 2 个源代码行,并且您的续行符没有正确放置。您表示您的代码全部缩进了 6 space,但是第 20 行和第 23 行的两个续行必须在第 6 列中具有续行字符。
编辑行:
call nlo_add_inequality_constraint(ires, opt, myconstraint,
$ d1, 1.D-8)
d2(1) = -1.
d2(2) = 1.
call nlo_add_inequality_constraint(ires, opt, myconstraint,
$ d2, 1.D-8)
至:
call nlo_add_inequality_constraint(ires, opt, myconstraint,
$ d1, 1.D-8)
d2(1) = -1.
d2(2) = 1.
call nlo_add_inequality_constraint(ires, opt, myconstraint,
$ d2, 1.D-8)
第 6 列中除 space 或零以外的任何字符的存在表示该行是上一行的延续(请参阅 3.3.3.3 Fortran 2008)。
我正在使用 Simply Fortran(gfortran 编译器)练习来自 http://ab-initio.mit.edu/wiki/index.php/NLopt_Tutorial 的 NLopt 示例。 NLopt 库包含 libnlopt-0.def、linlopt-0.dll(用 c 编写)和 nlopt.f。这是我的主程序 test.f
program main
external myfunc, myconstraint
double precision lb(2)
integer*8 opt
double precision d1(2), d2(2)
double precision x(2), minf
integer ires
include 'nlopt.f'
opt=0
call nlo_create(opt, NLOPT_LD_MMA, 2)
call nlo_get_lower_bounds(ires, opt, lb)
lb(2) = 0.0
call nlo_set_lower_bounds(ires, opt, lb)
call nlo_set_min_objective(ires, opt, myfunc, 0)
d1(1) = 2.
d1(2) = 0.
call nlo_add_inequality_constraint(ires, opt, myconstraint,
$ d1, 1.D-8)
d2(1) = -1.
d2(2) = 1.
call nlo_add_inequality_constraint(ires, opt, myconstraint,
$ d2, 1.D-8)
call nlo_set_xtol_rel(ires, opt, 1.D-4)
x(1) = 1.234
x(2) = 5.678
call nlo_optimize(ires, opt, x, minf)
if (ires.lt.0) then
write(*,*) 'nlopt failed!'
else
write(*,*) 'found min at ', x(1), x(2)
write(*,*) 'min val = ', minf
endif
call nlo_destroy(opt)
end
subroutine myfunc(val, n, x, grad, need_gradient, f_data)
double precision val, x(n), grad(n)
integer n, need_gradient
if (need_gradient.ne.0) then
grad(1) = 0.0
grad(2) = 0.5 / dsqrt(x(2))
endif
val = dsqrt(x(2))
end
subroutine myconstraint(val, n, x, grad, need_gradient, d)
integer need_gradient
double precision val, x(n), grad(n), d(2), a, b
a = d(1)
b = d(2)
if (need_gradient.ne.0) then
grad(1) = 3. * a * (a*x(1) + b)**2
grad(2) = -1.0
endif
val = (a*x(1) + b)**3 - x(2)
end
它是用 Fortran 77 编写的,每行有 6 个缩进。构建文件出现此错误:
"C:\Program Files (x86)\Simply Fortran\mingw-w64\bin\gfortran.exe" -c -o "build\test.o" -g -m32 -Jmodules ".\test.f"
.\test.f:19.72:
call nlo_add_inequality_constraint(ires, opt, myconstraint, d1, 1.
1
Error: Syntax error in argument list at (1)
.\test.f:22.72:
call nlo_add_inequality_constraint(ires, opt, myconstraint, d2, 1.
1
Error: Syntax error in argument list at (1)
Error(E42): Last command making (build\test.o) returned a bad status
Error(E02): Make execution terminated
但是,调用 nlo_add_inequality_constraint 具有正确的参数数量,由 NLopt 引用指示:
call nlo_add_inequality_constraint(ires, opt, fc, fc_data, tol)
谁能知道这是怎么回事?非常感谢!
该错误表明参数列表中存在语法错误,而不是过程调用中的不匹配。原因是您的行跨越了 2 个源代码行,并且您的续行符没有正确放置。您表示您的代码全部缩进了 6 space,但是第 20 行和第 23 行的两个续行必须在第 6 列中具有续行字符。
编辑行:
call nlo_add_inequality_constraint(ires, opt, myconstraint,
$ d1, 1.D-8)
d2(1) = -1.
d2(2) = 1.
call nlo_add_inequality_constraint(ires, opt, myconstraint,
$ d2, 1.D-8)
至:
call nlo_add_inequality_constraint(ires, opt, myconstraint,
$ d1, 1.D-8)
d2(1) = -1.
d2(2) = 1.
call nlo_add_inequality_constraint(ires, opt, myconstraint,
$ d2, 1.D-8)
第 6 列中除 space 或零以外的任何字符的存在表示该行是上一行的延续(请参阅 3.3.3.3 Fortran 2008)。