임의의 직교 행렬을 코드 골프


9

직교 행렬 열과 행 직교하는 단위 벡터 (즉, 직교 벡터) 리얼 항목 가진 정방 행렬이다.

이것은 M ^ TM = I이며, 여기서 I는 항등 행렬이고 ^ T는 행렬 전치를 나타냅니다.

이것은 "특수 직교"가 아닌 직교이므로 M의 결정자는 1 또는 -1 일 수 있습니다.

이 과제의 목표는 기계 정밀도가 아니므로 M ^ TM = I 인 경우 소수점 이하 4 자리 이내이면 괜찮습니다.

이 작업은 양의 정수를 취하고 임의의 직교 n x n 행렬을n > 1 출력하는 코드를 작성하는 것입니다 . 행렬은 모든 n x n 개의 직교 행렬 에서 무작위로 균일하게 선택해야합니다 . 이러한 맥락에서, "균일 한"은 Haar 측정에 의해 정의되며, 이는 자유롭게 선택된 직교 행렬을 곱한 경우 분포가 변하지 않도록 본질적으로 요구한다. 이것은 행렬의 값이 -1에서 1 사이의 부동 소수점 값이됨을 의미합니다.

입력 및 출력은 편리한 형태 일 수 있습니다.

코드 실행에 대한 명확한 예를 보여주십시오.

직교 행렬을 생성하는 기존 라이브러리 함수를 사용할 수 없습니다. 이 규칙은 약간 미묘하므로 더 자세히 설명하겠습니다. 이 규칙은 일부 (또는 비) 입력을 받아 직교 할 수있는 n x n 크기의 행렬을 출력하는 기존 함수의 사용을 금지합니다. 극단적 인 예로서, n x n 단위 행렬을 원한다면 직접 만들어야합니다.

선택한 난수를 선택하기 위해 표준 난수 생성기 라이브러리를 사용할 수 있습니다.

에 대한 코드는 최대 몇 초 내에 완료되어야합니다 n < 50.


내장 된 ID 매트릭스를 사용하는 것은 금지되어 있습니까?
JungHwan Min 2018

@JHM 적어도 n x n 단위 행렬을 만드는 데 사용할 수 없습니다.

무엇에 대해 diag? 실제로 직교하지만 항상 직교하는 것은 아닌 대각선 행렬을 만듭니다.
Karl Napf

이것은 "Y없이 X를한다"의 예인 것 같습니다. 따라서 합의를 피해야합니다.
flawr

1
대각선 행렬은 직교 행렬이 아니므 diag로 괜찮습니다.

답변:


7

하스켈 169 150 148 141 132 131 바이트

import Numeric.LinearAlgebra
z=(unitary.flatten<$>).randn 1
r 1=asRow<$>z 1
r n=do;m<-r$n-1;(<>diagBlock[m,1]).haussholder 2<$>z n

n-1오른쪽 하단에 1을 더하여 직교 크기의 행렬을 재귀 적으로 확장 하고 임의의 세대 반사를 적용하십시오. randn가우스 분포에서 임의의 값을 가진 행렬을 z d제공하고 d차원 에서 균일하게 분포 된 단위 벡터를 제공 합니다.

haussholder tau v단위 벡터가 아닌 I - tau*v*vᵀ경우 직교하지 않은 행렬 을 반환합니다 v.

용법:

*Main> m <- r 5
*Main> disp 5 m
5x5
-0.24045  -0.17761   0.01603  -0.83299  -0.46531
-0.94274   0.12031   0.00566   0.29741  -0.09098
-0.02069   0.30417  -0.93612  -0.13759   0.10865
 0.02155  -0.83065  -0.35109   0.32365  -0.28556
-0.22919  -0.41411   0.01141  -0.30659   0.82575
*Main> (<1e-14) . maxElement . abs $ tr m <> m - ident 5
True

제작 1×1매트릭스 단지 가우시안 확률 변수에서 제로를 얻기를 위해 내 취향, 특별한 경우 너무 많은 공간을 차지 : / (그게 없으면, 제로 열을 얻을 수 미소 기회있다)
Angs

나는 당신이 그것을 완전히 옳게 만드는 당신의 정신을 좋아하지만, 나는 당신이 그 요구를 버릴 수 있다고 생각합니다. 내 코드에는 2 개의 행이 선형 적으로 의존하고 아무도 신경 쓰지 않을 가능성이 있습니다.
Karl Napf

@KarlNapf 음, 어쨌든 그 부분에서 2 바이트를 잃는 방법을 알아 냈습니다. 그래서 문제는 부분적으로 해결되었습니다 :)
Angs

아 좋아, 내 의견을 삭제 ...
Karl Napf

하스켈 답변이 이길 때 항상 행복합니다!

4

Python 2 + NumPy, 163 바이트

균일 한 값 대신 정규 분산 임의 값을 사용하도록 지적 해 주신 xnor에게 감사합니다.

from numpy import*
n=input()
Q=random.randn(n,n)
for i in range(n):
 for j in range(i):u=Q[:,j];Q[:,i]-=u*dot(u,Q[:,i])/dot(u,u)
Q/=(Q**2).sum(axis=0)**0.5
print Q

가우스 임의의 값이있는 행렬 에서 Gram Schmidt 직교 화를 사용하여 모든 방향을 갖습니다.

데모 코드 다음에

print dot(Q.transpose(),Q)

n = 3 :

[[-0.2555327   0.89398324  0.36809917]
 [-0.55727299  0.17492767 -0.81169398]
 [ 0.79003155  0.41254608 -0.45349298]]
[[  1.00000000e+00   0.00000000e+00   0.00000000e+00]
 [  0.00000000e+00   1.00000000e+00  -5.55111512e-17]
 [  0.00000000e+00  -5.55111512e-17   1.00000000e+00]]

n = 5 :

[[-0.63470728  0.41984536  0.41569193  0.25708079  0.42659843]
 [-0.36418389  0.06244462 -0.82734663 -0.24066123  0.3479231 ]
 [ 0.07863783  0.7048799   0.08914089 -0.64230492 -0.27651168]
 [ 0.67691426  0.33798442 -0.05984083  0.17555011  0.62702062]
 [-0.01095148 -0.45688226  0.36217501 -0.65773717  0.47681205]]
[[  1.00000000e+00   1.73472348e-16   5.37764278e-17   4.68375339e-17
   -2.23779328e-16]
 [  1.73472348e-16   1.00000000e+00   1.38777878e-16   3.33066907e-16
   -6.38378239e-16]
 [  5.37764278e-17   1.38777878e-16   1.00000000e+00   1.38777878e-16
    1.11022302e-16]
 [  4.68375339e-17   3.33066907e-16   1.38777878e-16   1.00000000e+00
    5.55111512e-16]
 [ -2.23779328e-16  -6.38378239e-16   1.11022302e-16   5.55111512e-16
    1.00000000e+00]]

n = 50의 깜박임과 n = 500의 몇 초 안에 완료됩니다.


나는 이것이 균일하다고 생각하지 않습니다. 대각선을 향한 더 많은 것을 가지고있는 입방체로 시작 분포. 랜덤 가우스는 구형 대칭 분포를 생성하기 때문에 작동합니다.
xnor

@xnor 고정. 운 좋게도 이것은 정확히 1 바이트였습니다.
Karl Napf

@xnor 더 운이 좋으면, 바이트를 절약했습니다-0.5
Karl Napf

거의 법선의 평균이 0이되어야하지만 더 이상은 아닙니다 n.
xnor

-1

Mathematica, 69 바이트, 아마 비경쟁

#&@@QRDecomposition@Array[RandomVariate@NormalDistribution[]&,{#,#}]&

QRDecomposition는 한 쌍의 행렬을 반환하며, 첫 번째 행렬은 직교 함을 보장합니다. 두 번째 행렬은 직교하지 않고 위쪽 삼각형입니다. 이것은 기술적으로 포스트의 제한 문자에 순종한다고 주장 할 수 있습니다. 직교 행렬을 출력하지 않고 행렬 쌍을 출력합니다 ....

Mathematica, 63 바이트, 확실히 비경쟁

Orthogonalize@Array[RandomVariate@NormalDistribution[]&,{#,#}]&

OrthogonalizeOP에 의해 명백히 금지되어 있습니다. 그래도 Mathematica는 정말 멋지다?


You may not use any existing library function which creates orthogonal **matrices**.
Karl Napf
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.