Mã golf một ma trận trực giao ngẫu nhiên


9

Một ma trận trực giao là một ma trận vuông với các mục thực có cột và hàng là các vectơ đơn vị trực giao (tức là vectơ trực giao).

Điều này có nghĩa là M ^ TM = I, trong đó I là ma trận danh tính và ^ T biểu thị hoán vị ma trận.

Lưu ý rằng đây là trực giao không phải là "trực giao đặc biệt" nên định thức của M có thể là 1 hoặc -1.

Mục tiêu của thử thách này không phải là độ chính xác của máy nên nếu M ^ TM = I đến trong 4 chữ số thập phân thì sẽ ổn.

Nhiệm vụ là viết mã lấy một số nguyên dương n > 1và đưa ra một ma trận n trực giao ngẫu nhiên theo n ma trận . Ma trận nên được chọn ngẫu nhiên và thống nhất từ tất cả n bởi n ma trận trực giao. Trong bối cảnh này, "thống nhất" được định nghĩa theo phương pháp Haar, về cơ bản đòi hỏi phân phối không thay đổi nếu nhân với bất kỳ ma trận trực giao nào được chọn tự do. Điều này có nghĩa là các giá trị của ma trận sẽ là các giá trị dấu phẩy động trong phạm vi -1 đến 1.

Đầu vào và đầu ra có thể là bất kỳ hình thức nào bạn thấy thuận tiện.

Vui lòng hiển thị một ví dụ rõ ràng về mã của bạn đang chạy.

Bạn không được sử dụng bất kỳ chức năng thư viện hiện có nào tạo ra ma trận trực giao. Quy tắc này là một chút tinh tế vì vậy tôi sẽ giải thích thêm. Quy tắc này cấm sử dụng bất kỳ chức năng hiện có nào trong một số (hoặc không) đầu vào và đưa ra một ma trận có kích thước ít nhất là n bởi n được đảm bảo là trực giao. Một ví dụ cực đoan, nếu bạn muốn ma trận danh tính n by n, bạn sẽ phải tự tạo nó.

Bạn có thể sử dụng bất kỳ thư viện trình tạo số ngẫu nhiên tiêu chuẩn nào để chọn số ngẫu nhiên bạn chọn.

Mã của bạn sẽ hoàn thành trong vòng tối đa vài giây n < 50.


Vì vậy, sử dụng ma trận danh tính tích hợp có bị cấm?
JungHwan Min

@JHM Bạn không thể sử dụng nó để tạo ít nhất một ma trận danh tính n.

Thế còn diag? Nó tạo ra một ma trận đường chéo thực sự trực giao nhưng không phải lúc nào cũng trực giao.
Karl Napf

Đây dường như là một ví dụ về "làm X mà không có Y", vì vậy - nên tránh sự đồng thuận -.
flawr

1
Ma trận đường chéo không phải là ma trận trực giao diagnên sẽ ổn.
Angs

Câu trả lời:


7

Haskell, 169 150 148 141 132 131 byte

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

Đệ quy mở rộng một ma trận trực giao có kích thước n-1bằng cách thêm 1 vào góc dưới bên phải và áp dụng phản xạ Householder ngẫu nhiên. randnđưa ra một ma trận với các giá trị ngẫu nhiên từ phân bố gaussian và z dđưa ra một vectơ đơn vị phân bố đồng đều theo các dkích thước.

haussholder tau vtrả về ma trận I - tau*v*vᵀkhông trực giao khi vkhông phải là một vectơ đơn vị.

Sử dụng:

*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

Làm cho 1×1ma trận chiếm quá nhiều không gian theo sở thích của tôi, một trường hợp đặc biệt chỉ để lấy số 0 từ biến ngẫu nhiên gaussian: / (Không có nó, có một cơ hội vô hạn để có được một cột số 0)
Angs

Tôi thích tinh thần của bạn để làm cho nó hoàn toàn chính xác, nhưng tôi nghĩ bạn có thể bỏ yêu cầu đó. Trong mã của tôi cũng có khả năng 2 hàng phụ thuộc tuyến tính và không ai quan tâm.
Karl Napf

@KarlNapf tốt, tôi đã tìm ra cách để mất hai byte từ phần đó, vì vậy vấn đề đã được giải quyết một phần :)
Angs

À được rồi, xóa bình luận của tôi ...
Karl Napf

Luôn luôn vui khi câu trả lời của Haskell chiến thắng!

4

Python 2 + NumPy, 163 byte

Cảm ơn xnor đã chỉ ra sử dụng các giá trị ngẫu nhiên phân tán bình thường thay vì giá trị đồng nhất.

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

Sử dụng trực giao Gram Schmidt trên một ma trận với các giá trị ngẫu nhiên gaussian để có tất cả các hướng.

Mã trình diễn được theo sau bởi

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ó hoàn thành trong nháy mắt với n = 50 và vài giây cho n = 500.


Tôi không nghĩ đây là đồng phục. Phân phối bắt đầu của bạn với một khối lập phương, có nhiều thứ hơn đối với các đường chéo. Gaussian ngẫu nhiên sẽ hoạt động vì chúng tạo ra một phân bố đối xứng hình cầu.
xnor

@xnor đã sửa. May mắn thay, điều này có giá chính xác 1 byte.
Karl Napf

@xnor Thậm chí may mắn hơn, điều này đã lưu các byte cho-0.5
Karl Napf

Hầu như, bạn cần giá trị trung bình của bình thường là 0, nhưng điều đó không dài hơn n.
xnor

-1

Mathicala, 69 byte, có thể không cạnh tranh

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

QRDecompositiontrả về một cặp ma trận, cái đầu tiên được đảm bảo là trực giao (và cái thứ hai không phải là trực giao, mà là hình tam giác trên). Người ta có thể lập luận rằng về mặt kỹ thuật này tuân theo thư giới hạn trong bài viết: nó không tạo ra ma trận trực giao, mà là một cặp ma trận ....

Mathematica, 63 byte, chắc chắn không cạnh tranh

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

Orthogonalizebị OP cấm một cách rõ ràng. Tuy nhiên, Mathematica khá tuyệt nhỉ?


You may not use any existing library function which creates orthogonal **matrices**.
Karl Napf
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.