2012-02-14 25 views
5

Tôi đang chuyển đổi một số mã Fortran90 thành C#. Tôi có một số kiến ​​thức về Fortran77 nhưng không quen thuộc với Fortran90. Tôi đã chạy qua dòng mã sau đây mà tôi không chắc chắn làm thế nào để dịch.Fortran90 to C# Conversion Issue

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

Tôi đang nghĩ đến điều này nên được chuyển đổi như:

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

sự không chắc chắn của tôi bắt nguồn từ thực tế rằng có tồn tại một ngụ ý làm xây dựng vòng lặp cho khởi tạo mảng; tức là

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

nhưng tôi chưa bao giờ thấy từ "sản phẩm" được sử dụng như trong tuyên bố Fortran được đề cập. Tôi biết có một hàm nội tại cho phép nhân vectơ hoặc ma trận gọi là PRODUCT nhưng "sản phẩm" không phải là một mảng trong mã tôi đang làm việc và cú pháp của hàm intrisic PRODUCT sử dụng MASK vì vậy rõ ràng câu lệnh của tôi không sử dụng hàm này.

Bất kỳ thông tin chi tiết hoặc trợ giúp nào sẽ được đánh giá cao. Cảm ơn bạn.

+2

Bạn nên có lẽ thử để hiểu mã này làm gì và không chỉ dịch nó một cách mù quáng. – svick

+2

Về mặt toán học ở trên là '-cos (π * m) * m!' Vì vậy, sản phẩm đầu tiên lật dấu, và thứ hai đánh giá giai thừa của 'm'. Trong 'C#' bạn có thể sử dụng '1-2 * (m% 2)' để lật dấu cho mỗi 'm'. – ja72

+0

Cảm ơn bạn ja72. – Zeos6

Trả lời

7

Nếu bạn phân hủy các bộ phận và in chúng, bạn sẽ nhận thấy đây là những cách đơn giản về tạo sử dụng thuật ngữ vectorized ngắn gọn:

! 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 

Một điều khác cần lưu ý là product() không đòi hỏi 3 đối số. Đối số thứ hai (thứ nguyên để sử dụng) và đối số thứ ba (một mặt nạ mảng) là không bắt buộc.

Tại thời điểm này, nó trở nên rõ ràng rằng các sản phẩm đầu tiên thực sự là -1m-1 và sản phẩm thứ hai là m!.

Vì vậy, một bản dịch thích hợp (nhưng không nhất thiết phải hiệu quả) có thể là:

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

gọn gàng, chặt chẽ trong "tinh thần" với F90, nhưng hầu như không hiệu quả:

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

Cảm ơn bạn rất nhiều. Tôi đã kết thúc bằng cách sử dụng gợi ý của ja72 cho dấu lật [-1 + 2 * (m% 2)], và tính toán giai thừa sử dụng đệ quy đuôi. Cảm ơn các bạn rất nhiều. – Zeos6