0

我正在使用 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)

任何人都可以找出发生了什么吗?非常感谢!

4

1 回答 1

1

该错误表示参数列表中的语法错误,而不是过程调用中的不匹配。原因是您的行跨越了 2 个源代码行,并且您的续行字符没有正确放置。您指出您的代码全部缩进 6 个空格,但第 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 列中出现除空格或零之外的任何字符表示该行是前一行的延续(请参阅 3.3.3.3 Fortran 2008)。

于 2015-08-19T20:37:08.757 回答