Trygonometria macierzowa

13

Wprowadzenie

Dwa najbardziej popularne funkcje trygonometryczne, sinei cosine(lub sini coskrócej), może być rozszerzone do funkcji matrycy wartościach. Jednym ze sposobów obliczenia analogów wycenianych w macierzy jest:

Rozważ te dwie ważne tożsamości trygonometryczne:

wyzwalać tożsamości

Używając tych tożsamości, możemy wyprowadzić następujące równania dla sini cos:

funkcje trig

Wykładniczy matrycy istnieje dla matryc kwadratowych i jest przez:

wykładnicza macierzowa

gdzie 0 jest macierz identyczności I o tych samych wymiarach jak A . Korzystając z macierzy wykładniczej, te dwie funkcje trygonometryczne (a zatem wszystkie pozostałe funkcje trygonometryczne) można ocenić jako funkcje macierzy.

Wyzwanie

Biorąc pod uwagę macierz kwadratową A , wypisz wartości sin(A)i cos(A).

Zasady

  • Dane wejściowe i wyjściowe mogą być w dowolnym dogodnym, rozsądnym formacie (macierz 2D, format macierzy języka itp.).
  • Możesz napisać pojedynczy program, dwa niezależne programy, jedną funkcję lub dwie funkcje. Jeśli zdecydujesz się napisać dwie funkcje, kod może być współdzielony między nimi (np. Funkcje importu i pomocnicze).
  • Wartościami macierzy wejściowej zawsze będą liczby całkowite.
  • Twoje rozwiązanie może mieć problemy z dokładnością w wyniku niedokładności zmiennoprzecinkowej. Jeśli twój język ma magiczne wartości nieskończonej precyzji, twoje rozwiązanie powinno działać idealnie (ignorując fakt, że wymagałoby to nieskończonego czasu i / lub pamięci). Ponieważ jednak te magiczne wartości nieskończonej precyzji nie istnieją, niedokładności spowodowane ograniczoną precyzją są dopuszczalne. Zasada ta ma na celu uniknięcie komplikacji wynikających z wymagania określonej precyzji w danych wyjściowych.
  • Wbudowane funkcje obliczające funkcje trygonometryczne dla argumentów macierzy (w tym hiperboliczne funkcje wyzwalania) są niedozwolone. Inne wbudowane macierze (takie jak mnożenie, potęgowanie, diagonalizacja, rozkład i wykładniczy macierz) są dozwolone.

Przypadki testowe

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]]

Dalsza lektura

To doskonałe pytanie w Math.SE obejmuje kilka alternatywnych pochodnych macierzy analogów funkcji trygonometrycznych.

Mego
źródło
Mam sin([[1, 0, 1], [0, 0, 0], [0, 1, 0]]) = {{0.841, -0.158, 0.841}, {0, 0, 0}, {0, 1, 0}}z Mathematica, możesz sprawdzić?
kennytm
1
@kennytm To pokazuje przypadek testowy.
Mego
1
@Mego Najwyraźniej wszystkie istniejące odpowiedzi powinny zostać usunięte.
feersum
3
@Mego Nie ma sensu myśleć, że wszystkie wbudowane funkcje zmiennoprzecinkowe używają dokładnego algorytmu (lub takiego, który byłby dokładny, gdyby operacje zmiennoprzecinkowe zostały zastąpione operacjami „liczb rzeczywistych”).
feersum
1
@feersum Zajęłam się tym w mojej ostatniej edycji:(ignoring the fact that it would require infinite time and/or memory)
Mego

Odpowiedzi:

6

Julia, 33 19 bajtów

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

Jest to funkcja, która akceptuje dwuwymiarową tablicę liczb zmiennoprzecinkowych i zwraca krotkę takich tablic odpowiadających odpowiednio cosinus i sinus. Zauważ, że jest to odwrotność kolejności podanej w przypadkach testowych, w których sinus jest wymieniony jako pierwszy.

Dla macierzy A o wartościach rzeczywistych mamy

sinus

i

cosinus

To znaczy, sinus i cosinus A odpowiadają wyobrażonym i rzeczywistym częściom macierzy wykładniczej e iA . Zobacz funkcje macierzy (Higham, 2008).

Wypróbuj online! (obejmuje wszystkie przypadki testowe)

Zaoszczędzono 14 bajtów dzięki Dennisowi!

Alex A.
źródło
6

Mathematica, 27 bajtów

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

Na podstawie @ Rainer P. roztworu „s.

Bierze macierz kwadratową Ajako argument i wyświetla listę zawierającą {sin(A), cos(A)}.

Dane wejściowe są sformatowane w Ncelu otrzymania wartości liczbowych, zamiast długiego Dokładny wzór i Columnwyświetlanie wyników sin(A)i cos(A)w postaci oddzielnych matryc zamiast zagnieżdżonej listy.

Przykład

Obliczanie wartości osobno wymaga 38 bajtów

{(#2-#)I,+##}/2&@@MatrixExp/@{I#,-I#}&
mile
źródło
6

Galaretka , 23 22 bajtów

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

Wypróbuj online!

tło

To podejście bezpośrednio oblicza szereg Taylora dla sinusa i cosinusa , tj.

formuła

Zwiększa liczbę początkowych składników obu serii, dopóki wynik się nie zmienia, więc jego dokładność jest ograniczona jedynie precyzją typu zmiennoprzecinkowego.

Jak to działa

®Ḥ‘©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.
Dennis
źródło
3

C ++, 305 bajtów

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

Dane wejściowe to lista liczb, które są idealnym kwadratem na standardowym wejściu. Wyjście to ładnie wydrukowana tablica 2d na standardowym wyjściu

HSchmale
źródło
2

Matlab, 138 121 52 50 bajtów

Ponieważ dozwolone jest potęgowanie macierzy (czego wcześniej nie zauważyłem, d'oh), nie muszę już definiować funkcji pomocnika, a całość można rozwiązać w trywialny sposób:

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

Dane wejściowe powinny być macierzą, np. [1,2;4,5]Lub alternatywnie[[1,2];[3,4]]

Nieoczekiwaną rzeczą (z perspektywy czasu nie taką nieoczekiwaną) jest to, że macierz cosinus i sinus nadal spełnia

I = sin(A)^2+cos(A)^2
wada
źródło
Czy to nie A^0to samo co eye(size(A))?
FryAmTheEggman
Och, masz rację, dziękuję!
flawr
2
Dlaczego nie użyć expm?
Luis Mendo,
2
Co do tożsamości: mam nadzieję, że spełnią tę tożsamość, biorąc pod uwagę, że forma skalarna została użyta do rozszerzenia funkcji na macierze!
Mego
1
Cóż, wtedy cała sprawa staje się prawie banalna.
flawr
2

Matlab, 37 bajtów

@(A){imag(expm(i*A));real(expm(i*A))}
Rainer P.
źródło
0

Julia 0.4, 28 bajtów

A->imag({E=expm(im*A),im*E})

Dane wejściowe to macierz liczb zmiennoprzecinkowych, dane wyjściowe to tablica macierzy. Wypróbuj online!

Dennis
źródło
0

Sage, 44 bajty

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

Wypróbuj online .

Ta anonimowa funkcja zwraca listę 2 macierzy odpowiadających odpowiednio sin(A)i cos(A). exp(I*A)oblicza wykładniczą macierz dla I*A( Aze wszystkimi elementami pomnożonymi przez urojoną jednostkę) i matrix.apply_map(f)zwraca macierz, w której fzastosowano wszystkie jej elementy. Stosując imagi real(funkcje do uzyskiwania wyobrażonych i rzeczywistych części wartości skalarnej) do macierzy, otrzymujemy wartości sin(A)i cos(A)dzięki słynnej tożsamości Eulera (o której mowa w tekście wyzwania).

Mego
źródło