Trigonometria a matrice


13

introduzione

Le due funzioni trigonometriche più comuni, sinee cosine(o sine cosin breve), possono essere estesi ad essere funzioni di matrici a valori. Un modo per calcolare gli analoghi valutati a matrice è il seguente:

Considera queste due importanti identità trigonometriche:

identità di trigoni

Usando queste identità, possiamo derivare le seguenti equazioni per sine cos:

funzioni di trigger

La matrice esponenziale esiste per tutte le matrici quadrate ed è data da:

matrice esponenziale

dove A 0 è la matrice identità che con le stesse dimensioni A . Usando l'esponenziale della matrice, queste due funzioni trigonometriche (e quindi tutte le altre funzioni trigonometriche) possono essere valutate come funzioni di matrici.

La sfida

Data una matrice quadrata A , genera i valori di sin(A)e cos(A).

Regole

  • L'input e l'output possono essere in qualsiasi formato conveniente e ragionevole (array 2D, formato matrice della tua lingua, ecc.).
  • È possibile scrivere un singolo programma, due programmi indipendenti, una singola funzione o due funzioni. Se si sceglie di scrivere due funzioni, il codice potrebbe essere condiviso tra loro (come le funzioni di importazione e di supporto).
  • I valori della matrice di input saranno sempre numeri interi.
  • La soluzione potrebbe presentare problemi di precisione a causa dell'imprecisione in virgola mobile. Se il tuo linguaggio aveva magici valori di precisione infinita, allora la tua soluzione dovrebbe funzionare perfettamente (ignorando il fatto che richiederebbe tempo e / o memoria infiniti). Tuttavia, poiché non esistono quei magici valori di precisione infinita, sono inaccettabili le imprecisioni causate da una precisione limitata. Questa regola è in atto per evitare complicazioni derivanti dalla richiesta di una quantità specifica di precisione nell'output.
  • Non sono consentiti i builtin che calcolano le funzioni trigonometriche per gli argomenti di matrice (comprese le funzioni di trigocia iperbolica). Sono consentiti altri built-in di matrice (come moltiplicazione, esponenziazione, diagonalizzazione, decomposizione ed esponenziale della matrice).

Casi test

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

Ulteriori letture

Questa eccellente domanda di Math.SE include alcune derivazioni alternative degli analoghi valutati a matrice di funzioni trigonometriche.


Ho avuto sin([[1, 0, 1], [0, 0, 0], [0, 1, 0]]) = {{0.841, -0.158, 0.841}, {0, 0, 0}, {0, 1, 0}}con Mathematica, puoi controllare?
kennytm,

1
@kennytm Questo è ciò che mostra il caso di test.
Mego,

1
@Mego Apparentemente allora tutte le risposte esistenti dovrebbero essere eliminate.
feersum

3
@Mego È del tutto irragionevole pensare che tutti i builtin basati su virgola mobile utilizzino un algoritmo esatto (o uno che sarebbe esatto se le operazioni in virgola mobile fossero sostituite con operazioni con "numero reale").
feersum

1
@feersum L'ho affrontato nella mia ultima modifica:(ignoring the fact that it would require infinite time and/or memory)
Mego

Risposte:


6

Julia, 33 19 byte

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

Questa è una funzione che accetta una matrice bidimensionale di float e restituisce una tupla di tali array che corrispondono rispettivamente al coseno e al seno. Si noti che questo è il contrario dell'ordine indicato nei casi di test, in cui seno viene elencato per primo.

Per una matrice con valore reale A , abbiamo

seno

e

coseno

Cioè, il seno e il coseno di A corrispondono alle parti immaginarie e reali della matrice esponenziale e iA . Vedi funzioni delle matrici (Higham, 2008).

Provalo online! (include tutti i casi di test)

Salvato 14 byte grazie a Dennis!


6

Mathematica, 27 byte

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

Basato su @ Rainer P. soluzione s'.

Prende la matrice quadrata A come argomento e genera un elenco contenente {sin(A), cos(A)}.

L'input è formattato con Nper ottenere un valore numerico anziché una formula lunga e esatta e Columnper visualizzare i risultati di sin(A)e cos(A)come matrici separate anziché un elenco nidificato.

Esempio

Il calcolo dei valori separatamente richiede 38 byte

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

6

Gelatina , 23 22 byte

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

Provalo online!

sfondo

Questo approccio calcola direttamente la serie di Taylor per seno e coseno , ovvero

formula

Aumenta il numero di termini iniziali di entrambe le serie fino a quando il risultato non cambia più, quindi la sua precisione è limitata solo dalla precisione del tipo a virgola mobile.

Come funziona

®Ḥ‘©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 byte

Poiché l'espiazione della matrice è consentita, (ciò che non ho notato prima, d'oh) non ho più bisogno di definire la mia funzione di aiuto, e il tutto può essere banalmente risolto:

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

L'ingresso dovrebbe essere una matrice, ad esempio [1,2;4,5]o in alternativa[[1,2];[3,4]]

Una cosa inaspettata (col senno di poi non così inaspettata) è che la matrice del coseno e del seno continua a soddisfare

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

Non è A^0lo stesso di eye(size(A))?
FryAmTheEggman,

Oh, hai ragione, grazie!
flawr

2
Perché non usare expm?
Luis Mendo,

2
Per quanto riguarda l'identità: spero che soddisfino quell'identità, considerando che la forma scalare è stata utilizzata per estendere le funzioni alle matrici!
Mego,

1
Bene, allora tutto diventa quasi banale.
flawr


2

C ++, 305 byte

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

L'input è un elenco di numeri che sono un quadrato perfetto su stdin. L'output è un array 2d piuttosto stampato su stdout


0

Julia 0.4, 28 byte

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

L'input è una matrice di float, l'output è una matrice di matrici. Provalo online!


0

Sage, 44 byte

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

Provalo online .

Questa funzione anonima restituisce un elenco di 2 matrici corrispondenti rispettivamente a sin(A)e cos(A). exp(I*A)calcola la matrice esponenziale per I*A( Acon tutti gli elementi moltiplicati per l'unità immaginaria) e matrix.apply_map(f)restituisce una matrice in cui fè stata applicata a tutti i suoi elementi. Applicando image real(le funzioni per ottenere le parti immaginarie e reali di un valore scalare) alle matrici, otteniamo i valori sin(A)e cos(A), grazie alla famosa identità di Eulero (citata nel testo della sfida).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.