2016-01-23 106 views
1

什么是初始化复杂数组的快速而准确的方法?是否有以下任何差异:将复杂数组初始化为零的正确方法

complex(real64) :: x(2,2) 
x = 0 
x = 0d0 
x = (0d0,0d0) 

它们是否相同,我可以假设我在每个编译器上得到相同的结果吗?标准是否对此有任何说明?问题是特别是关于初始化为零,而不是任何其他数字。

+0

由于你的“快速”,我问这个问题是关于编译器是否可以做不同的事情(在运行时更快),但考虑到你对我的答案的评论,这可能实际上是写作过程中的简短/快速? – francescalus

+0

是的,快意味着写作简洁。任何时候通过写入'(0d0,0d0)'并避免隐式转换可以被忽略。理想情况下,我会写'x = 0',这可以节省我几秒钟的时间,并且可读性好。但是,这是科学的代码,我需要确定低层次上究竟发生了什么。我目前只能访问gfortran和ifort,对于他们来说,这些任务确实没有任何区别。 –

回答

2

在谈到真正的答案之前,请注意术语。在Fortran中你在这里不是初始化而是赋值。这是两件不同的事情。是的,很清楚这里是什么意思,但也许很好意识到这个区别。

x=0这样的行是内在赋值语句。 =的左边是变量,右边是表达式。对于这些问题中的每一个,有两个考虑因素:

  • 变量和表达式可能在类型或类型参数上有所不同;
  • 变量是一个数组,表达式是一个标量。

a related answer所述,当可变和表达类型或类型参数不同(但型贴合如在这种情况下)的表达转换为变量的类型和类型参数。

前两个分配肯定涉及类型转换:0是一个整数,而0d0是一个(双精度)实数。虽然(0d0, 0d0)是一个复杂的 - 所以没有类型转换 - 这将是别样的,除非double precision相同real(real64)

因此,至少前两个我们已经转换像相当于

x = CMPLX(0, KIND=real64) 
x = CMPLX(0d0, KIND=real64) 

和第三也许

x = CMPLX((0d0, 0d0), KIND=real64) 

随着

x = (0._real64, 0._real64) 

我们可以肯定的变量和表达式的种类是相同的。

只要CMPLX(0, KIND=real64)具有相同的值(0._real64, 0._real64)可以肯定的是,分配x=0(现在,标量x)具有作为x=(0._real64, 0._real64)同样的效果。这是Fortran标准的要求。

零是在它出现在每一个模型数集的特殊情况有所的,但每当一个(数学)数使用可以在所有三个被精确表示的效果将是相同的。同样,

x = 3.14_real64 

x = (3.14_real64, 0._real64) 

是等价的。

但值得注意的是,有些选项的编译器可能会提供有关隐式转换的警告。即使数值相等,这也是一个不同之处。

即将到来的数组/标量方面:表达式被视为与每个元素等于该标量值的变量具有相同形状的数组。

总结:这三个任务中的每一个都具有相同的Fortran效果。在作业x之后是给定形状的阵列,每个元素具有复数值(0._real64, 0._real64)

现在,这并不是说不会有什么令人兴奋的事情发生在低级别的可能性,并且零设置可能是一个特殊情况。但那是你和你的编译器(和系统)之间的事情。

+0

谢谢,的确,我的意思是按照Fortran术语进行分配。我可以从你的最后一段推断出答案不是我的问题,或者你不确定吗?我怀疑零转换始终没有失去准确性。如果它是像3.14这样的事情,那么所有这三项任务显然都会有所不同。 –

+0

零在某种程度上是一种特殊情况,因为在三个表示“整数”,“双精度”和“实数(real64)”中的每一个中,该值都可以精确地表示(我想可能存在奇怪的异常)。其他小数量整数也将是,所以这是“特殊”的限制。 '3.14'可能是一个不好的例子,因为它不是整数,但是'x = 3.14'和'x = 3.14d0'可能会给出不同的结果,但是这取决于字面常量本身以及每种类型的近似值,而不是随后的转换为复杂/真实(real64)'。 – francescalus

+0

纠正我以前的评论:每个型号集中都明确存在零。哪些其他(数学)数字可以精确地表示在每个模型中取决于模型,但在实际水平1将是,但3.14不会。 – francescalus