Array -Programmierung

Im Informatik, Array -Programmierung Bezieht sich auf Lösungen, die die Anwendung von Operationen auf einen gesamten Satz von Werten gleichzeitig ermöglichen. Solche Lösungen werden üblicherweise in verwendet wissenschaftlich und Ingenieurwesen die Einstellungen.

Moderne Programmiersprachen, die Array -Programmierung unterstützen (auch bekannt als Vektor oder mehrdimensional Sprachen) wurden speziell entwickelt, um den Vorgängen zu verallgemeinern Skalare transparent anwenden auf Vektoren, Matrizen, und höherdimensionale Arrays. Diese beinhalten Apl, J, Forran 90, Matlab, Analytica, TK -Löser (als Listen),, Oktave, R, Cilk Plus, Julia, Perl Data Language (PDL). In diesen Sprachen kann eine Operation, die auf ganzen Arrays arbeitet vektorisiert Betrieb,[1] unabhängig davon, ob es auf einem ausgeführt wird Vektorprozessor, was Vektoranweisungen implementiert. Array -Programmierprimitive drücken präzise breite Ideen zur Datenmanipulation aus. Der Spiegelungsgrad kann in bestimmten Fällen dramatisch sein: Es ist nicht ungewöhnlich[Beispiel erforderlich] Um Array -Programmiersprache zu finden Einzeiler Das erfordern mehrere Seiten objektorientierter Code.

Konzepte von Array

Die grundlegende Idee hinter der Array -Programmierung besteht darin, dass Operationen gleichzeitig für eine ganze Reihe von Werten gelten. Das macht es a Programmierung auf hoher Ebene Das Modell, das es dem Programmierer ermöglicht, auf ganze Daten zu denken und zu arbeiten, ohne auf explizite Schleifen einzelner skalarer Operationen zurückgreifen zu müssen.

Kenneth E. Iverson beschrieb die Begründung hinter Array -Programmierung (tatsächlich bezieht sich auf APL) wie folgt:[2]

Die meisten Programmiersprachen sind der mathematischen Notation deutlich unterlegen und werden nur wenig als Gedankenwerkzeuge verwendet, die beispielsweise durch einen angewandten Mathematiker als signifikant angesehen werden.

Die These ist, dass die Vorteile von Ausführbarkeit und Universalität in Programmiersprachen in einer einzigen kohärenten Sprache effektiv kombiniert werden können, wobei die Vorteile der mathematischen Notation angeboten werden. Es ist wichtig, die Schwierigkeit zu unterscheiden, eine Notation von der Schwierigkeit zu beschreiben und zu lernen, ihre Auswirkungen zu beherrschen. Zum Beispiel ist das Erlernen der Regeln für die Berechnung eines Matrixprodukts einfach, aber eine Beherrschung seiner Auswirkungen (wie der Assoziativität, der Verteilung über Zugabe und seiner Fähigkeit, lineare Funktionen und geometrische Operationen darzustellen), ist eine andere und viel schwierigere Angelegenheit .

In der Tat kann die Suggestivität einer Notation es aufgrund der vielen Eigenschaften, die sie für Erkundungen vorschlägt, schwieriger erscheinen lassen.

[...]

Benutzer von Computern und Programmiersprachen befassen sich häufig hauptsächlich mit der Effizienz der Ausführung von Algorithmen und können daher viele der hier vorgestellten Algorithmen abweisen. Eine solche Entlassung würde kurzsichtig sein, da eine klare Aussage eines Algorithmus normalerweise als Grundlage verwendet werden kann, von der man leicht einen effizienteren Algorithmus ableiten kann.

Die Basis hinter Array -Programmierung und -Kemine besteht darin, die Eigenschaften von Daten zu finden und auszunutzen, bei denen einzelne Elemente ähnlich oder benachbart sind. Im Gegensatz zur Objektorientierung, die die Daten implizit in ihre Bestandteile aufbricht (oder Skalar Mengen), Array -Orientierung sieht zu Gruppendaten und wendet ein einheitliches Handling an.

Der Funktionsrang ist ein wichtiges Konzept für Array -Programmiersprachen im Allgemeinen im Allgemeinen analog zu Array Tensor Rang in Mathematik: Funktionen, die auf Daten arbeiten, können durch die Anzahl der Dimensionen klassifiziert werden, auf die sie reagieren. Die gewöhnliche Multiplikation ist beispielsweise eine skalarrangige Funktion, da sie mit nulldimensionalen Daten (einzelne Zahlen) arbeitet. Das Kreuzprodukt Der Betrieb ist ein Beispiel für eine Vektorrangfunktion, da sie auf Vektoren und nicht auf Skalaren arbeitet. Matrix-Multiplikation ist ein Beispiel für eine 2-Rang-Funktion, da sie mit zweidimensionalen Objekten (Matrizen) arbeitet. Kollapsbetreiber Reduzieren Sie die Dimensionalität eines Eingangsdatenarrays um eine oder mehrere Dimensionen. Beispielsweise bricht das Summieren über Elemente das Eingangsarray um 1 Dimension zusammen.

Verwendet

Array -Programmierung ist sehr gut geeignet für implizite Parallelisierung; Ein Thema vieler Forschung heutzutage. Des Weiteren, Intel und kompatible CPUs, die nach 1997 entwickelt und hergestellt wurden MMX und weitermachen SSSE3 und 3dnow!, einschließlich rudimentärer Simd Array -Funktionen. Die Array -Verarbeitung unterscheidet sich von unterscheidet sich von Parallelverarbeitung In diesem einen physischen Prozessor führt der physische Prozessor gleichzeitig Operationen auf einer Gruppe von Elementen durch, während die parallele Verarbeitung darauf abzielt, ein größeres Problem in kleinere aufzuteilen ((Mimd) von zahlreichen Prozessoren stücklos gelöst zu werden. Prozessoren mit zwei oder mehr Kernen werden heute immer häufiger.

Sprachen

Die kanonischen Beispiele für Array -Programmiersprachen sind Forran, Apl, und J. Andere umfassen: A+, Analytica, Kapelle, Idl, Julia, K, Klong, Q, Matlab, Gnu octave, PDL, R, Slang, SACK, Nial, Zpl und Ti-basic.

Skalarsprachen

In skalaren Sprachen wie z. C und Pascal, Operationen gelten nur für einzelne Werte, also a+b drückt die Zugabe von zwei Zahlen aus. In solchen Sprachen erfordert das Hinzufügen eines Arrays zu einem anderen eine Indexierung und Looping, deren Codierung mühsam ist.

zum (i = 0; i < n; i++)   zum (j = 0; j < n; j++)   a[i][j] += b[i][j]; 

In Array-basierten Sprachen, beispielsweise in Forran, kann der verschachtelte Verschachtel oben in Array-Format in einer Zeile geschrieben werden.

a = a + b 

oder alternativ, um die Array -Natur der Objekte zu betonen,

a(:, :) = a(:, :) + b(:, :) 

Während Skalarsprachen wie C als Teil der richtigen Sprache keine nativen Array -Programmierelemente haben, bedeutet dies nicht, dass Programme, die in diesen Sprachen geschrieben wurden Vektorbasierte Anweisungen Wenn es sie hat oder durch Verwendung mehrerer CPU -Kerne). Einige C -Compiler mögen GCC Bei einigen Optimierungsebenen erkennen und vektorisieren Sie Codeabschnitte, die seine Heuristik bestimmen würde. Ein anderer Ansatz wird von der gegeben OpenMP API, mit der man die geltenden Codeabschnitte parallelisieren kann, indem mehrere CPU -Kerne profitieren.

Arraysprachen

In Array -Sprachen sind Operationen verallgemeinert, um sowohl für Skalare als auch für Arrays zu gelten. Daher, a+b drückt die Summe von zwei Skalaren aus, wenn a und b sind Skalare oder die Summe von zwei Arrays, wenn es sich um Arrays handelt.

Eine Array -Sprache vereinfacht die Programmierung, aber möglicherweise zu einem Preis, der als die bezeichnet wird Abstraktionsstrafe.[3][4][5] Da die Ergänzungen isoliert vom Rest der Kodierung isoliert werden, produzieren sie möglicherweise nicht das optimalste effizient Code. (Zum Beispiel können Anschlüsse anderer Elemente desselben Arrays anschließend während derselben Ausführung auftreten, was zu unnötigen wiederholten Lookups führt.) Selbst die anspruchsvollsten Compiler optimieren Es wäre extrem schwer, zwei oder anscheinend unterschiedliche Funktionen zu malken, die in verschiedenen Programmabschnitten oder Unterroutinen erscheinen könnten Überkopf).

Ada

Der vorherige C -Code würde in der Folgendes werden Ada Sprache,[6] Dies unterstützt die Array-Programmierungssyntax.

A : = A + B; 

Apl

APL verwendet Unicode -Symbole für einzelne Zeichen ohne syntaktische Zucker.

A  A + B 

Diese Operation funktioniert auf Arrays eines beliebigen Ranges (einschließlich Rang 0) sowie auf einem Skalar und einem Array. Dyalog APL erweitert die Originalsprache mit Erweiterte Aufgaben:

A + B 

Analytica

Analytica bietet die gleiche Ausdruckswirtschaft wie ADA.

A: = a + b;

BASIC

Dartmouth Basic hatte MAT -Anweisungen für die Manipulation von Matrix und Array in seiner dritten Ausgabe (1966).

Schwach A(4),B(4),C(4) MATTE A = 1 MATTE B = 2 * A MATTE C = A + B MATTE DRUCKEN A,B,C 

Mata

Stata's Matrix -Programmiersprache Mata unterstützt die Array -Programmierung. Im Folgenden veranschaulichen wir Addition, Multiplikation, Zugabe einer Matrix und eines Skalars, Elements nach Elementmultiplikation, Abonnement und einer der vielen inversen Matrixfunktionen von MATA.

. Mata:: A = ((1,2,3) \ (4,5,6) : EIN 1  2  3  +-------------+  1 | 1  2  3  | 2 | 4  5  6  | +-------------+ : B = ((2..4) \ (1..3) : B 1  2  3  +-------------+  1 | 2  3  4  | 2 | 1  2  3  | +-------------+ : C = J(3,2,1) // a 3 mal 2 Matrix von Einen : C 1  2  +---------+  1 | 1  1  | 2 | 1  1  | 3 | 1  1  | +---------+ : D = a + B: d 1  2  3  +-------------+  1 | 3  5  7  | 2 | 5  7  9  | +-------------+ : E = a*C: e 1  2  +-----------+  1 | 6  6  | 2 | 15  15  | +-----------+ : F = a:*B: f 1  2  3  +----------------+  1 | 2  6  12  | 2 | 4  10  18  | +----------------+ : G = e:+ 3 : G 1  2  +-----------+  1 | 9  9  | 2 | 18  18  | +-----------+ : H = f [((2\1), (1, 2)] // Abonnement, um eine Submatrix von F und zu erhalten : // Zeile 1 und 2 schalten : H 1  2  +-----------+  1 | 4  10  | 2 | 2  6  | +-----------+ : I = Invsym(F'*F) // verallgemeinerte inverse (f*f^(-1) f = f) von a : // symmetrische positive halbdefinite Matrix : I [symmetrisch] 1  2  3  +-------------------------------------------+  1 | 0                              | 2 | 0  3.25                | 3 | 0  -1.75   .9444444444  | +-------------------------------------------+ : Ende 

Matlab

Die Implementierung in Matlab Ermöglicht die gleiche Wirtschaft, die durch die Verwendung der FORTRAN -Sprache zulässig ist.

A = A + B; 

Eine Variante der Matlab -Sprache ist die Gnu octave Sprache, die die Originalsprache mit erweiterten Aufgaben erweitert:

A += B; 

Sowohl Matlab als auch GNU Octave unterstützen nativ nativ Lineare Algebra Operationen wie Matrixmultiplikation, Matrixinversionund die numerische Lösung von System der linearen Gleichungen, sogar die Verwendung der Moore -Penrose Pseudoinverse.[7][8]

Das Nial Beispiel für das innere Produkt von zwei Arrays kann mit dem nativen Matrix -Multiplikationsoperator implementiert werden. Wenn a ist ein Zeilenvektor der Größe [1 n] und b ist ein entsprechender Spaltenvektor der Größe [n 1].

a * b;

Das innere Produkt zwischen zwei Matrizen mit derselben Anzahl von Elementen kann mit dem Hilfsbetreiber implementiert werden (:), die eine bestimmte Matrix in einen Säulenvektor umformulieren und die Transponieren Operator ':

A (:) ' * b (:);

Rasql

Das Rasdaman Query Language ist eine datenbankorientierte Arrayprogrammierungssprache. Beispielsweise könnten zwei Arrays mit der folgenden Abfrage hinzugefügt werden:

AUSWÄHLEN A + B AUS  A, B 

R

Die R -Sprache unterstützt standardmäßig das Array -Paradigma. Das folgende Beispiel veranschaulicht einen Multiplikationsprozess von zwei Matrizen, gefolgt von einer Zugabe eines Skalars (was tatsächlich ein Einselementvektor ist) und eines Vektors:

> A <- Matrix(1:6, Nrow=2)  #!! Das hat nrow = 2 ... und a hat 2 Zeilen > A  [,1] [,2] [,3] [1,]  1  3  5 [2,]  2  4  6 > B <- t( Matrix(6:1, Nrow=2) )  # t () ist ein Transponierungsbetreiber !! Dies hat NROW = 2 ... und B hat 3 Zeilen-ein klarer Widerspruch zur Definition von a > B  [,1] [,2] [1,]  6  5 [2,]  4  3 [3,]  2  1 > C <- A %*% B > C  [,1] [,2] [1,]  28  19 [2,]  40  28 > D <- C + 1 > D  [,1] [,2] [1,]  29  20 [2,]  41  29 > D + c(1, 1)  # C () erstellt einen Vektor  [,1] [,2] [1,]  30  21 [2,]  42  30 

Mathematisches Denken und Sprachnotation

Der Matrix linke Divisionsbetreiber drückt präzise einige semantische Eigenschaften von Matrizen aus. Wie im skalaren Äquivalent, wenn die (bestimmend des) Koeffizienten (Matrix) A ist nicht null, dann ist es möglich, die (vektorielle) Gleichung zu lösen A * x = b durch linke Multiplizierung beider Seiten durch die umgekehrt von A: A - 1 (Sowohl in Matlab- als auch in GNU -Oktavensprachen: A^-1). Die folgenden mathematischen Aussagen halten wenn A ist ein Voller Rang quadratische Matrix:

A^-1 * (a * x) == a^-1 * (b)
(A^-1 * a) * x == a^-1 * b (Matrix-Multiplikation Assoziativität)
x = a^-1 * b

wo == ist die Äquivalenz relationaler Operator. Die vorherigen Aussagen sind auch gültige MATLAB-Ausdrücke, wenn der dritte vor den anderen ausgeführt wird (numerische Vergleiche können aufgrund von Rundenfehlern falsch sein).

Wenn das System überbestimmt ist - so dass das A hat mehr Zeilen als Spalten - die Pseudoinverse A+ (In Matlab- und GNU -Oktavensprachen: Pinv (a)) kann die Inverse ersetzen A - 1, folgendermaßen:

pinv (a) * (a * x) == pinv (a) * (b)
(pinv (a) * a) * x == Pinv (a) * b (Assoziativität der Matrix-Multiplikation)
x = pinv (a) * b

Diese Lösungen sind jedoch weder die prägnantesten (z. B. bleibt nach wie vor die Notwendigkeit, überbestimmte Systeme notational differenzieren) noch die rechenintensivsten. Der letztere Punkt ist leicht zu verstehen, wenn man das skalare Äquivalent erneut in Betracht zieht a * x = bfür die Lösung x = a^-1 * b würde zwei Operationen anstelle von effizienter erfordern x = b / a. Das Problem ist, dass Matrixmultiplikationen im Allgemeinen nicht sind kommutativ Da die Erweiterung der skalaren Lösung auf den Matrix -Fall erforderlich wäre:

(a * x) / a == b / a
(x * a) / a == b / a (Die Kommunikation ist nicht für Matrizen!)
x * (a / a) == b / a (Assoziativität gilt auch für Matrizen)
x = b / a

Die MATLAB-Sprache führt den Operator für die linke Abteilung vor \ Um den wesentlichen Teil der Analogie zum skalaren Fall aufrechtzuerhalten, die mathematische Argumentation zu vereinfachen und die Übersicht aufrechtzuerhalten:

A \ (a * x) == a \ b
(A \ a)* x == a \ b (Die Assoziativität gilt auch für Matrizen. Die Kommunikation ist nicht mehr erforderlich)
x = a \ b

Dies ist nicht nur ein Beispiel für eine knappe Array -Programmierung aus der Sicht des Codierung, sondern auch aus der Sicht der Recheneffizienz, die in mehreren Array -Programmiersprachen von recht effizienten linearen Algebra -Bibliotheken wie z. B. profitiert ATLAS oder Lapack.[9]

Als Rückkehr zum vorherigen Zitat von Iverson sollte die Begründung dahinter jetzt offensichtlich sein:

Es ist wichtig, die Schwierigkeit zu unterscheiden, eine Notation von der Schwierigkeit zu beschreiben und zu lernen, ihre Auswirkungen zu beherrschen. Zum Beispiel ist das Erlernen der Regeln für die Berechnung eines Matrixprodukts einfach, aber eine Beherrschung seiner Auswirkungen (wie der Assoziativität, der Verteilung über Zugabe und seiner Fähigkeit, lineare Funktionen und geometrische Operationen darzustellen), ist eine andere und viel schwierigere Angelegenheit . In der Tat kann die Suggestivität einer Notation es aufgrund der vielen Eigenschaften, die sie für Erkundungen vorschlägt, schwieriger erscheinen lassen.

Bibliotheken von Drittanbietern

Die Verwendung von spezialisierten und effizienten Bibliotheken zur Bereitstellung von stärkeren Abstraktionen ist auch in anderen Programmiersprachen üblich. Im C ++ Mehrere lineare Algebra -Bibliotheken nutzen die Fähigkeit der Sprache dazu Overload -Operatoren. In einigen Fällen wird eine sehr knappe Abstraktion in diesen Sprachen explizit durch das Array -Programmierparadigma als das beeinflusst Numpy Erweiterungsbibliothek an Python, Gürteltier und Blitz ++ Bibliotheken tun es.[10][11]

Siehe auch

Verweise

  1. ^ Stéfan van der Walt; S. Chris Colbert & Gaël Varoquaux (2011). "Das Numpy Array: eine Struktur für eine effiziente numerische Berechnung". Computing in Wissenschaft und Ingenieurwesen. IEEE. 13 (2): 22–30. Arxiv:1102.1523. Bibcode:2011cse .... 13b..22v. doi:10.1109/MCSE.2011.37. S2CID 16907816.
  2. ^ Iverson, K. E. (1980). "Notationen als Gedankenwerkzeug". Kommunikation der ACM. 23 (8): 444–465. doi:10.1145/358896.358899.
  3. ^ Surana P (2006). Metakompilierung von Sprachabstraktionen (These).
  4. ^ Kuketayev. "Die Datenabstraktionsstrafe (DAP) für kleine Objekte in Java". Archiviert von das Original am 2009-01-11. Abgerufen 2008-03-17.
  5. ^ Chatzigeorgiou; Stephanides (2002). "Bewertung der Leistung und Leistung von objektorientiertem vs. prozeduraler Programmiersprachen". In Blieberger; Strohmeier (Hrsg.). Proceedings - 7. Internationale Konferenz über zuverlässige Softwaretechnologien - ADA -Europe'2002. Springer. p. 367. ISBN 978-3-540-43784-0.
  6. ^ ADA -Referenzhandbuch: G.3.1 Reale Vektoren und Matrizen
  7. ^ "GNU -Oktavhandbuch. Arithmetische Operatoren". Abgerufen 2011-03-19.
  8. ^ "Matlab -Dokumentation. Arithmetische Operatoren". Abgerufen 2011-03-19.
  9. ^ "GNU Octave Manual. Anhang G Installation der Oktave". Abgerufen 2011-03-19.
  10. ^ "Referenz für Armadillo 1.1.8. Beispiele für die MATLAB/Octave -Syntax und die konzeptionell entsprechende Armadillo -Syntax". Abgerufen 2011-03-19.
  11. ^ "Blitz ++ Benutzerhandbuch. 3. Array -Ausdrücke". Archiviert von das Original Am 2011-03-23. Abgerufen 2011-03-19.

Externe Links