Các khuyến nghị cho một bộ giải đại số tuyến tính dày đặc dựa trên C / C ++


9

Hầu hết các chương trình của tôi là mã nghiên cứu một lần trong C để sử dụng riêng. Tôi chưa bao giờ phân phối bất kỳ mã nào ngoài các cộng tác viên thân thiết. Tôi đã phát triển một thuật toán mà tôi đang xuất bản trong một tạp chí khoa học. Tôi muốn cung cấp mã nguồn và có lẽ mã thực thi trong phần bổ sung trực tuyến cho bài viết. Một đồng nghiệp yêu cầu tôi thực hiện khái quát hóa thuật toán yêu cầu tôi viết bằng C ++ (ack!) Và yêu cầu tôi giải quyết các hệ thống tuyến tính dày đặc nhỏ. Nếu tôi thành công trong việc lấy cơ sở người dùng cho thuật toán thì đó sẽ là một phần vì thanh nhập để sử dụng nó thấp (như trên sàn). Người dùng tiềm năng sẽ không cài đặt thư viện, v.v. để sử dụng mã. Tôi muốn mã hoàn toàn độc lập và không bị cản trở bởi bất kỳ giấy phép nào cả. Tôi có thể chỉ đơn giản là viết bộ giải của riêng mình bằng cách lấy thứ gì đó ra khỏi Golub và van Loan nhưng tôi muốn sử dụng một bộ giải vanilla mà người khác đã viết nếu có bất kỳ thứ gì ngoài đó. Gợi ý đánh giá cao. Cảm ơn!



Jep thân mến, chào mừng đến với diễn đàn. Câu hỏi của bạn rất giống với câu hỏi ở đây: scicomp.stackexchange.com/questions3531/iêu
GertVdE

Người giải quyết thư viện có xu hướng phức tạp và lớn vì lợi ích của sự mạnh mẽ, hiệu quả và tính tổng quát. Nếu các vấn đề của bạn rất nhỏ và có điều kiện hợp lý, tôi sẽ đề nghị bạn viết bản thực hiện nhỏ của riêng bạn.
Stefano M

@GertVdE, cảm ơn bạn đã trả lời nhanh câu hỏi này. Tôi không thoải mái khi liên kết với câu hỏi "Khuyến nghị ..." vì cả câu hỏi và câu trả lời hàng đầu đều quá chung chung để cung cấp bất kỳ trợ giúp nào trong các tình huống như thế này. Nếu bạn muốn thảo luận thêm về vấn đề này, tôi khuyên chúng ta nên đưa nó vào phòng chat scicomp .
Aron Ahmadia

@AronAhmadia: Tôi nghĩ rằng cách duy nhất để bắt đầu giải quyết một số cuộc tranh luận này là bắt đầu thực hiện một thuật toán lập trình khoa học tính toán phụ thuộc cả ngôn ngữ và thư viện. Nếu mã rõ ràng và các vấn đề cấu hình có thể được xử lý (sử dụng tập lệnh shell, Chef hoặc Puppet), thì các cuộc tranh luận về hiệu suất có thể được xử lý (hoặc thực hiện cụ thể) bằng cách chỉ chạy mã và định thời gian cho nó máy tham khảo. Các cuộc tranh luận về sự rõ ràng có thể được giải quyết (hoặc ít nhất, được thực hiện cụ thể hơn) bằng cách xem mã. Nếu không, chúng ta sẽ tiếp tục có những lý lẽ tương tự.
Geoff Oxberry

Câu trả lời:


7

Tôi sẽ đề nghị sao chép chính xác giao diện Lapack với chức năng mà bạn cần, hầu hết có lẽ bạn chỉ cần dgesv. Bằng cách đó, những người đã cài đặt Lapack có thể chỉ cần liên kết với nó và nó sẽ chỉ hoạt động. Đối với những người chưa cài đặt Lapack, bạn cung cấp triển khai đơn giản chức năng này của riêng bạn hoặc có thể triển khai bằng Eigen hoặc FLENS như những người khác đề xuất.

Ở vùng đất Fortran, thư viện Lapack là một tiêu chuẩn như vậy, hầu hết mọi người chỉ đơn giản sử dụng nó và đó là nó, thay vì cung cấp các triển khai của riêng họ.


+1 Thêm vào đó là thực tế là hầu hết các bản phân phối Linux (ít nhất là dựa trên Debian) đều có các gói nhị phân trong kho lưu trữ và tất cả các libs toán học được cung cấp (MKL, SunPerf, ACML, ESSL, v.v.) đều mang nó. Bạn phải luôn luôn sử dụng libs tiêu chuẩn càng nhiều càng tốt mặc dù nếu bạn sử dụng Windows / Mac, bạn có thể sử dụng một cái gì đó dựa trên C để cài đặt trình biên dịch Fortran miễn phí (gfortran) cho chúng là một số công việc hoặc tôi đã nghe thấy.
stali

Tôi đã sử dụng lapack nhiều lần nhưng hiện tại tôi không ở vùng đất fortran. Tôi hy vọng rằng việc phân phối thống kê các nền tảng mà cơ sở người dùng của tôi chạy trên sẽ tương tự như thế giới với ý nghĩa chủ yếu là các cửa sổ, tỷ lệ mac nhỏ hơn và tỷ lệ * nix thậm chí còn nhỏ hơn. Kinh nghiệm của tôi với các cửa sổ là tối thiểu và tôi thích giữ nó theo cách đó. Đây là lý do tôi muốn một mã C ++ độc lập. Tôi nghĩ rằng tôi sẽ phải cung cấp cho một số người dùng của mình trợ giúp để nhận mã để biên dịch và chạy. Tôi cần giảm thiểu công việc cần thiết để làm điều đó.
jep

Nếu cơ sở người dùng của bạn là Windows / Mac thì bạn sẽ tốt hơn với cách triển khai dựa trên C đơn giản (thậm chí là của riêng bạn). Gói khó cài đặt hoặc phụ thuộc vào 5 lib khác, đặc biệt khi không có kho lưu trữ gói nhị phân hạng nhất (như Debian), sẽ tắt người dùng của bạn trong một thời gian dài. Hãy nhớ rằng hầu hết người dùng Windows / Mac được sử dụng để cài đặt một lần nhấp. Dễ sử dụng chiến thắng mọi thứ khác.
stali

5

Một sai lầm rất sớm mà nhiều người mắc phải khi bắt đầu tính toán khoa học là giả định rằng bạn cần phải viết tất cả mã của mình bằng cùng một ngôn ngữ. Tôi nghĩ rằng điều này phần lớn là do các lý do lịch sử, khi không rõ làm thế nào để làm cho các chương trình được biên dịch giao tiếp với nhau qua các phiên bản của cùng một trình biên dịch. Điều đó nói rằng, trong trường hợp này, nếu bạn vẫn đang sử dụng C ++, có một số thư viện mẫu chỉ có tiêu đề C ++ rất tốt có thể phù hợp với nhu cầu của bạn.

Vì bạn đang phân phối mã của mình vì lý do học thuật và bạn muốn nhúng một bộ giải đại số tuyến tính dày đặc vào mã của mình, tôi thực sự khuyên bạn nên xem xét Eigen . Eigen đã được cấp phép theo Giấy phép Công cộng Mozilla và là thư viện chỉ dành cho tiêu đề. Điều này có nghĩa là bạn có thể phân phối Eigen với mã của mình ở dạng nguồn (điều này không áp đặt bất kỳ hạn chế cấp phép nào đối với mã của bạn) và bạn sẽ nhận được quyền truy cập vào các khả năng chung của nó, bao gồm các bộ giải tuyến tính dày đặc cực kỳ hiệu quả. Như GertVdE đề cập, bạn có một số tùy chọn khác .


Tôi đã hy vọng cho một tập tin duy nhất. Tôi đã thực hiện lập trình khoa học khá lâu. Tôi có các ngôn ngữ hỗn hợp như C và fortran khá nhiều nhưng đối với dự án này tôi thực sự chỉ muốn một tệp chứa tất cả mã nguồn của mình. Tôi cho rằng tôi có thể đặt một bộ giải C vào mã C ++ sẽ không phải là vấn đề lớn. Chủ yếu tôi muốn giữ mã đơn giản nhất có thể. LU với xoay vòng là đủ. Tôi sẽ nhìn vào Eigen. Cảm ơn!
jep

@jep, bạn cũng có thể thử chọn các thói quen mà bạn cần từ CLAPACK nếu bạn thực sự không quan tâm đến hiệu suất.
Aron Ahmadia

Có nhiều lý do để viết tất cả các mã phụ thuộc trong cùng một ngôn ngữ, đặc biệt, trong môi trường HPC, bạn có các vấn đề liên quan đến trình biên dịch / liên kết kỳ lạ và các vấn đề giao diện 32/64-bit. Ví dụ: làm thế nào để tôi biết chiều rộng của một số nguyên cho các thư viện tích hợp? Làm cách nào để biết chắc chắn trình biên dịch nào đã được sử dụng cho thư viện tích hợp và tôi có thể liên kết với trình biên dịch này không? Có tất cả mọi thứ trong một ngôn ngữ đơn giản hóa nhiều vấn đề này. Và vâng, cần có tài liệu được cung cấp bởi các nhà duy trì cụm, nhưng hầu hết thời gian không có.
Victor Liu

@VictorLiu - Các vấn đề bạn đang đề cập đến được liên kết chặt chẽ hơn với việc triển khai hơn ngôn ngữ. Không gian bình luận là một nơi tồi tệ để tham gia vào một cuộc thảo luận nghiêm túc, nhưng tôi rất vui khi được bạn tham gia trò chuyện hoặc ở nơi khác nếu bạn muốn tôi mở rộng suy nghĩ của mình về điều này.
Aron Ahmadia

4

Nếu bạn muốn một bộ giải đáng tin cậy cho các hệ phương trình tuyến tính, tôi sẽ khuyên dùng FLENS . Nó chứa một triển khai lại chính xác LAPACK (thậm chí nó còn tái tạo các lỗi làm tròn giống như LAPACK nếu sử dụng triển khai BLAS một luồng đơn). Điều này đúng với tất cả các hàm FLENS-LAPACK (cùng với các hàm tiện ích khoảng 100 thường trình).

FLENS theo Giấy phép BSD và do đó cho phép kết hợp thành các sản phẩm độc quyền.

FLENS chỉ là tiêu đề và nếu bạn chỉ cần một tập hợp con FLENS, tôi có thể cung cấp cho bạn phiên bản rút gọn chỉ chứa những chức năng bạn cần. FLENS đi kèm với việc thực hiện BLAS tham chiếu riêng của mình. Nhưng tùy chọn người dùng của bạn có thể liên kết với các thư viện BLAS được tối ưu hóa như ATLAS, OpenBLAS hoặc GotoBALS. Đối với các ma trận lớn, điều này mang lại hiệu suất tăng khoảng 40% so với Eigen.

Và vâng, Eigen cũng sử dụng bộ thử nghiệm LAPACK để kiểm tra kết quả của họ. Họ làm điều này cho 3 chức năng (Lu, Cholesky và Eigenvalues ​​/ -vector của một ma trận đối xứng). Tuy nhiên, việc tính toán giá trị riêng / giá trị của ma trận không đối xứng sẽ làm thất bại bộ thử nghiệm LAPACK.

Tuyên bố miễn trừ trách nhiệm: Vâng, FLENS là con tôi! Điều đó có nghĩa là tôi đã mã hóa khoảng 95% của nó và mỗi dòng mã đều có giá trị.


1
Michael - Vui lòng xem đây là một cảnh báo thân thiện rằng bạn cần tuân theo quy tắc trong faq liên quan đến việc tiết lộ liên kết .
Aron Ahmadia

Chắc chắn, nhưng bạn cũng có thể diễn đạt lại các bài đăng của mình từ 'Tôi thực sự khuyên bạn nên xem xét Eigen' thành một cái gì đó như 'ví dụ như Eigen'. Trong trường hợp này, tôi xóa nhận xét của mình về Eigen (mặc dù tất cả chúng đều được chứng minh là đúng) bao gồm cả điều này.
Michael Lehn

1
Nhận xét của bạn về Eigen không phải là vấn đề ở đây (mặc dù chúng có vẻ lạc đề với tôi). Bạn là nhà phát triển chính của FLENS, nếu bạn muốn giới thiệu nó trong câu trả lời ở đây, bạn phải tiết lộ liên kết của mình với tư cách là nhà phát triển dự án.
Aron Ahmadia

À, được rồi. Tôi nghĩ đã hoàn toàn rõ ràng bởi '... Tôi có thể cho bạn ...'. Là tiết lộ trong hình thức này ok?
Michael Lehn

2
Tôi chỉ muốn nói cảm ơn vì đã làm điều này; Tôi đã có kế hoạch tương tự để thực hiện lại một phần lớn Lapack trong C ++. Tuy nhiên, dường như đối với hầu hết các thói quen nâng cao (eigenvalue), bạn chỉ cần gọi vào Lapack, do đó, có một chút quảng cáo sai khi nói rằng bạn thực hiện lại toàn bộ. Mặt khác, tôi thực sự đã chuyển nguồn ZGEEV sang C ++ trong RNP , mặc dù một số phần vẫn nằm trong chỉ mục dựa trên 1 từ chuyển đổi tự động.
Victor Liu
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.