我的Fortran代码中有以下一组命令:
COMPLEX*16, DIMENSION(4,1) :: INSTATE_BASISSTATES
INSTATE_BASISSTATES(:,:) = (0.0D0,0.0D0)
INSTATE_BASISSTATES(1,1) = ((1.0D0/SQRT(2)),0.0D0)
INSTATE_BASISSTATES(3,1) = ((1.0D0/SQRT(2)),0.0D0)当我在cygwin上使用gfortran运行/编译程序时,我得到错误
INSTATE_BASISSTATES(1,1) = (1.0D0/DREAL(SQRT(2.0D0)),0.0D0)
1
Error: Expected a right parenthesis in expression at (1)
INSTATE_BASISSTATES(3,1) = (1.0D0/DREAL(SQRT(2.0D0)),0.0D0)
1
Error: Expected a right parenthesis in expression at (1)可能的问题是什么?我的括号是不是正确?
发布于 2016-08-16 17:27:29
在赋值语句的右侧,您正在尝试使用复杂的文字常量。然而,
(1.0D0/DREAL(SQRT(2.0D0)),0.0D0)不是此类常量的有效形式。
对于复数文字,实部和虚部必须是命名常量或文字常量。1.0D0/DREAL(SQRT(2.0D0))不是这两样东西。对于没有问题的那一行,(0.0D0,0.0D0)的两个组件都是文字常量。
与在this other answer中一样,您可以使用所需的值创建一个命名常量并使用该常量。或者,由于您只是在执行一个无聊的赋值(它没有应用于初始化等方面的各种限制),因此您可以使用cmplx内部函数来返回一个复杂值
INSTATE_BASISSTATES(1,1) = CMPLX(1.0D0/DREAL(SQRT(2.0D0)),0.0D0)这里的实部和虚部不需要是常量。你甚至可以注意到
INSTATE_BASISSTATES(1,1) = CMPLX(1.0D0/DREAL(SQRT(2.0D0)))同样有效:如果没有提供虚部分值,则返回的复数具有虚部零。
不过,这里有一点小问题。默认情况下,cmplx会返回一个默认实数类型的复数。要返回与complex*16匹配的内容(这不是标准的Fortran,但让我们假设它对应于double precision),您需要CMPLX(..., [...], KIND=KIND(0d0)) (或KIND=KIND(INSTATE_BASISSTATES))
顺便说一句,正如Vladimir F评论的那样,dreal不是标准的Fortran。您可以使用带有适当种类编号的dble或real。但我们也可以看到,sqrt(2d0)已经返回了一个双精度实数,所以即使是这些也是多余的:1/sqrt(2d0)的结果与原始的更繁琐的表达式相同(数学)。2d0**(-0.5)和sqrt(2d0)/2也是如此。
您甚至可以将右侧替换为
SQRT((5d-1,0))正如我们所看到的,sqrt还接受一个复杂的参数(在本例中是一个复杂的文字常量)。这种形式还避免了kind=说明符的笨拙:它的值既有参数的类型也有类型。
发布于 2016-08-16 16:45:13
这确实是“故意的”,可以先定义感兴趣的常量,然后在初始化中使用它。例如:
COMPLEX*16, DIMENSION(4,1) :: INSTATE_BASISSTATES
REAL*8, PARAMETER :: my_const = 1D0 / SQRT(2D0)
INSTATE_BASISSTATES(:,:) = (0.0D0,0.0D0)
INSTATE_BASISSTATES(1,1) = (my_const,0.0D0)
INSTATE_BASISSTATES(3,1) = (my_const,0.0D0)但是,语句REAL*8, PARAMETER :: my_const = 1D0 / SQRT(2D0)似乎至少需要Fortran2003标准,否则,将产生以下错误Elemental function as initialization expression with non-integer/non-character arguments。可以使用gfortran和-std=f2003指定标准,尽管默认情况下gfortran可能是活动的。
发布于 2016-08-17 02:48:18
@J123仍然没有回答这个紧迫的问题。您是使用.f扩展名的固定格式还是自由格式的.f90编写代码?另外,您使用的是哪个版本的gfortran?我已经在下面发布了一个完整的修复。您可以通过使用命名的parameter常量或作为内部转换函数cmplx的返回值直接赋值来创建数组。请注意,可以自由使用kind参数wp来控制浮点精度。
program main
use iso_fortran_env, only: &
wp => REAL64, & ! Or REAL128 if your architecture supports it
compiler_version, &
compiler_options
! Explicit typing only
implicit none
! Variable declarations
complex(wp) :: instate_basisstates(4,1)
real (wp), parameter :: ZERO = 0 ! Assigning integers is safe
real (wp), parameter :: SQRT2 = sqrt(2.0_wp)
real (wp), parameter :: ONE_OVER_SQRT2 = 1.0_wp/SQRT2
! Executable statements
instate_basisstates(:,:) = ZERO
instate_basisstates(1,1) = (ONE_OVER_SQRT2, ZERO)
instate_basisstates(3,1) = cmplx(1.0_wp/sqrt(2.0_wp), 0.0_wp, kind=wp)
print '(/4a/)', &
'This file was compiled using ', compiler_version(), &
' using the options ', compiler_options()
end program main这会产生以下结果:
This file was compiled using GCC version 6.1.1 20160802 using the options -mtune=generic -march=x86-64 -O3 -Wall -std=f2008tshttps://stackoverflow.com/questions/38969323
复制相似问题