Fortran90到C#的转换问题

本文关键字:转换 问题 Fortran90 | 更新日期: 2023-09-27 18:24:33

我正在将一些Fortran90代码转换为C#。我对Fortran77有所了解,但对Fortran90并不熟悉。我遇到了以下一行代码,我不确定如何翻译。

C1 = real(product((/(-1,i1=1,m-1)/))*product((/(i1,i1=2,m)/)))

我认为这应该转换为:

int product1 = -1; int product2 = 1;
for (int i1 = 1 ; i1 <= (m-1); i1++)
{
    product1 *= -1;
}
for (int i2 = 2, i2 <= m; i2++)
{
    product2 *= i2;
}
float C1 = (float)(product1 * product2);

我的不确定性源于这样一个事实,即存在用于初始化数组的隐含do循环构造;即

A = (/2*I, I = 1,5/)

但我从未见过像Fortran语句中那样使用"乘积"一词。我知道向量或矩阵乘法有一个内部函数叫做PRODUCT,但在我使用的代码中,"乘积"不是数组,而且内部函数PRODUCT的语法使用MASK,所以很明显,我的声明没有使用这个函数。

如有任何见解或帮助,我们将不胜感激。非常感谢。

Fortran90到C#的转换问题

如果您分解零件并打印它们,您会注意到这些只是使用简洁的矢量化术语创建的术语:

! given: (/(expr, start, end)/)
!
! (/(-1, i1=1, m-1)/) = vector, -1 repeated m-1 times
!
! (/(i1, i1=2, m)/)   = vector, 2..m
!
! Both are vectors with m-1 terms

需要注意的另一点是product()不需要3个参数。第二个参数(要使用的维度)和第三个参数(数组掩码)不是必需的。

在这一点上,第一个乘积实际上是-1m-1,而第二个乘积是m!

因此,一个合适的(但不一定有效的)翻译可以是:

// product((/(-1,i1=1,m-1)/)) => -1^m-1
double i = (m % 2 == 0 ? -1 : 1);
// product((/(i1,i1=2,m)/))   => m!
double mfact = i;
for (int jj = 2; jj < m; ++jj)
{
    mfact *= jj;
} // C1 = mfact;

简洁,接近F90的"精神",但几乎没有效率:

double i = (m % 2 == 0 ? -1 : 1);
double C1 = Enumerable.Range(2, m)
                      .Aggregate(i, (x, y) => x * y);