Matrix-Trigonometrie


13

Einführung

Die beiden häufigsten trigonometrische Funktionen, sineund cosine(oder sinund coskurz), kann erweitert werden , matrixWertFunktionen sind. Eine Möglichkeit, die Analoga mit Matrixwerten zu berechnen, ist die folgende:

Betrachten Sie diese beiden wichtigen trigonometrischen Identitäten:

Identitäten auslösen

Unter Verwendung dieser Identitäten können wir die folgenden Gleichungen für sinund ableiten cos:

Triggerfunktionen

Das Matrixexponential existiert für alle quadratischen Matrizen und ist gegeben durch:

Matrix Exponential

wobei A 0 die Identitätsmatrix I mit den gleichen Dimensionen wie A ist . Mit der Matrixexponentialfunktion können diese beiden trigonometrischen Funktionen (und damit alle anderen trigonometrischen Funktionen) als Funktionen von Matrizen ausgewertet werden.

Die Herausforderung

Geben Sie bei einer quadratischen Matrix A die Werte von sin(A)und aus cos(A).

Regeln

  • Die Ein- und Ausgabe kann in jedem geeigneten, angemessenen Format erfolgen (2D-Array, Matrixformat Ihrer Sprache usw.).
  • Sie können ein einzelnes Programm, zwei unabhängige Programme, eine einzelne Funktion oder zwei Funktionen schreiben. Wenn Sie zwei Funktionen schreiben möchten, wird der Code möglicherweise von beiden gemeinsam genutzt (z. B. Import- und Hilfsfunktionen).
  • Die Werte der Eingabematrix sind immer ganze Zahlen.
  • Ihre Lösung kann aufgrund von Gleitkommaungenauigkeiten Genauigkeitsprobleme aufweisen. Wenn Ihre Sprache magische Werte mit unendlicher Genauigkeit aufweist, sollte Ihre Lösung einwandfrei funktionieren (ohne die Tatsache zu berücksichtigen, dass dafür unendliche Zeit und / oder Speicher erforderlich wären). Da es diese magischen Werte mit unendlicher Genauigkeit nicht gibt, sind Ungenauigkeiten aufgrund begrenzter Genauigkeit akzeptabel. Diese Regel dient zur Vermeidung von Komplikationen, die sich aus der Anforderung einer bestimmten Genauigkeit der Ausgabe ergeben.
  • Builtins, die trigonometrische Funktionen für Matrixargumente berechnen (einschließlich hyperbolischer Triggerfunktionen), sind nicht zulässig. Andere Matrix-Buildins (wie Multiplikation, Exponentiation, Diagonalisierung, Zerlegung und die Exponentialmatrix) sind zulässig.

Testfälle

Format: A -> sin(A), cos(A)

[[0]] -> [[0]], [[1]]
[[0, 2], [3, 5]] -> [[-0.761177343863758, 0.160587281888277], [0.240880922832416, -0.359709139143065]], [[0.600283445979886, 0.119962280223493], [0.179943420335240, 0.900189146538619]]
[[1, 0, 1], [0, 0, 0], [0, 1, 0]] -> [[0.841470984807897, -0.158529015192103, 0.841470984807897], [0, 0, 0], [0, 1, 0]], [[0.540302305868140, -0.459697694131860, -0.459697694131860], [0, 1, 0], [0, 0, 1]]
[[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]] -> [[0.841470984807897, 0, 0, 0, 0], [0, 0.841470984807897, 0, 0, 0], [0, 0, 0.841470984807897, 0, 0], [0, 0, 0, 0.841470984807897, 0], [0, 0, 0, 0, 0.841470984807897]], [[0.540302305868140, 0, 0, 0, 0], [0, 0.540302305868140, 0, 0, 0], [0, 0, 0.540302305868140, 0, 0], [0, 0, 0, 0.540302305868140, 0], [0, 0, 0, 0, 0.540302305868140]]
[[-3, 2, -6], [3, 0, 4], [4, -2, 7]] -> [[-0.374786510963954, 0.135652884035570, -1.35191037980742], [1.14843105375406, 0.773644542790111, 1.21625749577185], [1.21625749577185, -0.135652884035570, 2.19338136461532]], [[4.13614256031450, -1.91289828483056, 5.50873853927692], [-2.63939111203107, 1.49675144828342, -3.59584025444636], [-3.59584025444636, 1.91289828483056, -4.96843623340878]]

Weitere Lektüre

Diese hervorragende Frage bei Math.SE enthält einige alternative Ableitungen der matrixwertigen Analoga trigonometrischer Funktionen.


Kannst sin([[1, 0, 1], [0, 0, 0], [0, 1, 0]]) = {{0.841, -0.158, 0.841}, {0, 0, 0}, {0, 1, 0}}du nachsehen, was ich mit Mathematica gemacht habe?
Kennytm

1
@kennytm Das zeigt der Testfall.
Mego

1
@Mego Anscheinend sollten dann alle vorhandenen Antworten gelöscht werden.
Feersum

3
@Mego Es ist völlig unvernünftig zu glauben, dass alle Gleitkomma-basierten Buildins einen exakten Algorithmus verwenden (oder einen, der exakt wäre, wenn Gleitkomma-Operationen durch "reelle Zahlen" -Operationen ersetzt würden).
Feersum

1
@feersum Ich habe das in meiner letzten Ausgabe angesprochen:(ignoring the fact that it would require infinite time and/or memory)
Mego

Antworten:


6

Julia, 33 19 Bytes

A->reim(expm(A*im))

Dies ist eine Funktion, die ein zweidimensionales Array von Floats akzeptiert und ein Tupel solcher Arrays zurückgibt, die dem Cosinus bzw. Sinus entsprechen. Beachten Sie, dass dies die Umkehrung der Reihenfolge ist, die in den Testfällen angegeben wurde, in denen der Sinus zuerst aufgeführt wird.

Für eine reelle Matrix A gilt:

Sinus

und

Kosinus

Das heißt, der Sinus und Kosinus von A entsprechen den imaginären und realen Teile der Matrix exponentiellen e iA . Siehe Funktionen von Matrizen (Higham, 2008).

Probieren Sie es online! (beinhaltet alle Testfälle)

14 Bytes gespart dank Dennis!


6

Mathematica, 27 Bytes

{Im@#,Re@#}&@MatrixExp[I#]&

Basierend auf der Lösung von @ Rainer P ..

Nimmt die quadratische Matrix Aals Argument und gibt eine Liste aus, die enthält {sin(A), cos(A)}.

Die Eingabe wird mit formatiert N, um einen numerischen Wert anstelle einer langen exakten Formel zu erhalten und Columndie Ergebnisse von sin(A)und cos(A)als separate Matrizen anstelle einer verschachtelten Liste anzuzeigen .

Beispiel

Die Berechnung der Werte erfordert gesondert 38 Byte

{(#2-#)I,+##}/2&@@MatrixExp/@{I#,-I#}&

6

Jelly , 23 22 Bytes

³æ*÷!
®Ḥ‘©r0Ç€s2_@/µÐL

Probieren Sie es online!

Hintergrund

Dieser Ansatz berechnet direkt die Taylor-Reihe für Sinus und Cosinus , dh

Formel

Erhöht die Anzahl der Anfangsterme beider Reihen, bis sich das Ergebnis nicht mehr ändert, sodass seine Genauigkeit nur durch die Genauigkeit des Gleitkommatyps begrenzt wird.

Wie es funktioniert

®Ḥ‘©r0Ç€s2_@/µÐL  Main link, Argument: A (matrix)

             µÐL  Loop; apply the chain until the results are no longer unique.
                  Return the last unique result.
®                   Yield the value of the register (initially zero).
 Ḥ                  Unhalve/double it.
  ‘©                Increment and copy the result (n) to the register.
    r0              Range; yield [n, ..., 0].
      ǀ            Apply the helper link to each k in the range.
        s2          Split the results into chunks of length 2. Since n is always
                    odd, this yields [[Ç(n), Ç(n-1)], ..., [Ç(1), Ç(0)]].
          _@/       Reduce the columns of the result by swapped subtraction,
                    yielding [Ç(1) - Ç(3) + ... Ç(n), Ç(0) - Ç(2) + ... Ç(n - 1)].


³æ*÷!             Helper link. Argument: k (integer)

³                 Yield the first command-line argument (A).
 æ*               Elevate A to the k-th power.
    !             Yield the factorial of k.
   ÷              Divide the left result by the right one.

2

Matlab, 138 121 52 50 Bytes

Da Matrix-Exponentiation erlaubt ist (was ich zuerst nicht bemerkt habe, oh), muss ich meine Helferfunktion nicht mehr definieren, und das Ganze kann trivial gelöst werden:

A=input('')*i;a=expm(A);b=expm(-A);[(b-a)*i,a+b]/2

Die Eingabe sollte zB [1,2;4,5]oder alternativ eine Matrix sein[[1,2];[3,4]]

Eine unerwartete Sache (im Nachhinein nicht so unerwartet) ist, dass die Cosinus- und Sinusmatrix immer noch befriedigen

I = sin(A)^2+cos(A)^2

Ist das nicht A^0dasselbe wie eye(size(A))?
FryAmTheEggman

Oh, du hast recht, danke!
Fehler

2
Warum nicht benutzen expm?
Luis Mendo

2
Bezüglich der Identität: Ich sollte hoffen, dass sie diese Identität erfüllen, wenn man bedenkt, dass die skalare Form verwendet wurde, um die Funktionen auf Matrizen zu erweitern!
Mego

1
Na dann wird das Ganze fast trivial.
Fehler


2

C ++, 305 Bytes

#include<cmath>
#include<iostream>
#include<vector>
int x,i=0, j;void p(std::vector<double> v){int x=sqrt(v.size());for(i=0;i<x;i++){for(j=0;j<x;j++) std::cout << v[x] << " ";std::cout << "\n";}}int main(){std::vector<double> s, c;while(std::cin >> x){s.push_back(sin(x));c.push_back(cos(x));}p(s);p(c);}

Die Eingabe ist eine Liste von Zahlen, die ein perfektes Quadrat für stdin darstellen. Die Ausgabe ist ein hübsch gedrucktes 2d-Array auf stdout



0

Salbei, 44 Bytes

lambda A:map(exp(I*A).apply_map,(imag,real))

Probieren Sie es online aus .

Diese anonyme Funktion gibt eine Liste von 2 Matrizen zurück, die sin(A)und entsprechencos(A) entsprechen. exp(I*A)berechnet die Exponentialmatrix für I*A( Awobei alle Elemente mit der imaginären Einheit multipliziert werden) und matrix.apply_map(f)gibt eine Matrix zurück f, auf die alle Elemente angewendet wurden. Indem wir imagund real(die Funktionen zum Abrufen der Imaginär- und Realteile eines Skalarwerts) auf die Matrizen anwenden , erhalten wir die Werte von sin(A)und cos(A), dank Eulers berühmter Identität (auf die im Herausforderungstext verwiesen wird).

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.