행렬 삼각법


13

소개

가장 일반적인 두 삼각 함수, sinecosine(또는 sincos짧은 경우), 행렬 값의 함수로 확장 될 수있다. 행렬 값 아날로그를 계산하는 한 가지 방법은 다음과 같습니다.

다음과 같은 두 가지 중요한 삼각 정체성을 고려하십시오.

삼각 정체성

이러한 아이덴티티를 사용하여 sin와에 대한 다음 방정식을 도출 할 수 있습니다 cos.

삼각 함수

행렬 지수는 모든 정사각형 행렬 존재에 의해 주어진다 :

행렬 지수

여기서 0 항등 행렬이며 I 과 동일한 치수 . 행렬 지수를 사용하여이 두 삼각 함수 (및 다른 모든 삼각 함수)는 행렬의 함수로 평가할 수 있습니다.

도전

정사각 행렬 A가 주어지면 sin(A)및 의 값을 출력합니다 cos(A).

규칙

  • 입력 및 출력은 편리하고 합리적인 형식 (2D 배열, 언어 매트릭스 형식 등) 일 수 있습니다.
  • 단일 프로그램, 2 개의 독립 프로그램, 단일 기능 또는 2 개의 기능을 작성할 수 있습니다. 두 함수를 작성하도록 선택하면 코드가 두 함수 (예 : 가져 오기 및 도우미 함수)간에 공유 될 수 있습니다.
  • 입력 행렬의 값은 항상 정수입니다.
  • 부동 소수점 부정확의 결과로 솔루션에 정확도 문제가있을 수 있습니다. 언어에 마법의 무한 정밀도 값이있는 경우 솔루션은 완벽하게 작동해야합니다 (무한 시간 및 / 또는 메모리가 필요하다는 사실을 무시하고). 그러나 이러한 마법의 무한 정밀도 값은 존재하지 않기 때문에 정밀도가 제한되어 부정확 한 부분이 허용됩니다. 이 규칙은 출력에서 ​​특정 정도의 정밀도를 요구하여 발생하는 복잡한 문제를 피하기 위해 마련되었습니다.
  • 행렬 인수 (쌍곡선 삼각 함수 포함)에 대한 삼각 함수를 계산하는 내장은 허용되지 않습니다. 다른 행렬 내장 (예 : 곱셈, 지수화, 대각 화, 분해 및 행렬 지수)이 허용됩니다.

테스트 사례

체재: 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]]

추가 자료

Math.SE에 대한이 훌륭한 질문 에는 삼각 함수의 행렬 값 아날로그에 대한 대체 파생물이 포함됩니다.


sin([[1, 0, 1], [0, 0, 0], [0, 1, 0]]) = {{0.841, -0.158, 0.841}, {0, 0, 0}, {0, 1, 0}}Mathematica와 함께 왔는데 확인할 수 있습니까?
kennytm

1
@kennytm 이것이 바로 테스트 사례입니다.
Mego

1
@Mego 분명히 기존의 모든 답변을 삭제해야합니다.
feersum

3
@Mego 모든 부동 소수점 기반 내장은 정확한 알고리즘 (또는 부동 소수점 연산이 "실수"연산으로 대체 된 경우 정확한 알고리즘)을 사용한다고 생각하는 것은 완전히 합리적이지 않습니다.
feersum

1
@feersum 최근 편집에서이 문제를 해결했습니다.(ignoring the fact that it would require infinite time and/or memory)
Mego

답변:


6

줄리아, 33 19 바이트

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

이것은 2 차원 부동 소수점 배열을 받아들이고 코사인과 사인에 각각 해당하는 배열의 튜플을 반환하는 함수입니다. 이는 사인이 맨 먼저 나열되는 테스트 사례의 순서와 반대입니다.

실수 행렬 A의 경우

사인

코사인

즉, A 의 사인과 코사인은 행렬 지수 e iA 의 허수와 실수 부분에 해당합니다 . 행렬 함수 (Higham, 2008)를 참조하십시오 .

온라인으로 사용해보십시오! (모든 테스트 케이스 포함)

Dennis 덕분에 14 바이트를 절약했습니다!


6

Mathematica, 27 바이트

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

@ Rainer P. 의 솔루션을 기반으로 합니다.

정사각 행렬 A을 인수로 받아서를 포함하는 목록을 출력합니다 {sin(A), cos(A)}.

입력은 N긴 정확한 공식 대신 숫자 값을 가져 오고 중첩 된 목록 대신 별도의 행렬로 Column결과를 표시하도록 형식화 됩니다.sin(A)cos(A)

예

값을 별도로 계산하려면 38 바이트 가 필요 합니다

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

6

젤리 , 23 22 바이트

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

온라인으로 사용해보십시오!

배경

이 접근법은 사인코사인에 대한 Taylor 시리즈를 직접 계산합니다 .

공식

결과가 더 이상 변경되지 않을 때까지 두 계열의 초기 항의 수를 증가 시키므로 정확도는 부동 소수점 유형의 정밀도에 의해서만 제한됩니다.

작동 원리

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

3

C ++, 305 바이트

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

입력은 stdin의 완벽한 제곱 인 숫자의 목록입니다. 출력은 표준 출력에서 ​​꽤 인쇄 된 2D 배열입니다


2

Matlab, 138121 52 50 바이트

행렬 지수가 허용되기 때문에 (내가 먼저 알지 못했던 것) 더 이상 도우미 기능을 정의 할 필요가 없으며 모든 것이 사소하게 해결 될 수 있습니다.

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

입력은 매트릭스 [1,2;4,5]또는 예를 들어 대안 이어야합니다[[1,2];[3,4]]

예기치 않은 것은 (후시가 그렇게 예상치 못한) 코사인과 사인 행렬이 여전히 만족한다는 것입니다.

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

하지가 A^0같은 eye(size(A))?
FryAmTheEggman

아 맞아, 고마워!
flawr

2
왜 사용하지 expm않습니까?
Luis Mendo

2
정체성에 따라 : 스칼라 형식이 함수를 행렬로 확장하는 데 사용되었다는 점을 고려하여 그 정체성을 만족시키기를 바랍니다!
Mego

1
그러면 모든 것이 거의 사소 해집니다.
flawr



0

세이지, 44 바이트

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

온라인으로 사용해보십시오 .

이 익명 함수는 각각 sin(A)및에 해당하는 2 개의 행렬 목록을 반환합니다 cos(A). exp(I*A)에 대한 행렬 지수 I*A( A모든 요소에 허수 단위를 곱한 값) 를 계산하고 모든 요소 에 적용된 matrix.apply_map(f)행렬을 반환합니다 f. 적용함으로써 imagreal행렬에 (스칼라 값의 가상 및 실제 부품을 얻기를위한 기능을), 우리는의 값을 취득 sin(A)하고 cos(A), (도전 텍스트에서 참조) 오일러의 유명한 정체성 덕분에.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.