ランダムな直交行列をコードゴルフ


9

直交行列は、行と列の直交単位ベクトル(すなわち、正規直交ベクトル)は、実際のエントリを有する正方行列です。

これは、M ^ TM = Iであることを意味します。ここで、Iは単位行列であり、^ Tは行列の転置を表します。

これは「特別な直交」ではなく直交であるため、Mの行列式は1または-1になります。

この課題の目的は機械の精度ではないため、M ^ TM = Iの場合、小数点以下4桁以内であれば問題ありません。

タスクは、正の整数を取りn > 1ランダムな直交n行n列の行列を出力するコードを記述することです。行列は 、n行n列のすべての直交行列からランダムかつ均一に選択する必要があります。この文脈では、「均一」はハール尺度で定義され、自由に選択した直交行列を掛けても分布が変化しないことが基本的に必要です。つまり、行列の値は-1から1の範囲の浮動小数点値になります。

入力と出力は、便利な任意の形式にすることができます。

実行中のコードの明確な例を示してください。

直交行列を作成する既存のライブラリ関数を使用することはできません。このルールは少し微妙なので、詳しく説明します。このルールは、一部の(またはまったくない)入力を取り込み、直交することが保証されている少なくともn行n列のサイズの行列を出力する既存の関数の使用を禁止します。極端な例として、n行n列の単位行列が必要な場合は、自分で作成する必要があります。

任意の標準乱数ジェネレータライブラリを使用して、任意の乱数を選択できます。

コードは、最大で数秒以内に完了するはずですn < 50


組み込みのIDマトリックスの使用は禁止されていますか?
JungHwan Min 2016

@JHM少なくともn行n列の単位行列の作成には使用できません。

どうdiagですか?実際には直交しているが常に直交するわけではない対角行列を作成します。
Karl Napf 2016年

これは「YなしでXを実行する」の例のようです。そのため、コンセンサスは避けてください。
2016年

1
対角行列は直交行列ではないため、問題ありdiagません。
Angs

回答:


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 2016年

@KarlNapfよく、とにかくその部分から2バイトを失う方法を
見つけた

ああ、コメントを削除しています...
Karl Napf '11 / 11/16

ハスケルの答えが勝ったときはいつも幸せです!

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

ガウスランダム値を持つ行列でグラムシュミット直交化を使用して、すべての方向を持ちます。

デモコードの後に​​は

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 2016年

@xnorが修正されました。幸いなことに、これは正確に1バイトかかりました。
Karl Napf 2016年

@xnorさらに幸運なことに、これによりバイトを節約できました-0.5
Karl Napf

ほとんどの場合、法線の平均は0である必要がありますが、それはを超えませんn
xnor 2016年

-1

Mathematica、69バイト、おそらく競合しない

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

QRDecomposition行列のペアを返します。最初の行列は直交することが保証されています(2番目の行列は直交ではなく、上三角行列です)。これは、技術的には投稿の制限事項に準拠していると主張することができます。これは、直交行列ではなく、行列のペアを出力します...

Mathematica、63バイト、間違いなく非競合

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

OrthogonalizeOPによって明確に禁止されています。それでも、Mathematicaはかなりかっこいいですよね?


You may not use any existing library function which creates orthogonal **matrices**.
Karl Napf 2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.