Проблема преобразования Fortran90 в C # - PullRequest
5 голосов
/ 14 февраля 2012

Я конвертирую код 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/)

, но я никогда не видел слова «продукт», используемого в рассматриваемом утверждении Фортрана.Я знаю, что есть встроенная функция для векторного или матричного умножения, называемая PRODUCT, но «product» не является массивом в коде, с которым я работаю, и синтаксис встроенной функции PRODUCT использует MASK, поэтому в моем утверждении эта функция не используется.1010 *

Любое понимание или помощь будет принята с благодарностью.Спасибо.

1 Ответ

7 голосов
/ 14 февраля 2012

Если вы раскладываете части и распечатываете их, вы заметите, что это просто термины, созданные с использованием кратких векторизованных терминов:

! 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);
...