2012-02-14 15 views
5

Konwertuję niektóre kody Fortran90 na C#. Mam trochę wiedzy o Fortran77, ale nie znam Fortran90. Przeszukałem poniższy wiersz kodu, którego nie jestem pewien, jak tłumaczyć.Konwersja Fortran90 do C#

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

myślę to powinno zostać przekształcone jako:

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

Moja niepewność wynika z faktu, że istnieje dorozumiana zrobić budowę pętli do inicjalizacji tablic; tj

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

ale nigdy nie widziałem słowo „produkt” używane jak w Fortran oświadczenia o którym mowa. Wiem, że istnieje wewnętrzna funkcja mnożenia wektorów lub macierzy o nazwie PRODUCT, ale "produkt" nie jest tablicą w kodzie, z którym pracuję, a składnia funkcji intrisic PRODUCT używa MASK, więc wyraźnie moja instrukcja nie używa tej funkcji.

Każdy wgląd lub pomoc byłaby bardzo doceniana. Dziękuję Ci.

+2

Należy prawdopodobnie spróbować zrozumieć, co robi kod, a nie tylko tłumaczyć go na ślepo. – svick

+2

Matematycznie powyższe jest '-cos (π * m) * m!' Tak więc pierwszy produkt odwraca znak, a drugi ocenia silnię 'm'. W 'C#' możesz użyć '1-2 * (m% 2)', aby odwrócić znak dla każdego 'm'. – ja72

+0

Dziękuję ja72. – Zeos6

Odpowiedz

7

Jeśli rozłożenia części i wydrukować je, można zauważyć, są to po prostu warunki stworzone przy użyciu zwięzłych wektorowy warunki:

! 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 

Inną rzeczą jest, aby pamiętać, że nie wymaga product() 3 argumenty. Drugi argument (wymiar do użycia) i trzeci argument (maska ​​tablicy) nie są wymagane.

W tym momencie staje się jasne, że pierwszy produkt jest rzeczywiście -1m-1 i drugi produkt jest m!.

więc właściwa (ale niekoniecznie skuteczny) tłumaczenie mogłoby być:

// 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; 

Zwięzły, blisko w "ducha" z F90, ale mało wydajny:

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

Dziękuję bardzo. Skończyło się na tym, że użyłem sugestii ja72 do odwrócenia znaku [-1 + 2 * (m% 2)] i obliczyć silnię za pomocą rekurencji ogona. Dziękuję wszystkim bardzo. – Zeos6