编码高尔夫随机正交矩阵


9

一个正交矩阵是方阵与真正的条目,其列和行是正交的单位向量(即,正交向量)。

这意味着M ^ TM = I,其中I是单位矩阵,^ T表示矩阵转置。

注意,这是正交的而不是“特殊正交”,因此M的行列式可以是1或-1。

挑战的目标不是机器精度,因此如果M ^ TM = I到4个小数位以内就可以了。

任务是编写采用正整数n > 1并输出n×n矩阵的正交正交代码。矩阵应从所有 n×n个正交矩阵中随机且均匀地选择。在这种情况下,“均一”是根据Haar测度定义的,这实际上要求如果乘以任何自由选择的正交矩阵,分布就不会改变。这意味着矩阵的值将是-1到1范围内的浮点值。

输入和输出可以是您认为方便的任何形式。

请显示代码运行的明确示例。

您不能使用任何现有的创建正交矩阵的库函数。这个规则有些微妙,所以我将进一步解释。该规则禁止使用任何现有函数,该函数需要一些(或不输入)输入并输出大小至少为n×n的矩阵,该矩阵必须保证正交。举一个极端的例子,如果您想要n×n单位矩阵,则必须自己创建。

您可以使用任何标准随机数生成器库来选择所需的随机数。

您的代码最多应在几秒钟内完成n < 50


因此,禁止使用内置身份矩阵?
JungHwan Min

@JHM至少不能使用它来创建n x n的单位矩阵。

diag呢 它创建一个对角矩阵,该对角矩阵的确是正交的,但并不总是正交的。
Karl Napf '16

这似乎是“做X而不做Y”的示例,因此-应该避免这种共识。
瑕疵的

1
对角矩阵不是正交矩阵,因此diag应该可以。
昂斯,2016年

Answers:


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 递归扩展大小为正交的矩阵,并应用随机Householder反射。randn给出具有高斯分布随机值的矩阵,并z d给出d尺寸均匀分布的单位矢量。

haussholder tau vI - 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好吧,我想出了一种方法来从那部分丢失两个字节,所以问题部分得到解决了:)
Angs

好的,删除我的评论...
Karl 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正交化以具有所有方向。

演示代码后跟

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 '16

@xnor更幸运的是,这为-0.5
Karl Napf 16'Nov

几乎,您需要将法线的均值设为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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.