ガウス行列を作成します


12

ガウスぼかしは、画像を滑らかにぼかすために使用される方法です。画像のピクセルと畳み込むことで使用されるマトリックスを作成する必要があります。この課題でのタスクは、ガウスぼかしで使用される行列を作成することです。次元(2 r + 1×2 r + 1)の行列を作成するために、ぼかしの半径となる入力rと標準偏差となる入力σを取ります。その行列の各値は、中心からの各方向の絶対距離に依存する(xy)値を持ち、Gxy)の計算に使用されます。G

式

たとえば、r = 2の場合、5 x 5の行列を生成します。まず、(xy)値の行列は

(2, 2) (1, 2) (0, 2) (1, 2) (2, 2)
(2, 1) (1, 1) (0, 1) (1, 1) (2, 1)
(2, 0) (1, 0) (0, 0) (1, 0) (2, 0)
(2, 1) (1, 1) (0, 1) (1, 1) (2, 1)
(2, 2) (1, 2) (0, 2) (1, 2) (2, 2)

次に、σ = 1.5とし、各(xy)にGを適用します

0.0119552 0.0232856 0.0290802 0.0232856 0.0119552
0.0232856 0.0453542 0.0566406 0.0453542 0.0232856
0.0290802 0.0566406 0.0707355 0.0566406 0.0290802
0.0232856 0.0453542 0.0566406 0.0453542 0.0232856
0.0119552 0.0232856 0.0290802 0.0232856 0.0119552

通常、画像のぼかしでは、このマトリックスは、そのマトリックス内のすべての値の合計を取り、それで割ることによって正規化されます。この課題では、それは不要であり、式によって計算される生の値が出力になります。

ルール

  • これはので、最短のコードが優先されます。
  • 入力rは非負の整数で、σは正の実数になります。
  • 出力は行列を表す必要があります。2D配列、2D配列を表す文字列、または同様のものとしてフォーマットできます。
  • 浮動小数点の不正確さは、あなたに対してカウントされません。

テストケース

(r, σ) = (0, 0.25)
2.54648

(1, 7)
0.00318244 0.00321509 0.00318244
0.00321509 0.00324806 0.00321509
0.00318244 0.00321509 0.00318244

(3, 2.5)
0.00603332 0.00900065 0.0114421  0.012395 0.0114421 0.00900065 0.00603332
0.00900065  0.0134274 0.0170696 0.0184912 0.0170696  0.0134274 0.00900065
 0.0114421  0.0170696 0.0216997  0.023507 0.0216997  0.0170696  0.0114421
  0.012395  0.0184912  0.023507 0.0254648  0.023507  0.0184912   0.012395
 0.0114421  0.0170696 0.0216997  0.023507 0.0216997  0.0170696  0.0114421
0.00900065  0.0134274 0.0170696 0.0184912 0.0170696  0.0134274 0.00900065
0.00603332 0.00900065 0.0114421  0.012395 0.0114421 0.00900065 0.00603332

(4, 3.33)
0.00339074 0.00464913 0.00582484 0.00666854 0.00697611 0.00666854 0.00582484 0.00464913 0.00339074
0.00464913 0.00637454 0.00798657  0.0091434 0.00956511  0.0091434 0.00798657 0.00637454 0.00464913
0.00582484 0.00798657  0.0100063  0.0114556   0.011984  0.0114556  0.0100063 0.00798657 0.00582484
0.00666854  0.0091434  0.0114556   0.013115  0.0137198   0.013115  0.0114556  0.0091434 0.00666854
0.00697611 0.00956511   0.011984  0.0137198  0.0143526  0.0137198   0.011984 0.00956511 0.00697611
0.00666854  0.0091434  0.0114556   0.013115  0.0137198   0.013115  0.0114556  0.0091434 0.00666854
0.00582484 0.00798657  0.0100063  0.0114556   0.011984  0.0114556  0.0100063 0.00798657 0.00582484
0.00464913 0.00637454 0.00798657  0.0091434 0.00956511  0.0091434 0.00798657 0.00637454 0.00464913
0.00339074 0.00464913 0.00582484 0.00666854 0.00697611 0.00666854 0.00582484 0.00464913 0.00339074

piとeの精度はどれくらい必要ですか?
xnor 16

@xnor良い質問です。言語で許可されている場合、これらの値は既に変数または類似のものに格納されていると想定できます。そうでない場合は、小数点以下2桁までの値を使用して、pi = 3.14およびe = 2.72とし、これらの各値を1バイトとしてカウントできます。もちろん、最終回答の不正確さは二度とカウントされません。
マイル

出力は10進数である必要がありますか、それとも定数を含む正確な数値である可能性がありますか?
ジョンファンミン

@JungHwanMin Mathematicaの数値のような正確な数値は問題ありません。
マイル

1
@miles特定の精度(小数点以下3桁など)を指定した方が簡単だと思います。
orlp

回答:


7

Mathematica、60 54 50バイト

4バイトありがとう@GregMartin!

Array[s=2#2^2;E^(-{##}.{##}/s)/π/s&,1+2{#,#},-#]&

rとsigmaを入力として取り、行列(正確な数)を返します。

組み込みバージョン(58バイト)

GaussianMatrix[{##},Standardized->1<0,Method->"Gaussian"]&

もちろん、Mathematicaにもこの機能が組み込まれていますが、長すぎます。


4
あなたは置き換えることができます-lによって-#(最後にArrayあなたのための両方の次元上でそれをスレッドします)。定義する必要がなくなりl、4バイトを節約できます。
グレッグマーティン

5

MATL、20バイト

_G&:U&+iUE/_Ze5MYP*/

オンラインでお試しください!

説明

_     % Take input r implicitly. Negate
G     % Push r again
&:    % Binary range: [-r -r+1 ... r]
U     % Square, elementwise
&+    % Matrix of all pairwise additions
i     % Take input σ
U     % Square
E     % Multiply by 2. Gives 2σ^2
/     % Divide
_     % Negate
Ze    % Exponential
5M    % Push 2σ^2 again
YP    % Push pi
*     % Multiply
/     % Divide. Display implicitly

5

オクターブ、45バイト

@(r,s)exp((x=-(-r:r).^2/2/s^2)+x')/2/s^2/pi


4

Python、88バイト

lambda r,s:[[.5/3.14/s/s/2.72**((x*x+y*y)/2/s/s)for x in range(-r,r+1)]for y in range(-r,r+1)]

それぞれ1バイトのコストで3.14および2.72をハードコーディングできるルールを使用します。


1

Perl 6、71バイト

->\r,\σ{map ->\y{map ->\x{exp((x*x+y*y)/-2/σ/σ)/2/pi/σ/σ},-r..r},-r..r}

技術的には、エンコードしてファイルに保存した場合、これは71バイトを超える場合がありますが、実際のギリシャ語のシグマで「シグマ」入力に名前を付けることは避けられません。必要に応じて、任意のプレーンASCII文字に名前を変更できます。


1

SASマクロ言語、296バイト

これを行うにはおそらくはるかに効率的な方法ですが、動作します:)

このコードは、結果のデータセットを出力します。

%macro G(r,s);%let l=%eval(2*&r+1);%let pi=%sysfunc(constant(pi));data w;array a[*] t1-t&l;%do i=-&r %to &r;%do j=-&r %to &r;%let t=%sysfunc(sum(&j,&r,1));a[&t]=%sysevalf(1/(2*&pi*&s**2)*%sysfunc(exp(-(%sysfunc(abs(&j))**2+%sysfunc(abs(&i))**2)/(2*&s**2))));%end;output;%end;proc print;run;%mend;

1

Haskell、59バイト

r#s|i<-[-r..r]=[[exp(-(x*x+y*y)/2/s/s)/2/pi/s/s|x<-i]|y<-i]

使用例:

1#7

[[3.1824449424224664e-3,3.2150851187016326e-3,3.1824449424224664e-3],
 [3.2150851187016326e-3,3.2480600630999047e-3,3.2150851187016326e-3],
 [3.1824449424224664e-3,3.2150851187016326e-3,3.1824449424224664e-3]]

0

Python 2.7、167バイト

非常に簡単な解決策:

from __future__ import division;from math import*;r,s=input();s*=2*s;R=range(-r,r+1);print"\n".join("\t".join(str(pow(e,-(x*x+y*y)/s)/(pi*s))[:9]for x in R)for y in R)

ここで試してみてください

ゴルフをしていない:

from __future__ import division
from math import *
r,s = input()                         # Take input
s *= 2*s                              # Set s = 2*s^2; simplifies the expression
R = range(-r,r+1)                     # Range object; used twice

                                   # G(x,y)             # Stripped
print "\n".join("\t".join(str(pow(e,-(x*x + y*y)/s)/(pi*s))[:9] for x in R) for y in R)

5
from __future__ import division、 本当に?
orlp 16
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.