Matriks Trigonometri

13

pengantar

Dua fungsi trigonometri yang paling umum, sinedan cosine(atau sindan cosuntuk pendek), dapat diperpanjang menjadi fungsi matriks bernilai. Salah satu cara untuk menghitung analog bernilai matriks adalah sebagai berikut:

Pertimbangkan dua identitas trigonometri penting ini:

identitas trigonometri

Dengan menggunakan identitas ini, kita dapat memperoleh persamaan berikut untuk sindan cos:

fungsi trigonometri

The matriks eksponensial ada untuk semua matriks persegi dan diberikan oleh:

matriks eksponensial

di mana A 0 adalah matriks identitas I dengan dimensi yang sama seperti A . Menggunakan matriks eksponensial, dua fungsi trigonometri ini (dan dengan demikian semua fungsi trigonometri lainnya) dapat dievaluasi sebagai fungsi matriks.

Tantangan

Diberikan matriks kuadrat A , menampilkan nilai-nilai sin(A)dan cos(A).

Aturan

  • Input dan output mungkin dalam format apa pun yang nyaman dan wajar (array 2D, format matriks bahasa Anda, dll.).
  • Anda dapat menulis satu program, dua program independen, satu fungsi, atau dua fungsi. Jika Anda memilih untuk menulis dua fungsi, kode dapat dibagikan di antara mereka (seperti impor dan fungsi pembantu).
  • Nilai-nilai matriks input akan selalu berupa bilangan bulat.
  • Solusi Anda mungkin memiliki masalah akurasi sebagai akibat dari ketidaktepatan floating-point. Jika bahasa Anda memiliki nilai presisi tak terbatas magis, maka solusi Anda harus bekerja dengan sempurna (mengabaikan fakta bahwa itu akan membutuhkan waktu dan / atau memori tak terbatas). Namun, karena nilai presisi tak terbatas magis itu tidak ada, ketidakakuratan yang disebabkan oleh presisi terbatas dapat diterima. Aturan ini berlaku untuk menghindari komplikasi yang timbul karena membutuhkan sejumlah presisi dalam output.
  • Builtin yang menghitung fungsi trigonometri untuk argumen matriks (termasuk fungsi trigonometri hiperbolik) tidak diperbolehkan. Matriks bawaan lainnya (seperti multiplikasi, eksponensial, diagonalisasi, dekomposisi, dan matriks eksponensial) diperbolehkan.

Uji Kasus

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

Bacaan lebih lanjut

Pertanyaan yang luar biasa ini di Math.SE mencakup beberapa derivasi alternatif dari analog yang bernilai matriks dari fungsi trigonometri.

Mego
sumber
Saya dapat sin([[1, 0, 1], [0, 0, 0], [0, 1, 0]]) = {{0.841, -0.158, 0.841}, {0, 0, 0}, {0, 1, 0}}dengan Mathematica, dapatkah Anda memeriksanya?
kennytm
1
@kennytm Itulah yang ditunjukkan oleh test case.
Mego
1
@Mego Rupanya semua jawaban yang ada harus dihapus.
feersum
3
@Mego Benar-benar tidak masuk akal untuk berpikir bahwa semua builtin berbasis floating-point menggunakan algoritma yang tepat (atau yang akan tepat jika operasi floating-point diganti dengan operasi "nomor nyata").
feersum
1
@feersum Saya sudah membahas hal itu dalam edit terakhir saya:(ignoring the fact that it would require infinite time and/or memory)
Mego

Jawaban:

6

Julia, 33 19 byte

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

Ini adalah fungsi yang menerima array 2 dimensi mengapung dan mengembalikan tuple array seperti yang saling berhubungan ke cosinus dan sinus. Perhatikan bahwa ini adalah kebalikan dari urutan yang diberikan dalam kasus uji, di mana sinus terdaftar terlebih dahulu.

Untuk matriks A bernilai nyata , kami punya

sinus

dan

kosinus

Yaitu, sinus dan kosinus A berhubungan dengan bagian imajiner dan nyata dari matriks eksponensial e iA . Lihat Fungsi Matriks (Higham, 2008).

Cobalah online! (termasuk semua kasus uji)

Disimpan 14 byte berkat Dennis!

Alex A.
sumber
6

Mathematica, 27 byte

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

Berdasarkan pada solusi @ Rainer P.

Mengambil matriks kuadrat Asebagai argumen dan menampilkan daftar yang berisi {sin(A), cos(A)}.

Input diformat dengan Nuntuk mendapatkan nilai numerik alih-alih rumus panjang yang tepat dan Columnuntuk menampilkan hasil sin(A)dan cos(A)sebagai matriks terpisah, bukan daftar bersarang.

Contoh

Menghitung nilai secara terpisah membutuhkan 38 byte

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

Jelly , 23 22 byte

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

Cobalah online!

Latar Belakang

Pendekatan ini secara langsung menghitung deret Taylor untuk sinus dan cosinus , yaitu,

rumus

Ini meningkatkan jumlah syarat awal dari kedua seri hingga hasilnya tidak lagi berubah, jadi akurasinya hanya dibatasi oleh ketepatan jenis floating point.

Bagaimana itu bekerja

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

Matlab, 138 121 52 50 byte

Karena exponentiation matriks diperbolehkan, (apa yang saya tidak perhatikan terlebih dahulu, d'oh) saya tidak perlu mendefinisikan fungsi pembantu saya lagi, dan semuanya bisa diselesaikan dengan sepele:

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

Input harus berupa matriks misalnya [1,2;4,5]atau sebagai alternatif[[1,2];[3,4]]

Suatu hal yang tidak terduga (di belakang tidak begitu tak terduga) adalah bahwa matriks cosinus dan sinus masih memuaskan

I = sin(A)^2+cos(A)^2
cacat
sumber
Tidak A^0sama dengan eye(size(A))?
FryAmTheEggman
Oh kamu benar, terima kasih!
flawr
2
Kenapa tidak digunakan expm?
Luis Mendo
2
Sesuai identitas: Saya harap mereka memenuhi identitas itu, mengingat bahwa bentuk skalar digunakan untuk memperluas fungsi ke matriks!
Mego
1
Kalau begitu semuanya menjadi hampir sepele.
flawr
2

Matlab, 37 byte

@(A){imag(expm(i*A));real(expm(i*A))}
Rainer P.
sumber
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);}

Input adalah daftar angka yang merupakan kuadrat sempurna pada stdin. Output adalah array 2d yang cukup dicetak pada stdout

HSchmale
sumber
0

Julia 0,4, 28 byte

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

Input adalah matriks float, output adalah berbagai matriks. Cobalah online!

Dennis
sumber
0

Sage, 44 byte

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

Cobalah online .

Fungsi anonim ini mengembalikan daftar 2 matriks yang sesuai dengan sin(A)dan cos(A), masing-masing. exp(I*A)menghitung eksponensial matriks untuk I*A( Adengan semua elemen dikalikan dengan unit imajiner), dan matrix.apply_map(f)mengembalikan matriks yang ftelah diterapkan ke semua elemennya. Dengan menerapkan imagdan real(fungsi untuk mendapatkan bagian imajiner dan nyata dari nilai skalar) ke matriks, kita mendapatkan nilai-nilai sin(A)dan cos(A), berkat identitas Euler yang terkenal (dirujuk dalam teks tantangan).

Mego
sumber