Пример #1
0
double PartialOmega(int k0, double *r, int k) {
  int i, k1, g, g2, i0, i1, i2, i3;
  double a, b, c, x;

  x = 0.0;
  for (i = 0; i <= k; i++) {
    k1 = k0 + i*2 - k;
    a = 2.0*(2.0*k0+1.0)*(2.0*k1+1.0);
    g2 = k0 + k1 + k;
    g = g2/2;
    i0 = g2 - 2*k0;
    i1 = g2 - 2*k1;
    i2 = g2 - 2*k;
    if (i2 < 0) i2 = 0;
    i3 = g2 + 1;
    b = LnFactorial(i0)+LnFactorial(i1)+LnFactorial(i2)-LnFactorial(i3);
    i0 = g - k0;
    i1 = g - k1;
    i2 = g - k;
    if (i2 < 0) i2 = 0;
    c = LnFactorial(g)-LnFactorial(i0)-LnFactorial(i1)-LnFactorial(i2);
    b += 2.0*c;
    b = exp(b);
    x += a*b*r[i]*r[i];
  }

  return x;
}
Пример #2
0
/*
** Wigner d-matrix <jm|exp(-iJ_y*a)|jn>
** j2 = j*2, m2 = m*2, n2 = n*2
*/
double WignerDMatrix(double a, int j2, int m2, int n2) {
    double b, c, ca, sa, x;
    int k, kmin, kmax;

    a *= 0.5;
    kmin = Max(0, (m2+n2)/2);
    kmax = Min((j2+m2)/2, (j2+n2)/2);
    ca = cos(a);
    sa = sin(a);
    x = 0.0;
    for (k = kmin; k <= kmax; k++) {
        b = pow(ca, (2*k-(m2+n2)/2));
        b *= pow(sa, (j2+(m2+n2)/2-2*k));
        c = LnFactorial(k);
        c += LnFactorial((j2+m2)/2-k);
        c += LnFactorial((j2+n2)/2-k);
        c += LnFactorial(k-(m2+n2)/2);
        b /= exp(c);
        if (IsOdd(k)) b = -b;
        x += b;
    }
    c = LnFactorial((j2+m2)/2);
    c += LnFactorial((j2-m2)/2);
    c += LnFactorial((j2+n2)/2);
    c += LnFactorial((j2-n2)/2);
    c = exp(0.5*c);
    if (IsOdd((j2+m2)/2)) c = -c;
    x *= c;

    return x;
}
Пример #3
0
// divide N particles among p compartments
int main(void) // takes in no parameters
{
  int i,j,k,l,index;
  int P,N,Ncycle;
  double Distribution[MAX_COMPARTMENTS][MAX_PARTICLES]; //2D Array: what are the brackets doing here? Okay most likely they are to define the dimensionality of the array.
  int NumInComp[MAX_COMPARTMENTS]; //1D Array: declaring number of particles in compartment
  FILE *FilePtr; //created sufficient memory for FilePtr

  // initialize the random number generator with the system time
  InitializeRandomNumberGenerator(time(0l)); //most likely a function located in ran_uniform.h; I think time(01) is supposed to be the seed value for the generator

  // read the input parameters
  printf("Number of Particles N? "); 
  fscanf(stdin,"%d",&N); //I REALLY DON'T Understand what fscanf is doing in this situation
 
  printf("Number of Compartments p? ");
  fscanf(stdin,"%d",&P);

  printf("Number of Cycles (x %d)? ",CycleMultiplication);
  fscanf(stdin,"%d",&Ncycle);

  if(P<2||P>MAX_COMPARTMENTS||N<2||N>MAX_PARTICLES)
  {
    printf("Error in input parameters\n");
    exit(1); //what does exit do here (and what is the 1 for?)
  }

  // initialize: So you have to make sure every entry is zero? What is the default setting?
  for(i=0;i<N;i++)
  {
    for(j=0;j<P;j++)
    {
      Distribution[j][i]=0.0;
      NumInComp[j]=0;
    }
  }

  // loop over all cycles
  for(i=0;i<Ncycle;i++)
    for(k=0;k<CycleMultiplication;k++)
    {

  // Distribute particles over the compartments:
  // Loop over all particles, pick a random compartment, and add 
  // a particle to it.
  // A random number in the interval [0,1> can be generated using 
  // RandomNumber().

  // NumInComp[index] = number of particles in compartment 'index'.

      // start modification

      for(l=0;l<N;l++)
      {
        index = round(RandomNumber()*(P));
        NumInComp[index] += 1;
      }


      // end modification

      // make a histogram
      for(j=0;j<P;j++)
      {
        Distribution[j][NumInComp[j]]+=1.0;
        NumInComp[j]=0;
      }
    }

  // Write Results
  FilePtr=fopen("results.dat","w");
  for(j=0;j<P;j++)
  {
    for(i=0;i<N;i++)
    {

      if(Distribution[j][i]>0.0)
        Distribution[j][i]/=(double)Ncycle*CycleMultiplication;

      fprintf(FilePtr,"%d %f\n",i,Distribution[j][i]);
    }
    fprintf(FilePtr,"\n");
  }
  fclose(FilePtr);

  // write analytical distribution
    FilePtr=fopen("analytical.dat","w");

    for(j=0;j<N;j++)
    {
      fprintf(FilePtr,"%d %f\n",j,exp(LnFactorial(N)-LnFactorial(j)-
                       LnFactorial(N-j)-j*log(P)-(N-j)*log(P/((double)(P-1)))));
    }

    fclose(FilePtr);
  return 0;
}
Пример #4
0
/*
** FUNCTION:    W6j.
** PURPOSE:     calculate the 6j symbol.
** INPUT:       {int j1},
**              angular momentum.
**              {int j2},
**              angular momentum.
**              {int j3},
**              angular momentum.
**              {int i1},
**              angular momentum.
**              {int i2},
**              angular momentum.
**              {int i3},
**              angular momentum.
** RETURN:      {double},
**              6j symbol.
** SIDE EFFECT:
** NOTE:
*/
double W6j(int j1, int j2, int j3, int i1, int i2, int i3) {
    int n1, n2, n3, n4, n5, n6, n7, k, kmin, kmax, ic, ki;
    double r, a;

#ifdef PERFORM_STATISTICS
    clock_t start, stop;
    start = clock();
#endif

    if (!(Triangle(j1, j2, j3) &&
            Triangle(j1, i2, i3) &&
            Triangle(i1, j2, i3) &&
            Triangle(i1, i2, j3)))
        return 0.0;

    n1 = (j1 + j2 + j3) / 2;
    n2 = (i2 + i1 + j3) / 2;
    n3 = (j1 + i2 + i3) / 2;
    n4 = (j2 + i1 + i3) / 2;
    n5 = (j1 + j2 + i2 + i1) / 2;
    n6 = (j1 + i1 + j3 + i3) / 2;
    n7 = (j2 + i2 + j3 + i3) / 2;

    kmin = Max(n1, n2);
    kmin = Max(kmin, n3);
    kmin = Max(kmin, n4) + 1;
    kmax = Min(n5, n6);
    kmax = Min(kmax, n7) + 1;

    r = 1.0;
    ic = 0;
    for (k = kmin + 1; k <= kmax; k++) {
        ki = kmax -ic;
        r = 1.0 - (r * ki * (n5-ki+2.0) * (n6-ki+2.0) * (n7-ki+2.0))/
            ((ki-1.0-n1) * (ki-1.0-n2) * (ki-1.0-n3) * (ki - 1.0 - n4));
        ic++;
    }

    a = (LnFactorial(kmin) -
         LnFactorial(kmin-n1-1) -
         LnFactorial(kmin-n2-1) -
         LnFactorial(kmin-n3-1) -
         LnFactorial(kmin-n4-1) -
         LnFactorial(n5+1-kmin) -
         LnFactorial(n6+1-kmin) -
         LnFactorial(n7+1-kmin)) +
        ((LnFactorial(n1-j1) + LnFactorial(n1-j2) +
          LnFactorial(n1-j3) - LnFactorial(n1+1) +
          LnFactorial(n2-i2) + LnFactorial(n2-i1) +
          LnFactorial(n2-j3) - LnFactorial(n2+1) +
          LnFactorial(n3-j1) + LnFactorial(n3-i2) +
          LnFactorial(n3-i3) - LnFactorial(n3+1) +
          LnFactorial(n4-j2) + LnFactorial(n4-i1) +
          LnFactorial(n4-i3) - LnFactorial(n4+1))/2.0);

    r = r * exp(a);

    if (IsEven(n5+kmin)) r = -r;
    if (IsOdd(((j1+j2+i1+i2)/2))) r = -r;

#ifdef PERFORM_STATISTICS
    stop = clock();
    timing.w6j += stop - start;
#endif
    return r;

}
Пример #5
0
/*
** FUNCTION:    W3j.
** PURPOSE:     calculate the Wigner 3j symbol.
** INPUT:       {int j1},
**              angular momentum.
**              {int j2},
**              angular momentum.
**              {int j3},
**              angular momentum.
**              {int m1},
**              projection of j1.
**              {int m2},
**              projection of j2.
**              {int m3},
**              projection of j3.
** RETURN:      {double},
**              3j coefficients.
** SIDE EFFECT:
** NOTE:        the _sumk array is used to store all
**              summation terms to avoid overflow.
**              the predefined MAXTERM=512 allows the
**              maximum angular momentum of about 500.
**              if this limit is exceeded, the routine
**              issues a warning.
*/
double W3j(int j1, int j2, int j3, int m1, int m2, int m3) {
    int i, k, kmin, kmax, ik[14];
    double delta, qsum, a, b;

#ifdef PERFORM_STATISTICS
    clock_t start, stop;
    start = clock();
#endif

    if (m1 + m2 + m3) return 0.0;
    if (!Triangle(j1, j2, j3)) return 0.0;
    if (abs(m1) > j1) return 0.0;
    if (abs(m2) > j2) return 0.0;
    if (abs(m3) > j3) return 0.0;

    ik[0] = j1 + j2 - j3;
    ik[1] = j1 - j2 + j3;
    ik[2] = -j1 + j2 + j3;
    ik[3] = j1 + j2 + j3 + 2;
    ik[4] = j1 - m1;
    ik[5] = j1 + m1;
    ik[6] = j2 - m2;
    ik[7] = j2 + m2;
    ik[8] = j3 - m3;
    ik[9] = j3 + m3;
    ik[10] = j2 - j3 - m1;
    ik[11] = j1 - j3 + m2;
    ik[12] = j3 - j2 + m1;
    ik[13] = j1 - j2 - m3;

    for (i = 0; i < 14; i++) {
        ik[i] = ik[i] / 2;
    }

    delta = - LnFactorial(ik[3]);
    for (i = 0; i < 3; i++) delta += LnFactorial(ik[i]);
    for (i = 4; i < 10; i++) delta += LnFactorial(ik[i]);

    kmin = Max(0, ik[10]);
    kmin = Max(kmin, ik[11]);
    kmax = Min(ik[0], ik[4]);
    kmax = Min(kmax, ik[7]);

    qsum = 0.0;
    a = 1E30;
    for (k = kmin, i = 0; k <= kmax && i < MAXTERM; k++, i++) {
        _sumk[i] = LnFactorial(k) +
                   LnFactorial(ik[0]-k) +
                   LnFactorial(ik[4]-k) +
                   LnFactorial(ik[7]-k) +
                   LnFactorial(ik[12]+k) +
                   LnFactorial(k-ik[11]);
        if (_sumk[i] < a) a = _sumk[i];
    }
    if (i == MAXTERM) {
        printf("Maximum terms in the 3j symbol sum reached\n");
        printf("Results may be inaccurate\n");
    }
    for (k = kmin, i = 0; k <= kmax; k++, i++) {
        b = exp(-(_sumk[i]-a));
        if (IsOdd(k)) b = -b;
        qsum += b;
    }

    if (IsOdd(ik[13])) qsum = -qsum;

    b = exp(0.5*delta-a);
    b *= qsum;

#ifdef PERFORM_STATISTICS
    stop = clock();
    timing.w3j += stop -start;
#endif

    return b;
}