황금 나선 방법
황금 나선 방법을 사용할 수 없다고 하셨는데, 정말 정말 훌륭하기 때문에 안타깝습니다. 나는 당신이 "번치"되는 것을 막는 방법을 이해할 수 있도록 당신에게 그것에 대한 완전한 이해를 드리고 싶습니다.
그래서 여기에 대략적으로 정확한 격자를 만드는 빠르고 랜덤하지 않은 방법이 있습니다. 위에서 논의한 바와 같이 격자는 완벽하지 않지만 이것만으로도 충분할 수 있습니다. 다른 방법과 비교됩니다. BendWavy.org와 되지만 멋지고 예쁘게 보일뿐만 아니라 한계에서 균일 한 간격을 보장합니다.
입문서 : 단위 디스크의 해바라기 나선
이 알고리즘을 이해하기 위해 먼저 2D 해바라기 나선형 알고리즘을 살펴 보도록하겠습니다. 이것은 가장 비합리적인 숫자가 황금 비율이라는 사실에 기반 (1 + sqrt(5))/2
하고 있으며, "중앙에 서서 전체 턴의 황금 비율을 돌린 다음 그 방향으로 다른 지점을 방출"하는 접근 방식으로 포인트를 방출하면 자연스럽게 a 나선형은 점의 수를 점점 더 많이 증가 시키면서도 점이 정렬되는 잘 정의 된 '막대'를 갖기를 거부합니다. (참고 1)
디스크의 균등 한 간격에 대한 알고리즘은 다음과 같습니다.
from numpy import pi, cos, sin, sqrt, arange
import matplotlib.pyplot as pp
num_pts = 100
indices = arange(0, num_pts, dtype=float) + 0.5
r = sqrt(indices/num_pts)
theta = pi * (1 + 5**0.5) * indices
pp.scatter(r*cos(theta), r*sin(theta))
pp.show()
다음과 같은 결과를 생성합니다 (n = 100 및 n = 1000).
방사형으로 점 간격
중요한 이상한 점은 공식입니다 r = sqrt(indices / num_pts)
. 내가 그 사람에게 어떻게 왔습니까?(노트 2.)
음, 저는 여기에 제곱근을 사용하고 있습니다. 왜냐하면 디스크 주위에 균등 한 영역 간격을 갖기를 원하기 때문입니다. 그것은 큰 N 의 한계에서 나는 작은 영역 R ∈ ( r , r + d r ), Θ ∈ ( θ , θ + d θ )가 그 면적에 비례하는 수의 점을 포함하기를 원한다고 말하는 것과 같습니다 . 이것은 r d r d θ 입니다. 이제 우리가 여기서 임의의 변수에 대해 이야기하고 있다고 가정하면, 이것은 ( R , Θ )에 대한 결합 확률 밀도 가 단지 cr 이라고 말하는 것으로 간단하게 해석됩니다.일부 상수 = 1 / π 합니다.c . 그러면 단위 디스크의 정규화는 c 를 강제 합니다.
이제 트릭을 소개하겠습니다. 그것은 역 CDF 샘플링으로 알려진 확률 이론에서 비롯된 것 입니다. 확률 밀도 f ( z )를 가진 랜덤 변수 를 생성 하고 싶고 랜덤 변수 U ~ Uniform (0, 1)이 있다고 가정합니다. 대부분의 프로그래밍 언어에서. 어떻게하나요?random()
- 먼저 밀도를 누적 분포 함수 또는 CDF 로 바꾸십시오 .이를 F ( z )라고합니다. CDF는 미분 f ( z)를 사용 하여 0에서 1까지 단조롭게 증가합니다. )를 사용 합니다.
- 그런 다음 CDF의 역함수 F -1 ( z )를 계산합니다 .
- 당신은 발견 할 것이다 Z = F -1 ( U가 ) 목표 밀도에 따라 배포됩니다. (노트 3).
이제 황금비 나선 트릭은 θ 에 대해 매우 균일 한 패턴으로 포인트 간격을 지정 하므로이를 통합 해 보겠습니다. 단위 디스크의 경우 F ( r ) = r 2 로 남습니다 . 따라서 역함수는 F -1 ( u ) = u 1/2 이므로 디스크에 임의의 점을 r = sqrt(random()); theta = 2 * pi * random()
.
이제이 역함수 를 무작위로 샘플링하는 대신 균일하게 샘플링하고, 균일 한 샘플링에 대한 좋은 점은 점이 큰 N 의 한계에서 어떻게 퍼져 있는지에 대한 결과 가 마치 무작위로 샘플링 한 것처럼 동작한다는 것입니다. 이 조합이 트릭입니다. 대신를 random()
사용 (arange(0, num_pts, dtype=float) + 0.5)/num_pts
하므로 10 개의 포인트를 샘플링하려면 r = 0.05, 0.15, 0.25, ... 0.95
. 동일한 면적의 간격을 얻기 위해 r 을 균일하게 샘플링 하고, 출력에서 점의 끔찍한 "막대"를 피하기 위해 해바라기 증분을 사용합니다.
이제 구형에 해바라기를하고
점으로 구에 점을 찍기 위해 필요한 변경 사항은 구면 좌표의 극좌표를 전환하는 것뿐입니다. 물론 방사상 좌표는 우리가 단위 구체에 있기 때문에 여기에 들어 가지 않습니다. 여기서 좀 더 일관성을 유지하기 위해 물리학 자로 훈련을 받았지만 0 ≤ φ ≤ π는 극에서 내려 오는 위도이고 0 ≤ θ ≤ 2π는 경도 인 수학자의 좌표를 사용 합니다. 따라서 위와의 차이점은 기본적으로 변수 r 을 φ로 대체한다는 것 입니다.
r d r d θ 였던 면적 요소는 이제 그다지 복잡하지 않은 sin ( φ ) d φ d θ가 됩니다. 따라서 균일 한 간격을위한 접합 밀도는 sin ( φ ) / 4π입니다. 밖으로 통합 θ를 , 우리는 찾을 수 F ( φ ) = 죄 ( φ ) / 2, 따라서 F ( φ -) = (COS (1 φ / 2)). 이것을 반전하면 균일 한 랜덤 변수가 acos (1-2 u ) 처럼 보일 것임을 알 수 있지만, 우리는 랜덤이 아닌 균일하게 샘플링하므로 대신 φ k = acos (1 − 2 ( k+ 0.5) / N ). 나머지 알고리즘은 이것을 x, y, z 좌표에 투영합니다.
from numpy import pi, cos, sin, arccos, arange
import mpl_toolkits.mplot3d
import matplotlib.pyplot as pp
num_pts = 1000
indices = arange(0, num_pts, dtype=float) + 0.5
phi = arccos(1 - 2*indices/num_pts)
theta = pi * (1 + 5**0.5) * indices
x, y, z = cos(theta) * sin(phi), sin(theta) * sin(phi), cos(phi);
pp.figure().add_subplot(111, projection='3d').scatter(x, y, z);
pp.show()
다시 n = 100 및 n = 1000에 대한 결과는 다음과 같습니다.
추가 연구
Martin Roberts의 블로그에 한마디하고 싶었습니다. 위에서 각 인덱스에 0.5를 추가하여 인덱스 오프셋을 생성했습니다. 이것은 시각적으로 매력적 이었지만 오프셋 선택이 매우 중요 하고 간격 동안 일정하지 않으며 올바르게 선택하면 패킹에서 최대 8 % 더 나은 정확도를 얻을 수 있음이 밝혀졌습니다 . 또한 그의 R 2 시퀀스 가 구를 덮도록 하는 방법이 있어야하며, 이것이 아마도있는 그대로의 좋은 균등 커버링을 생성하는지 확인하는 것이 흥미로울 것입니다. 단위 사각형은 대각선으로 자르고 원을 만들기 위해 늘어납니다.
노트
이러한 "바"는 다수 합리적인 근사치에 의해 형성되고, 다수의 가장 합리적인 근사치 지속적인 분획 식 온되는 정수이고, 한정된 양의 정수 또는 무한 시퀀스 중입니다z + 1/(n_1 + 1/(n_2 + 1/(n_3 + ...)))
z
n_1, n_2, n_3, ...
def continued_fraction(r):
while r != 0:
n = floor(r)
yield n
r = 1/(r - n)
분수 부분 1/(...)
은 항상 0과 1 사이에 있기 때문에 연속 된 분수의 큰 정수는 특히 좋은 합리적인 근사치를 허용합니다. "1을 100과 101 사이의 것으로 나눈 것"이 "1과 2 사이의 것으로 나눈 것"보다 낫습니다. 그러므로 가장 비합리적인 숫자는 1 + 1/(1 + 1/(1 + ...))
특히 좋은 합리적 근사치를 갖고 있지 않은 숫자입니다 . 황금 비율에 대한 공식을 얻기 위해 φ 를 곱하여 φ = 1 + 1 / φ 를 풀 수 있습니다 .
NumPy에 익숙하지 않은 사람들을 위해 모든 함수가 "벡터화"되어 있으므로 sqrt(array)
다른 언어가 작성하는 것과 동일 map(sqrt, array)
합니다. 따라서 이것은 구성 요소 별 sqrt
응용 프로그램입니다. 스칼라로 나누거나 스칼라를 추가하는 경우에도 마찬가지입니다. 모든 구성 요소에 병렬로 적용됩니다.
이것이 결과라는 것을 알면 증거는 간단합니다. 당신은 확률 무엇을 요구하는 경우에 z는 < Z는 < Z + D의 z는 ,이 확률 무엇을 물어와 동일한 Z < F -1 ( U는 ) < Z + D z는 적용 F를 가 있음을 주목할 세 가지 표현으로는 단조 증가하는 함수, 따라서 F ( z ) < U < F ( z + d z ), 오른쪽을 확장하여 F ( z ) + f(z ) d z 이고 U 는 균일하기 때문에이 확률은 약속 한대로 f ( z ) d z 입니다.