รหัสกอล์ฟเป็นเมทริกซ์มุมฉากแบบสุ่ม


9

เมทริกซ์มุมฉากเป็นเมทริกซ์ตารางกับรายการจริงที่มีคอลัมน์และแถวเวกเตอร์หน่วยมุมฉาก (เช่นเวกเตอร์ orthonormal)

นี่หมายความว่า M ^ TM = I โดยที่ฉันคือเมทริกซ์เอกลักษณ์และ ^ T หมายถึงการเคลื่อนย้ายเมทริกซ์

โปรดทราบว่านี่คือมุมฉากไม่ใช่ "orthogonal พิเศษ" ดังนั้นดีเทอร์มีแนนต์ของ M สามารถเป็น 1 หรือ -1

เป้าหมายของการท้าทายนี้ไม่ใช่ความแม่นยำของเครื่องจักรดังนั้นหาก M ^ TM = I ถึงภายในทศนิยม 4 ตำแหน่งที่จะใช้ได้

งานคือการเขียนโค้ดที่ใช้เวลาเป็นจำนวนเต็มบวกn > 1และผลสุ่มมุมฉาก n โดย n เมทริกซ์ เมทริกซ์ควรจะแบบสุ่มและสม่ำเสมอได้รับการแต่งตั้งจากทั้งหมด n โดย n เมทริกซ์มุมฉาก ในบริบทนี้ "เครื่องแบบ" ถูกกำหนดในแง่ของการวัดฮาร์ซึ่งจำเป็นต้องมีการกระจายที่ไม่เปลี่ยนแปลงถ้าคูณด้วยเมทริกซ์มุมฉากที่เลือกอย่างอิสระใด ๆ นี่หมายความว่าค่าของเมทริกซ์จะเป็นค่าทศนิยมในช่วง -1 ถึง 1

อินพุตและเอาต์พุตสามารถเป็นรูปแบบที่คุณสะดวก

โปรดแสดงตัวอย่างที่ชัดเจนเกี่ยวกับการเรียกใช้รหัสของคุณ

คุณไม่สามารถใช้ฟังก์ชันไลบรารีใด ๆ ที่มีอยู่ซึ่งสร้างเมทริกซ์มุมฉาก กฎนี้ค่อนข้างบอบบางดังนั้นฉันจะอธิบายเพิ่มเติม กฎนี้ห้ามการใช้งานฟังก์ชั่นใด ๆ ที่มีอยู่ในอินพุต (หรือไม่มี) และเมทริกซ์ที่มีขนาดอย่างน้อย n คูณ n ซึ่งรับประกันได้ว่าเป็นมุมฉาก เป็นตัวอย่างสุดขีดหากคุณต้องการเมทริกซ์เอกลักษณ์แบบ n โดย n คุณจะต้องสร้างมันเอง

คุณสามารถใช้ไลบรารีตัวสร้างตัวเลขสุ่มแบบมาตรฐานสำหรับการเลือกหมายเลขแบบสุ่มที่คุณเลือก

n < 50รหัสของคุณควรจะเสร็จสมบูรณ์ภายในที่มากที่สุดไม่กี่วินาที


ดังนั้นห้ามใช้เมทริกซ์เอกลักษณ์ในตัว?
JungHwan Min

@JHM คุณไม่สามารถใช้มันเพื่อสร้างเมทริกซ์เอกลักษณ์แบบ n โดย n อย่างน้อยที่สุด

เกี่ยวกับdiagอะไร มันสร้างเมทริกซ์แนวทแยงมุมซึ่งแน่นอนเป็นมุมฉาก แต่ไม่เสมอไป
Karl Napf

นี่น่าจะเป็นตัวอย่างของ "do X ที่ไม่มี Y" ซึ่งควรหลีกเลี่ยงฉันทามติ
ข้อบกพร่อง

1
เมทริกซ์แบบทแยงมุมไม่ใช่เมทริกซ์แบบมุมฉากดังนั้นdiagน่าจะโอเค
อัง

คำตอบ:


7

Haskell, 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เมทริกซ์ใช้พื้นที่มากเกินไปสำหรับรสชาติของฉันเป็นกรณีพิเศษเพียงสำหรับการเป็นศูนย์จากตัวแปรสุ่ม Gaussian: / (โดยไม่ได้มีโอกาสน้อยที่จะได้รับคอลัมน์ศูนย์)
Angs

ฉันชอบจิตวิญญาณของคุณในการทำให้ถูกต้องโดยสิ้นเชิง แต่ฉันคิดว่าคุณสามารถทำตามข้อกำหนดนั้นได้ ในรหัสของฉันยังมีโอกาสที่ 2 แถวจะขึ้นอยู่กันเป็นเส้นตรงและไม่มีใครสนใจ
Karl Napf

@KarlNapf ดีฉันคิดหาวิธีที่จะสูญเสียไบต์ที่สองจากส่วนที่อยู่แล้วเพื่อแก้ไขปัญหาส่วนหนึ่ง :)
Angs

อาโอเคลบความคิดเห็นของฉัน ...
คาร์ล Napf

มีความสุขเสมอเมื่อคำตอบของ Haskell ชนะ!

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 Orthogonalization บนเมทริกซ์ที่มีค่าสุ่ม Gaussian ให้มีทุกทิศทาง

ตามด้วยรหัสการสาธิต

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[]&,{#,#}]&

Orthogonalizeถูกห้ามอย่างไม่น่าเชื่อโดย OP ถึงกระนั้น 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.