Source code in C to simulate a Speckle Potential

Addendum: After writing this post I had a nagging feeling. Some kind of unease about the codes I provided. After taking a quick read of my second edition of Numerical Recipes in C I realized what might have caused that nagging feeling. Copyright! I realized that by posting portions of their code as it was I was violating the terms of he license.

I’m not the biggest fan of the concept of copyright, but I have to respect those that are, and I have to respect them even more when I use their work in ways that are positive to my line of work. Thus I’ve decided to redact everything that is from the Numerical Recipes but I’ll leave the lines of code that belong to me.

And just to clarify things: everything that comes from me on this blog can be used by others as long as they respect the terms put forward in this license: Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

In this post I provided a code that enable one to compute some properties of fermions when subjected to a cigar shaped trap potential.

Then I posted a Mathematica code that allows one one to simulate a speckle potential.

Now I’ll provide the code I did back in the day in order to simulate a speckle potential. This code uses some of the routines available in the Numerical Recipes in C and like in the previous posts I’ll also provide the graphs I obtained back then.

I used the files nr.h, nrutil.h and nrutil.c from Numerical Recipes in C.

And this is my code:


#include<stdio.h>
#include<math.h>
#include <stdlib.h>
#include<string.h>
#include<malloc.h>

#include"nr.h"
#include"nrutil.h"

#define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr

#define IM1 2147483563
#define IM2 2147483399
#define AM (1.0/IM1)
#define IMM1 (IM1-1)
#define IA1 40014
#define IA2 40692
#define IQ1 53668
#define IQ2 52774
#define IR1 12211
#define IR2 3791
#define NTAB 32
#define NDIV (1+IMM1/NTAB)
#define EPS 1.2e-7
#define RNMX (1.0-EPS)

/*
Replaces data by its ndim-dimensional discrete Fourier transform, if isign is input as 1.
nn[1..ndim] is an integer array containing the lengths of each dimension (number of complex
values), which MUST all be powers of 2. data is a real array of length twice the product of
these lengths, in which the data are stored as in a multidimensional complex array: real and
imaginary parts of each element are in consecutive locations, and the rightmost index of the
array increases most rapidly as one proceeds along data. For a two-dimensional array, this is
equivalent to storing the array by rows. If isign is input as -1, data is replaced by its inverse
transform times the product of the lengths of all dimensions.
*/

void fourn(float data[], unsigned long nn[], int ndim, int isign);

float ran2(long *idum);
float gasdev(long *idum);

void histogram(float vector[],int num,unsigned long int dimension, char name[]);
void average_intensity(float vector[],int dim);
void probability_density_function(int vector_count[],float vector_classes[], float bin,int nbin,int dim,char file_name[]);

int main()
{
unsigned long int dim=512;
int ndim=2;
int i,j,k,num_aux,l;
unsigned long *nn;
float **grid,**matrix_aux;
/*
**grid is the matrix were we are going to save the values of the field intensities at each point of our grid
**matrix_aux is the matrix that is going to be used on the definition of the window function
*/
float *data; // The values of the electric fields are going to be saved on this vector
float vector_histogram[dim*dim],aux;
long int iseed=-1;
FILE *f_out,*f_intensity;

char nome[35]="Speckle_Potential_";
char nome_2[20]="Intensity_";
char ext[]=".dat";
char num[5];

sprintf(num,"%d",(int)dim);

strcat(nome,num);
strcat(nome,ext);

strcat(nome_2,num);
strcat(nome_2,ext);

num_aux=2*dim*dim;
data=vector(1,num_aux);
nn=lvector(1,ndim);
grid=matrix(1,dim,1,dim);
matrix_aux=matrix(1,dim,1,2*dim);

f_out=fopen(nome,"w+");
f_intensity=fopen(nome_2,"w+");

/*
Initialization of the nn vector with the number of points of each dimension.
*/

for(i=1;i<=ndim;i++)
nn[i]=dim;

/*
Initialization of the elements of the grid
*/

/*
Real part of the electric field initialization
*/

for(i=0; i<=(num_aux-2)/2; i++)
data[i*2+1]=gasdev(&iseed);

/*
Imaginary part of the electric field initialization
*/

for(i=1;i<=num_aux/2;i++)
data[2*i]=gasdev(&iseed);

/*
End of the initialization of the grid
*/


/*
Fast fourier Transform algorithm
*/

fourn(data,nn,ndim,1);

/*
End of the Fourier Transform
*/


/*
Window function definition
*/

for(i=1,k=1;i<=dim;i++)
for(j=1;j<=2*dim;j++)
{
matrix_aux[i][j]=data[k];
k=k+1;
}

for(i=1;i<=dim;i++)
for(j=1;j<=2*dim;j++)
{
if( (i>1 && i<dim) && (j>2 && j<2*dim-1) )
matrix_aux[i][j]=matrix_aux[i][j];
else
matrix_aux[i][j]=0;
}

for(i=1,k=1;i<=dim;i++)
for(j=1;j<=2*dim;j++)
{
data[k]=matrix_aux[i][j];
k=k+1;
}

/*
Inverse Fourier Transform in order to create E'(x,y)
*/

fourn(data,nn,ndim,-1);

/*
E'(x,y) field has been created but lacks the normalization procedure
so we have to normalize it by hand.
*/

for(i=1;i<=num_aux;i++)
data[i]=data[i]/(dim*dim);

for(i=1,k=1,l=0;i<=dim;i++)
for(j=1;j<=dim;j++)
{
grid[i][j]=data[k]*data[k]+data[k+1]*data[k+1];
k=k+2;
fprintf(f_out,"%d\t%d\t%f\n",i,j,grid[i][j]);
fprintf(f_intensity,"%f\n",grid[i][j]);
vector_histogram[l]=grid[i][j];
l=l+1;
}

histogram(vector_histogram,dim,dim*dim,nome_2);
average_intensity(vector_histogram,dim*dim);

free_vector(data,1,num_aux);
free_lvector(nn,1,ndim);
free_matrix(grid,1,dim,1,dim);
free_matrix(matrix_aux,1,dim,1,2*dim);

fclose(f_out);
fclose(f_intensity);

return 0;
}

void histogram(float vector[],int num,unsigned long int dimension, char name[])
{
float class;
float num_max,num_min,aux,sum_aux=0;
FILE *f_hist;
int interval=100,i,j;
float hist[interval];
int count[interval];
char file_name[30]="Histogram_";

strcat(file_name,name);

for(i=0;i<interval;i++)
count[i]=0;

f_hist=fopen(file_name,"w+");

num_max=vector[0];
num_min=vector[0];

for(i=0;i<dimension;i++)
{
aux=vector[i];
if(aux>num_max)
num_max=aux;
}

for(i=0;i<dimension;i++)
{
aux=vector[i];
if(aux<num_min)
num_min=aux;
}
num_min=0;
class=(num_max-num_min)/(interval);

for(i=0;i<interval;i++)
hist[i]=num_min+i*class;

for(i=0;i<dimension;i++)
{
aux=vector[i];
for(j=0;j<interval;j++)
if((aux>=num_min+j*class) && (aux<=num_min+(j+1)*class))
count[j]=count[j]+1;
}

for(i=0;i<interval;i++)
{
sum_aux=0;
for(j=i;j<interval-1;j++)
sum_aux=sum_aux+count[j];

fprintf(f_hist,"%f\t%f\n",(hist[i]+hist[i+1])/2,sum_aux/dimension);
}

probability_density_function(count,hist,class,interval,dimension,name);

fclose(f_hist);
}

void average_intensity(float vector[], int num)
{
int i;
float average=0;
FILE *f_average;

f_average=fopen("Average_Intensity.dat","a+");

for(i=0;i<num;i++)
average=average+vector[i];

fprintf(f_average,"Average intensity in %d*%d grid is %f\n",(int)sqrt(num),(int)sqrt(num),average/num);
}

void probability_density_function(int vector_count[],float vector_classes[], float bin,int nbin,int dim,char file_name[])
{
float function_density[nbin],data_frequency[nbin];
FILE *f_density;
int i;
char name[30]="Density_Function_";

strcat(name,file_name);

f_density=fopen(name,"w+");

for(i=0;i<nbin;i++)
data_frequency[i]=vector_count[i]/(float)dim;

for(i=0;i<nbin;i++)
function_density[i]=data_frequency[i]/bin;

for(i=0;i<nbin;i++)
fprintf(f_density,"%f\t%f\n",vector_classes[i],function_density[i]);

fclose(f_density);

}

void fourn(float data[], unsigned long nn[], int ndim, int isign)
{
This code belongs to Numerical Recipes in C so I've redacted it.
}

float ran2(long *idum)
/*
Long period (> 2^1018) random number generator of L'Ecuyer with Bays-Durham shue
and added safeguards. Returns a uniform random deviate between 0.0 and 1.0 (exclusive of
the endpoint values). Call with idum a negative integer to initialize; thereafter, do not alter
idum between successive deviates in a sequence. RNMX should approximate the largest floating
value that is less than 1.
*/

{
This code belongs to Numerical Recipes in C so I've redacted it.
}

float gasdev(long *idum)
/*Returns a normally distributed deviate with zero mean and unit variance, using ran1(idum)
as the source of uniform deviates.*/
{

This code belongs to Numerical Recipes in C so I've redacted it.
}

We can change the size of the grid that we use to simulate the formation of the speckle pattern. The sizes that I used were 64×64, 128×128, 256×256 and 512×512. This progression allowed me to realize that Statistical Properties of the simulated speckle pattern got closer and closer to the statistical properties of a real speckle pattern.

As can be seen from the graphs the agreement gets better and better as the size of the grid one uses gets bigger.

References:

  1. M. Modugno, cond-mat/0509807.
  2. Goodman, J. W.: Statistical Properties of Laser Speckle Patterns
Posted in C, Condensed Matter, Physics, Programming | Leave a comment

Science 2.0

I truly believe in it. As the astute reader might have noticed by looking at the links to the right…

If you don’t know what I’m talking about take a look at this: The future of science by Michael Nielsen. And if you don’t read the whole series of posts be sure to read Doing science online and all of its comments.

So now you know a little bit more what to expect from this blog.

Posted in General | Leave a comment

Imitation is the sincerest (form) of flattery

Today was a slow day so I was surfing the web to see if anything mildly interesting happened in my favorite blogs (by the way, my favorite blog for the time being is mathbabe, so do check it out). I took to a few blogs and then wandered to a blog that has been inactive for quite a while: The Everything Seminar.

For no particular reason I checked out their about page (since I was very late to their party I think that this was the first time I did that) and I found something that makes a lot of sense to me:

A note on the tags:

As far as our tags go, we try to tag posts with the appropriate arxiv subject. If enough math blogs do this, then those tags should be able to generate journal-style compilations of posts on a topic.

Now, I’m not the one to put tags on my posts, but I do use categories. Thus from now on the categories on this blog will folow an arxiv inspired classification.

This classification makes so much sense that I feel kind of stupid for not thinking about it in the first place…

Posted in General | Leave a comment

Trick with partial derivatives in Statistical Physics

— 1. The problem —

Some time ago I was studying Statistical Physics and I ended up solving an interesting exercise. The exercise in question is from the book Statistical Physics by Mandl and it is on page 66:

A system possesses three energy levels {E_1=\epsilon}, {E_2=2 \epsilon} and {E_3=3 \epsilon}, with degeneracies {g(E_1)=g(E_3)=1}, {g(E_2)=2}. Find the heat capacity of the system.

The first time I solved this problem I did it in a normal way, but then I realized something that allowed to simplify my calculations and solve the problem in a more elegant way.

First we have to calculate the partition function, {Z}, for this system.

— 1.1. First Solution —

Since what matters in this problem is the difference of energies we let {E_2=0}.

{\begin{aligned} Z &= \displaystyle \sum_{E_r}g(E_r)e^{-\beta E_r} \\ &= e^{\beta \epsilon}+2+2e^{-\beta \epsilon} \\ &= 2(1+ \cosh (\beta \epsilon)) \end{aligned}}

After calculating the partition function we have to calculate the mean energy, {\bar{E}}, of this system. By definition it is:

{\begin{aligned} \bar{E} &= -\dfrac{\partial}{\partial \beta} \ln Z \\ &= -\dfrac{\partial}{\partial \beta} \ln 2(1+ \cosh (\beta \epsilon)) \\ &= -\dfrac{2 \epsilon \sinh (\beta \epsilon)}{2(1+\cosh (\beta \epsilon))} \\ &= -\dfrac{\epsilon \sinh (\beta \epsilon)}{1+\cosh (\beta \epsilon)} \end{aligned}}

By definition {c} is

{\begin{aligned} c &= \dfrac{\partial \bar{E}}{\partial T} \\ &= -\dfrac{\partial}{\partial T} \left( \dfrac{\epsilon \sinh (\beta \epsilon)}{1+\cosh (\beta \epsilon)}\right) \end{aligned}}

To differentiate the last expression with respect to {T} isn’t that hard, but it is bothersome and if one isn’t careful the possibility of making a mistake shouldn’t be discarded.

Keeping in mind that in Statistical Physics it is {\beta = 1/(kT)}, it follows that (this is the point were I start to use the mathematical trick):

{\begin{aligned} c &= \dfrac{\partial \bar{E}}{\partial T} \\ &= k \dfrac{\partial \bar{E}}{\partial (kT)} \\ &= k \dfrac{\partial \bar{E}}{\partial (1/\beta)} \\ &= -\beta ^2 k \dfrac{\partial \bar{E}}{\partial \beta}\\ &= \beta ^2 k \dfrac{\partial}{\partial \beta}\left( \dfrac{\epsilon \sinh (\beta \epsilon)}{1+\cosh (\beta \epsilon)}\right) \end{aligned}}

Please notice that I haven’t differentiated anything so far. All I’ve done is to change variables in order to calculate the derivative in an easier way.

This last expression is already easy to differentiate but we are caught up in the moment and we’ll just make one more change of variable.

{\begin{aligned} c &= \beta ^2 k \dfrac{\partial}{\partial \beta}\left( \dfrac{\epsilon \sinh (\beta \epsilon)}{1+\cosh (\beta \epsilon)}\right) \\ &= \beta ^2 \epsilon ^2 k \dfrac{\partial}{\partial (\beta \epsilon)}\left( \dfrac{ \sinh (\beta \epsilon)}{1+\cosh (\beta \epsilon)}\right) \\ &= x ^2 k \dfrac{\partial}{\partial x}\left( \dfrac{ \sinh x}{1+\cosh x}\right) \\ &= x ^2 k \dfrac{\cosh x + \cosh ^2 x - \sinh ^2 x}{(1+ \cosh x)^2} \\ &= x ^2 k \dfrac{\cosh x + 1}{(1+ \cosh x)^2} \\ &= \dfrac{x ^2 k}{1+ \cosh x} \end{aligned}}

Yes, in this case the simplification of the hard work involved wasn’t that big, but I think that we should keep in mind this type of reasoning. This way we can apply it to similar scenarios that appear countless times in Physics and Mathematics.

— 1.2. Second Solution —

The previous steps could be even more simplified if we let {E_1=0} and remember an elementary algebraic identity.

{\begin{aligned} Z &= 1+2e^{-\beta \epsilon}+e^{-\beta 2\epsilon} \\ &= (1+e^{-\beta \epsilon})^2 \\ \end{aligned}}

With this expression the calculus of {\bar{E} } and {c} is a lot easier.

{\begin{aligned} \bar{E} &= -\dfrac{\partial}{\partial \beta} \ln Z \\ &= -\dfrac{\partial}{\partial \beta} \ln(1+e^{-\beta \epsilon})^2 \\ &= -2\dfrac{\partial}{\partial \beta} \ln(1+e^{-\beta \epsilon}) \\ &= \dfrac{2\epsilon e^{-\beta\epsilon}}{1+e^{-\beta \epsilon}} \\ &= \dfrac{2\epsilon}{1+e^{\beta \epsilon}} \end{aligned}}

Now for {c} it is

{\begin{aligned} c &= \dfrac{\partial \bar{E}}{\partial T} \\ &= \dfrac{\partial}{\partial T}\left( \dfrac{2\epsilon}{1+e^{\beta \epsilon}}\right) \end{aligned}}

Even though this expression is relatively easy to differentiate with respect to {T} than {-\dfrac{\epsilon \sinh (\beta \epsilon)}{1+\cosh (\beta \epsilon)}} we’ll use the same technique of change of variables that we already know:

{\begin{aligned} c &= \dfrac{\partial \bar{E}}{\partial T} \\ &= k \dfrac{\partial \bar{E}}{\partial (kT)} \\ &= k \dfrac{\partial \bar{E}}{\partial (1/\beta)} \\ &= -\beta ^2 k \dfrac{\partial \bar{E}}{\partial \beta}\\ &= -2\beta^2 \epsilon k \dfrac{\partial}{\partial \beta}\left( \dfrac{1}{1+e^{\beta \epsilon}}\right)\\ &= -2x^2 k \dfrac{\partial}{\partial x}\left( \dfrac{1}{1+e^{x}}\right)\\ &= 2k\dfrac{x^2e^x}{(1+e^{x})^2} \end{aligned}}

An expression that is, apparently, different from {\dfrac{x ^2 k}{1+ \cosh x}}.

The proof that these two expressions for {c} are indeed the same is left as an exercise for the reader.

— 2. Appendixes —

In this section we will show that the value of {c} doesn’t depend on what level we consider to be the zero level of energy. We will also show some elementary properties of derivatives taking into account the change of variables.

— 2.1. Derivatives and changes of variables —

Throughout this text we used the properties of changes of variables in derivatives. The goal of this section is to give some quick proofs of the said properties.

Let {u=u(x)}. It is an elementary result that {\dfrac{\partial}{\partial u}=\dfrac{\partial x}{\partial u}\dfrac{\partial}{\partial x}}.

If it is {u=kx} then

\displaystyle \dfrac{\partial}{\partial u}=\dfrac{1}{k}\dfrac{\partial}{\partial x} \ \ \ \ \ (1)

 

If it is {u=1/x} then

\displaystyle \dfrac{\partial}{\partial u}=-\dfrac{1}{u^2}\dfrac{\partial}{\partial x} \ \ \ \ \ (2)

 

Rewriting equation 1 and equation 2 in order to {\dfrac{\partial}{\partial x}} we get the equalities used in the text.

— 2.2. The invariance of {c}

In the two deductions of {c} we took the the {0} level of energy the level that was most convenient. In the interest of having a self contained post we’ll give a justification of why this can be so.

The partition function of the system is {Z=e^{-\beta \epsilon}+2e^{-\beta 2\epsilon}+e^{-\beta 3\epsilon}}.

First we let {E_2=0}, and the partition function was {Z_2=e^{\beta \epsilon}+2+e^{-\beta \epsilon}}; while in the other resolution we let {E_1=0}, obtaining the partition function {Z_1=1+2e^{-\beta \epsilon}+e^{-\beta 2\epsilon}}.

Hence {Z_2=e^{\beta E_2} Z} and {Z_1=e^{\beta E_1} Z}. This method is readily generalized to {p} levels of energy where one has {Z_n=e^{\beta E_n} Z}, with {n\leq p}.

What we want to show is that for {Z} and {Z_n} it follows {c_n=c}.

{\begin{aligned} c_n &= \dfrac{\partial\bar{E}_n}{\partial T} \\ &= -\dfrac{\partial}{\partial T}\dfrac{\partial}{\partial \beta}\ln Z_n \\ &= -\dfrac{\partial}{\partial T}\dfrac{\partial}{\partial \beta}\ln \left( e^{-\beta E_n}Z\right) \\ &= -\dfrac{\partial}{\partial T}\dfrac{\partial}{\partial \beta}\ln e^{-\beta E_n} -\dfrac{\partial}{\partial T}\dfrac{\partial}{\partial \beta}\ln Z \\ &= \dfrac{\partial}{\partial T}\dfrac{\partial}{\partial \beta}(\beta E_n)+c\\ &= \dfrac{\partial}{\partial T} E_n+c\\ &= 0+c\\ &= c \end{aligned}}

Posted in Calculus, Mathematics, Physics, Statistical Physics | 2 Comments

Mathematica Resources

Well just because I suck at Mathematica programming it doesn’t mean you should suck at it too. Nor does it mean that I should suck at it forever.

With that in mind I want to bring to your attention a couple of resources on Mathematica that are certainly very useful.

The first one is An Introduction to Programming with Mathematica which a very nice book with a lot of examples. In Wolfram Library Archive you can find some additional files for the book.

The other book I’ll mention is freely available and quite frankly is very, very good. You can get it here with a lot of additional resources.

I’ll give myself two or three months to read these books and in the meantime I hope to become better at Mathematica.

Posted in General, Mathematica, Programming | 2 Comments

Some more jazz

In a previous post I’ve already mentioned a few books that are useful for people that want to get into Quantum Mechanics and Field Theory.

This time I want to add two more suggestions:

  1. Relativistic Quantum Mechanics and Field Theory.
  2. Some Notes on Scattering.

Yep, and this is it. In the nex week or so a few developments on this issue will start to appear in here.

In another news, the semester is finally over (which means that the pains of grading exams are about to come) and that just means more free time for me to get back to shape.

Don’t get me wrong, though! I do love the interaction with all of my students but after a while I just love it a tiny little bit less…

Ps: This website by Gerard ‘t Hooft also has a lot of goodies: HOW to BECOME a GOOD THEORETICAL PHYSICIST.

Posted in Books, Physics | Leave a comment

Not on a blogging binge

So no need to worry my dear three our four readers (that also includes me) that I do have a life. I’m just posting my old posts from Exploring the Mountain to my new place.

The thing is that I don’t see any point in having two separate blogs that are very closely interrelated. Thus I decided to go on a merger and I’m keeping all stuff Science related (more or less) in one just place.

Posted in General | Leave a comment