Empfehlungen für einen leichten / nicht installierten C- oder C ++ - dichten linearen Algebra-Löser

9

Der größte Teil meiner Programmierung besteht aus einmaligen Forschungscodes in C für meinen eigenen Gebrauch. Ich habe niemals Code an andere als enge Mitarbeiter verteilt. Ich habe einen Algorithmus entwickelt, den ich in einer wissenschaftlichen Zeitschrift veröffentliche. Ich möchte den Quellcode und möglicherweise den ausführbaren Code in der Online-Ergänzung zum Artikel bereitstellen. Ein Kollege forderte mich auf, eine Verallgemeinerung des Algorithmus vorzunehmen, bei der ich in C ++ schreiben musste (ack!) Und bei der ich kleine dichte lineare Systeme lösen muss. Wenn es mir gelingt, eine Benutzerbasis für den Algorithmus zu erhalten, liegt dies teilweise daran, dass die Eingabeleiste für die Verwendung niedrig ist (wie auf dem Boden). Potenzielle Benutzer installieren keine Bibliotheken usw., um den Code zu verwenden. Ich möchte, dass der Code vollständig eigenständig ist und überhaupt nicht durch eine Lizenz belastet wird. Ich könnte einfach meinen eigenen Löser schreiben, indem ich etwas aus Golub und van Loan herausnehme, aber ich würde lieber einen Vanille-Löser verwenden, den bereits jemand anderes geschrieben hat, wenn es einen gibt. Vorschläge geschätzt. Vielen Dank!

jep
quelle
Lieber Jep, willkommen im Forum. Ihre Frage ist der hier sehr ähnlich: scicomp.stackexchange.com/questions/351/…
GertVdE
Bibliothekslöser sind aus Gründen der Robustheit, Effizienz und Allgemeinheit in der Regel komplex und groß. Wenn Ihre Probleme sehr klein und einigermaßen gut konditioniert sind, würde ich Ihnen empfehlen, Ihre eigene Mini-Implementierung zu schreiben.
Stefano M
@GertVdE, danke für die schnelle Antwort auf diese Frage. Es ist mir unangenehm, auf die Frage "Empfehlungen ..." zu verlinken, da sowohl die Frage als auch die Top-Antwort zu allgemein sind, um in solchen Situationen Hilfe zu leisten. Wenn Sie dies weiter diskutieren möchten , schlage ich vor, dass wir es in den scicomp-Chatraum bringen .
Aron Ahmadia
@AronAhmadia: Ich denke, der einzige Weg, um einige dieser Debatten beizulegen, besteht darin, eine Chrestomathie der rechnergestützten Programmierung zu implementieren, die sowohl sprach- als auch bibliotheksabhängig ist. Wenn der Code klar ist und Konfigurationsprobleme behoben werden können (mithilfe eines Shell-Skripts, eines Chefs oder einer Marionette), können Debatten über die Leistung erledigt (oder konkretisiert) werden, indem nur der Code ausgeführt und auf a zeitlich festgelegt wird Referenzmaschine. Debatten über Klarheit können durch Betrachten des Codes gelöst (oder zumindest konkreter) werden. Andernfalls haben wir weiterhin dieselben Argumente.
Geoff Oxberry

Antworten:

7

Ich würde vorschlagen, die Lapack-Oberfläche genau auf die Funktion zu duplizieren, die Sie benötigen, höchstwahrscheinlich nur dgesv. Auf diese Weise können Personen, auf denen Lapack installiert ist, einfach eine Verknüpfung herstellen, und es funktioniert einfach. Für Personen, auf denen Lapack nicht installiert ist, stellen Sie Ihre eigene einfache Implementierung dieser Funktion bereit oder implementieren sie möglicherweise mit Eigen oder FLENS, wie von anderen vorgeschlagen.

Im Fortran-Land ist die Lapack-Bibliothek ein solcher Standard, dass die meisten Leute sie einfach verwenden und das ist es, anstatt ihre eigenen Implementierungen bereitzustellen.

Ondřej Čertík
quelle
+1 Hinzu kommt, dass die meisten Linux-Distributionen (zumindest auf Debian-Basis) Binärpakete im Repository haben und alle vom Hersteller bereitgestellten mathematischen Bibliotheken (MKL, SunPerf, ACML, ESSL usw.) diese enthalten. Sie sollten immer so viel Standardbibliotheken wie möglich verwenden. Wenn Sie jedoch unter Windows / Mac arbeiten, ist es möglicherweise besser, wenn Sie etwas C-basiertes verwenden, da die Installation eines kostenlosen Fortran-Compilers (gfortran) auf ihnen eine gewisse Arbeit darstellt, wie ich gehört habe.
stali
Ich habe viele Male Lapack benutzt, aber ich bin derzeit nicht im Festland. Ich gehe davon aus, dass die statistische Verteilung der Plattformen, auf denen meine Benutzerbasis ausgeführt wird, der der Welt insgesamt ähnlich sein wird, dh hauptsächlich Windows, ein geringerer Prozentsatz von Macs und ein noch geringerer Prozentsatz von * nix. Meine Erfahrung mit Fenstern ist minimal und ich ziehe es vor, es so zu halten. Aus diesem Grund möchte ich einen eigenständigen C ++ - Code. Ich denke, ich muss einigen meiner Benutzer helfen, damit der Code kompiliert und ausgeführt wird. Ich muss den dafür erforderlichen Aufwand minimieren.
Jep
Wenn Ihre Benutzerbasis Windows / Macs ist, ist eine einfache C-basierte (möglicherweise sogar Ihre eigene) Implementierung besser geeignet. Ein Paket, das schwierig zu installieren ist oder von 5 anderen Bibliotheken abhängt, insbesondere wenn kein erstklassiges Binärpaket-Repository (wie Debian) verfügbar ist, wird Ihre Benutzer für lange Zeit ausschalten. Denken Sie daran, dass die meisten Windows / Mac-Benutzer an die Installation mit einem Klick gewöhnt sind. Benutzerfreundlichkeit triumphiert alles andere.
stali
5

Ein sehr früher Fehler, den viele Menschen machen, wenn sie mit dem wissenschaftlichen Rechnen beginnen, ist die Annahme, dass Sie Ihren gesamten Code in derselben Sprache schreiben müssen. Ich denke, dies ist größtenteils auf historische Gründe zurückzuführen, als nicht klar war, wie kompilierte Programme über gleichmäßige Versionen desselben Compilers hinweg miteinander kommunizieren können. In diesem Fall gibt es jedoch mehrere sehr gute Vorlagenbibliotheken nur für C ++ - Header, die möglicherweise Ihren Anforderungen entsprechen, wenn Sie C ++ trotzdem verwenden möchten.

Da Sie Ihren Code aus akademischen Gründen verteilen und einen dichten linearen Algebra-Solver in Ihren Code einbetten möchten, würde ich Ihnen dringend empfehlen, Eigen in Betracht zu ziehen . Eigen wurde unter der Mozilla Public License lizenziert und ist eine reine Header-Bibliothek. Dies bedeutet, dass Sie Eigen mit Ihrem Code in Quellform verteilen können (dies legt keine Lizenzbeschränkungen für Ihren Code fest), und Sie erhalten Zugriff auf seine allgemeinen Funktionen, einschließlich äußerst effizienter dichter linearer Löser. Wie GertVdE erwähnt, haben Sie mehrere andere Möglichkeiten .

Aron Ahmadia
quelle
Ich hatte auf eine einzige Datei gehofft. Ich habe eine ganze Weile wissenschaftlich programmiert. Ich habe ziemlich viele gemischte Sprachen wie C und fortran, aber für dieses Projekt möchte ich wirklich nur eine Datei, die meinen gesamten Quellcode enthält. Ich nehme an, ich könnte einen C-Solver in den C ++ - Code einfügen, was keine große Sache wäre. Hauptsächlich möchte ich den Code so einfach wie möglich halten. LU mit Schwenk sollte ausreichend sein. Ich werde Eigen ansehen. Vielen Dank!
Jep
@jep, Sie können auch versuchen, die Routinen auszuwählen, die Sie von CLAPACK benötigen, wenn Ihnen die Leistung wirklich egal ist.
Aron Ahmadia
Es gibt gute Gründe, den gesamten abhängigen Code in derselben Sprache zu schreiben, insbesondere in HPC-Umgebungen. Sie haben seltsame Compiler- / Verknüpfungsprobleme und 32/64-Bit-Schnittstellenprobleme. Woher weiß ich beispielsweise, wie breit eine Ganzzahl für integrierte Bibliotheken ist? Woher weiß ich sicher, welcher Compiler für eine integrierte Bibliothek verwendet wurde, und kann ich ihn mit diesem anderen Compiler verknüpfen? Alles in einer Sprache zu haben, vereinfacht viele dieser Probleme. Und ja, es sollte eine Dokumentation geben, die von den Cluster-Betreuern bereitgestellt wird, aber meistens nicht.
Victor Liu
@VictorLiu - Die Probleme, auf die Sie sich beziehen, sind enger an Implementierungen gekoppelt als an Sprachen. Der Kommentarbereich ist ein schlechter Ort, um ernsthafte Diskussionen zu führen, aber ich freue mich, Sie in einen Chat oder anderswo einzubeziehen, wenn Sie möchten, dass ich meine Gedanken dazu erweitere.
Aron Ahmadia
4

Wenn Sie einen zuverlässigen Löser für lineare Gleichungssysteme suchen, würde ich FLENS empfehlen . Es enthält eine genaue Neuimplementierung von LAPACK (es reproduziert sogar die gleichen Rundungsfehler wie LAPACK, wenn eine BLAS-Implementierung mit einem Thread verwendet wird). Dies gilt für alle FLENS-LAPACK- Funktionen (zusammen mit den Utility-Funktionen ca. 100 Routinen).

FLENS steht unter einer BSD-Lizenz und kann daher in proprietäre Produkte integriert werden.

FLENS ist nur ein Header und wenn Sie nur eine Teilmenge von FLENS benötigen, kann ich Ihnen eine abgespeckte Version geben, die nur die Funktionen enthält, die Sie benötigen. FLENS wird mit einer eigenen Referenz-BLAS-Implementierung geliefert. Optional können Ihre Benutzer jedoch Links zu optimierten BLAS-Bibliotheken wie ATLAS, OpenBLAS oder GotoBALS erstellen. Bei großen Matrizen ergibt sich ein Leistungsgewinn von ca. 40% gegenüber Eigen.

Und ja, Eigen verwendet auch die LAPACK-Testsuite, um ihre Ergebnisse zu überprüfen. Sie tun dies für 3 Funktionen (Lu, Cholesky und Eigenwerte / -vektoren einer symmetrischen Matrix). Ihre Berechnung von Eigenwerten / -vektoren einer nicht symmetrischen Matrix würde jedoch die LAPACK-Testsuite nicht bestehen.

Haftungsausschluss: Ja, FLENS ist mein Baby! Das heißt, ich habe ungefähr 95% davon codiert und jede Codezeile hat sich gelohnt.

Michael Lehn
quelle
1
Michael - Bitte betrachten Sie dies als eine freundliche Warnung, dass Sie die Regel in der FAQ bezüglich der Offenlegung der Zugehörigkeit befolgen müssen .
Aron Ahmadia
Sicher, aber Sie könnten Ihre Beiträge auch von "Ich würde dringend empfehlen, dass Sie Eigen in Betracht ziehen" in etwas wie "Es gibt zum Beispiel Eigen" umformulieren. In diesem Fall lösche ich meine Bemerkungen zu Eigen (obwohl sich alle als wahr erwiesen haben), einschließlich dieser.
Michael Lehn
1
Ihre Bemerkungen zu Eigen stehen hier nicht zur Debatte (obwohl sie mir nicht zum Thema gehören). Sie sind ein Hauptentwickler von FLENS. Wenn Sie dies in einer Antwort hier empfehlen möchten, müssen Sie Ihre Zugehörigkeit als Entwickler des Projekts offenlegen.
Aron Ahmadia
Ah, ok dann. Ich dachte, es sei implizit klar durch "... ich kann dir geben ...". Ist die Offenlegung in dieser Form in Ordnung?
Michael Lehn
2
Ich möchte mich nur dafür bedanken. Ich hatte ähnliche Pläne, einen großen Teil von Lapack in C ++ erneut zu implementieren. Es scheint jedoch, dass Sie für die meisten fortgeschrittenen (Eigenwert-) Routinen einfach den Aufruf von Lapack verschieben. Es ist also ein bisschen falsche Werbung zu sagen, dass Sie das Ganze erneut implementieren. Andererseits habe ich die ZGEEV-Quelle in RNP tatsächlich nach C ++ portiert , obwohl einige Teile noch in der 1-basierten Indizierung von der automatischen Konvertierung enthalten sind.
Victor Liu