n次元球面上への一様分布-続

前回に引き続き、
n次元球面上への一様分布の改良を行ってみた

/*
**  Sphere.java  -  n次元球面への一様分布を行う
*/

public class Sphere{

  //n次元球面上に一様分布な入力を作成する
  public VectorND makeRandom(int dim){
    if(dim<2) return null;

    VectorND x=new VectorND(dim);

    if(dim==2)  x=make1D();
    else if(dim==3) x=make2D();
    else x=makeND(dim);
    
    return x;
  }

  //2次元球面上への一様分布 - 1次元分布
  public VectorND make1D(){
    VectorND x=new VectorND(2);
    double phi=Math.random()*Math.PI*2;
    x.e[0]=Math.sin(phi);
    x.e[1]=Math.cos(phi);
    
    return x;
  }

  //3次元球面上への一様分布 - 2次元分布
  public VectorND make2D(){
    VectorND x=new VectorND(3);
    double theta=Math.random()*2-1;
    double phi=Math.random()*Math.PI*2;
    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);
    
    return x;
  }

  //N次元球面上への一様分布 - n-1次元分布
  public VectorND makeND(int dim){
    VectorND x=new VectorND(dim);
    VectorND v;
    double phi=Math.random()*Math.PI*2;
    double theta=Math.random();
    
    v=makeRandom(dim-2);
    for(int i=0;i<dim-2;i++)
      x.e[i]=v.e[i]*Math.pow(theta,1/(double)(dim-2));
    x.e[dim-2]=Math.sqrt(1-Math.pow(theta,2/(double)(dim-2)))*Math.sin(phi);
    x.e[dim-1]=Math.sqrt(1-Math.pow(theta,2/(double)(dim-2)))*Math.cos(phi);
    
    return x;
  }

  //テスト用のメイン
  public static void main(String[] args){
    int num=1000;
    int dim=10;
    Sphere sp=new Sphere();

    for(int i=0;i<num;i++){
      VectorND x=sp.makeRandom(dim);
      System.out.println("["+i+"]="+x.norm());
    }
  }
}

実行してみた感じでは、ちゃんと上手く動いてると思う。*1