n次元球面への一様分布入力
ここを参考にn次元球面への一様分布入力を行うプログラムを作ってみた。
/* ** Sphere.java - n次元球面への一様分布を行う */ import java.util.*; public class Sphere{ //n次元球面上に一様分布な入力を作成する public VectorND makeRandom(int d){ int dim=d-1; VectorND x; if(dim%2==0) x=evenSphere(dim); else x=oddSphere(dim); return x; } //奇数次元球面の場合 public VectorND oddSphere(int dim){ int m=(dim+1)/2; VectorND x; if(m<2){ x=new VectorND(2); double phi=Math.random()*2*Math.PI; x.e[0]=Math.sin(phi); x.e[1]=Math.cos(phi); }else{ double theta=Math.random(); double phi=Math.random()*2*Math.PI; x=new VectorND(2*m); VectorND v=oddSphere(2*m-3); for(int i=0;i<2*m-2;i++) x.e[i]=v.e[i]*Math.sqrt(Math.pow(theta,1/(double)(m-1))); x.e[2*m-2]=Math.sqrt(1-Math.pow(theta,1/(double)(m-1)))*Math.sin(phi); x.e[2*m-1]=Math.sqrt(1-Math.pow(theta,1/(double)(m-1)))*Math.cos(phi); } return x; } //偶数次元の球面の場合 public VectorND evenSphere(int dim){ int m=dim/2; VectorND x; if(m<2){ double theta=Math.random()*2-1; double phi=Math.random()*2*Math.PI; x=new VectorND(3); x.e[0]=theta; x.e[1]=Math.sqrt(1-theta*theta)*Math.sin(phi); x.e[2]=Math.sqrt(1-theta*theta)*Math.cos(phi); }else{ double theta=Math.random(); double phi=Math.random()*2*Math.PI; x=new VectorND(2*m+1); VectorND v=evenSphere(2*m-2); for(int i=0;i<2*m-2;i++) x.e[i]=v.e[i]*Math.pow(theta,1/(double)(2*m-1)); x.e[2*m-1]=Math.sqrt(1-Math.pow(theta,2/(double)(2*m-1)))*Math.sin(phi); x.e[2*m]=Math.sqrt(1-Math.pow(theta,2/(double)(2*m-1)))*Math.cos(phi); } return x; } //メイン public static void main(String[] args){ int n=1000; int dim=3; Sphere sp=new Sphere(); for(int j=0;j<n;j++){ VectorND x=sp.makeRandom(dim); for(int i=0;i<x.e.length;i++) System.out.print(x.e[i]+" "); System.out.println(); } } } 」
これでOK!かと思ったら、
改・一般次元での単位球体内・球面上の一様分布
がありました。実装しなおそう