New avenues into Quantum Mechanics

In recent times two articles that can do the seemingly impossible in Quantum Mechanics have been published and they generated some buzz on the interweb.

This first article Observing the Average Trajectories of Single Photons in a Two-Slit Interferometer is notable because the authors show how they were able to observe the trajectories of photons in a double slit experiment and still managed to observe a clear interference pattern. A thing that is impossible to do according to the Complementarity principle.

In the second article, Direct measurement of the quantum wavefunction, the authors computed the the transverse spatial wavefunction of a single photon by means that they consider to be direct. For me, that haven’t read the article, so far it doesn’t seem to be a so direct method as claimed, but nevertheless the level of experimental expertise even to get an indirect computation of the wave function is certainly worthy of respect.

These spectacular achievements were possible because these two teams used weak measurement techniques, together with statistical ensembles of photons and non simultaneous measurements of the complementary variables they set out to determine.

The two abstracts are here (the bold isn’t in the original):

  • Direct measurement of the quantum wavefunction

    The wavefunction is the complex distribution used to completely describe a quantum system, and is central to quantum theory. But despite its fundamental role, it is typically introduced as an abstract element of the theory with no explicit definition. Rather, physicists come to a working understanding of the wavefunction through its use to calculate measurement outcome probabilities by way of the Born rule. At present, the wavefunction is determined through tomographic methods which estimate the wavefunction most consistent with a diverse collection of measurements. The indirectness of these methods compounds the problem of defining the wavefunction. Here we show that the wavefunction can be measured directly by the sequential measurement of two complementary variables of the system. The crux of our method is that the first measurement is performed in a gentle way through weak measurement so as not to invalidate the second. The result is that the real and imaginary components of the wavefunction appear directly on our measurement apparatus. We give an experimental example by directly measuring the transverse spatial wavefunction of a single photon, a task not previously realized by any method. We show that the concept is universal, being applicable to other degrees of freedom of the photon, such as polarization or frequency, and to other quantum systems ? for example, electron spins, SQUIDs (superconducting quantum interference devices) and trapped ions. Consequently, this method gives the wavefunction a straightforward and general definition in terms of a specific set of experimental operations. We expect it to expand the range of quantum systems that can be characterized and to initiate new avenues in fundamental quantum theory.

  • Observing the Average Trajectories of Single Photons in a Two-Slit Interferometer

    A consequence of the quantum mechanical uncertainty principle is that one may not discuss the path or ?trajectory? that a quantum particle takes, because any measurement of position irrevocably disturbs the momentum, and vice versa. Using weak measurements, however, it is possible to operationally define a set of trajectories for an ensemble of quantum particles. We sent single photons emitted by a quantum dot through a double-slit interferometer and reconstructed these trajectories by performing a weak measurement of the photon momentum, postselected according to the result of a strong measurement of photon position in a series of planes. The results provide an observationally grounded description of the propagation of subensembles of quantum particles in a two-slit interferometer.

And an excellent explanation of why this was possible can be found in this blog post Watching Photons Interfere: “Observing the Average Trajectories of Single Photons in a Two-Slit Interferometer”

Advertisements
Posted in 03 Physics, 03 Quantum Mechanics | 1 Comment

Cigar-shaped trap potential

At more or less at the same time that I did the Mathematica code to simulate a speckle pattern producing potential I also had to create a code that recreated a cigar-shaped trap potential. This was done with the goal of calculating a few properties of fermions.

The idea was to first start with a cigar shaped potential and then superimpose a random potential on it (the strength of this random potential would be variable) so that we could see what would happen to the properties of the fermions (the sample that we used was of 10000 fermions) as the randomness would get stronger and stronger.

This post is a preamble and the first in a series that will attempt to derive and explain a few things about this line of work that I tried to follow in my past.

For now I’ll only post the C code I wrote back then, and the graphics I obtained but in future posts I’ll talk more about this, because, even though it isn’t related with my current line of work, it is an interesting topic.

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

/*********************************************
 * Introduction of experimental parameters   *
 *********************************************/

float h=1.00;
float Mf=1.00; 	/* This is the fermion mass. */
float wlong=80.00;
float wtrans=200.00; /* wlong is the frequency on the x-axis and wtrans
			 the frequency on the y-z plane. */
float delta_x=1.0;
float delta_r=0.1;
float L;  
float l;

int n_sample=10000; /* This is the number of fermions given in the sample. */

double Ef,E0,Smax,sqrtPi;

/*********************************************************
 * End of the introduction the experimental parameters   *
 *********************************************************/


const int Num=2600; /* Num will be the variable that will permit us
		       to calculate the number of fermions in function
		       of the fermi energy. */

double hermitepoly(int n, double x); /* Function that will calculate the Hermite 
					polynomial for a given degree and given point.*/


unsigned long int N_fermiEnergy(double a); /*Function that will calculate the number of fermions
					     for each fermi energy. */

double fermienergy(void); /* By examining where this functions changes signs we will calculate
			     the fermi energy of a sample given an initial number of fermions. */

double factorial(int n); /*Calculates the factorial of a given number. */

/* The three wave functions that we obtain after separation of variables. */
/* And th~ese are the properly squared nondimensional functions already. */

double psi1_x(int mx, double x);
double psi2_y(int my, double y);
double psi3_z(int mz, double z);

/* Functions that will allow us to plot the fermion density by calculating
   their contribution in the expression of the fermion density*/
 
double Ns(int n);

double density(double x, double y, double z);

void plot_distribution(void); /* Function that will "plot" the fermion density. */

void integral(void); /* Functional that will calculate the number of fermions acording 
			to function distribution to certify that the program really works. */

int main(void)
{
  E0 = h*(wlong/2 + wtrans);
  Ef=fermienergy();
  printf("Ef=%lf\n",Ef);
  Smax = (Ef-E0)/(h*wtrans)+1;
   
  sqrtPi=sqrt(3.1415927);
  
  L=sqrt(h/(Mf*wlong));  
  l=sqrt(h/(Mf*wtrans));
  
  plot_distribution();
  integral();
    
  return 0;
}

double hermitepoly (int n, double x)
{
  double a;
  double b;
  double c;
  int i;
  
  if (n == 0)
    return 1;
  if (n == 1)
    return 2 * x;
  a = 1.0;
  b = 2.0 * x;
  for (i = 2; i <= n; i++)
    {
      c = b;
      b = 2.0 * x * b - 2.0 * (i - 1.0) * a;
      a = c;
    }
  
  return b;
  
}

unsigned long int N_fermiEnergy(double a)
{
  unsigned long int *Num_niveis;
  unsigned long int Ntot=0;
  double smax;
  int i;
  
  smax=(int)((a-E0)/(h*wtrans)+1);
  
  Num_niveis = (unsigned long int*) malloc((int)smax);
  
  for (i=0; i < smax; i++)
    {
      
      Num_niveis[i]=(i+1)*((int)((a-(E0+i*h*wtrans))/(h*wlong))+1); 
      
      Ntot = Num_niveis[i] + Ntot;
    }
  
  free(Num_niveis);
  
  return Ntot;
  
}

double fermienergy(void)
{
  
  double aux,x1=0,x2=0;
  long int k;
  unsigned long int n_fermions;
  
  for(aux=h*(wlong/2 + wtrans); aux<Num; aux=aux+wlong/12)
    { 
      n_fermions=N_fermiEnergy(aux);
      
      k = n_fermions-n_sample;
      if(k==0)
	return aux;
      else
	{
	  if(k<0)
            {
	      x1=aux;
	      x2=aux+wlong/12;
	    }
	  
	}
    }
  
  return (x1+x2+wlong/6)/2;
  
}

double factorial(int n)
{
  double res=1;
  int i;
    
  for(i=1;i<=n;i++)
    res=res*i;
  
  return res;
}

double psi1_x(int mx, double x)
{
  return (l/L)*pow(hermitepoly(mx,x*l/L),2)*(1/(pow(2,mx)*factorial(mx)*sqrtPi))*exp(-(pow(x,2)*pow(l,2)/pow(L,2)));
}

double psi2_y(int my, double y)
{
  return pow(hermitepoly(my,y),2)*((1/(pow(2,my)*factorial(my)*sqrtPi))*exp(-pow(y,2)));
}

double psi3_z(int mz, double z)
{
  return pow(hermitepoly(mz,z),2)*((1/(pow(2,mz)*factorial(mz)*sqrtPi))*exp(-(pow(z,2))));
}

double Ns(int s)
{
  return (((Ef-(E0+s*h*wtrans))/(h*wlong))+1);
}

double density(double x, double y, double z)
{
  int s, t, p,n;
  double squared_yz,squared_x, squared=0;
  
  for(s=0;s<=Smax;s++)
    {
      n=(int)Ns(s);
      squared_yz=0;
      squared_x=0;
      
      for(p=0;p<n;p++)
	squared_x = squared_x + psi1_x(p,x);
      
      for(t=0;t<=s;t++)
	squared_yz = squared_yz + psi2_y(t,y)*psi3_z(s-t,z);
      
      squared = squared + squared_x*squared_yz;
    } 
  return squared;
}

void plot_distribution()
{
  double i,j; /*i is the variable that will provide the steps in the x direction
                and j the one that will provide the steps in the "r direction". */
  FILE *fp;
  char X='x';
  char R='r';
  char str[]= "Density";
  int dim_x=14;
  int dim_r=7;
  
  fp=fopen("fermion_y_10000.dat","w+");
  
  if(fp==NULL)
    printf("File impossible to open!!!\n"); 
  else
    {
      
      fprintf(fp,"%c\t%c\t%s\n",X,R,str);
      for(i=-dim_x;i<=dim_x;i=i+delta_x)
	for(j=0;j<=dim_r;j=j+delta_r)
	  {
	    fprintf(fp,"%lf\t%lf\t%lf\n",i,j,density(i,j,0.0));
	  }
    }
  
  fclose(fp);
}

void integral(void)
{
  double i,j; /*i is the variable that will provide the steps in the x direction
                and j the one the will provide the steps in the "r direction". */
  
  double fermion_number=0;
  double base_area=delta_r*delta_x; 
  int dim_x=14;
  int dim_r=7;
  
  for(i=-dim_x;i<=dim_x;i=i+delta_x)
    for(j=0;j<=dim_r;j=j+delta_r)
      fermion_number = fermion_number + j*density(i+delta_x/2,j+delta_r/2,0.0)*base_area;           
  
  printf("The number of fermions is %lf.\n",2*3.1415927*fermion_number);
}


To finalize this post I’ll just show a few graphics that were produced:

Posted in 00 General, 03 Programming | 1 Comment

Mathematica code

A long time ago I had to make a program that would simulate a speckle pattern. I ended up doing it in C and in Mathematica.

Now I’ll just post in here my Mathematica code to see how it looks like in wordpress.com style. I’ll be following the guidelines in this page.

Without further ado here is the code:

ClearAll["Global`*"]

dim = 64

grid64 = Table[
RandomReal[NormalDistribution[0, 1]] +
I*RandomReal[NormalDistribution[0, 1]], {i, dim}, {j, dim}];

fourier64 = Fourier[grid64];

(*This part of the code will define the window function. Notice that the \
values of i and j can be changed and this shouldn't have any effect on the \
final result*)

For[i = 1, i <= dim, i++,
For[j = 1, j <= dim, j++,
If[(i > 1 && i < dim) && (j > 1 &&  j < dim),
fourier64[[i, j]] = fourier64[[i, j]], fourier64[[i, j]] = 0]]]

finalfield64 = InverseFourier[fourier64];

gridintensity64 = Table[, {i, dim}, {j, dim}];

(*This part of the code calculates the speckle field intensity in each point \
of the grid.*)

For[i = 1, i <= dim, i++,
For[j = 1, j <= dim, j++,
gridintensity64[[i, j]] = Abs[finalfield64[[i, j]]]^2   ]]

list64 = Table[0, {i, dim*dim}];

(* In this part of the code we will save the values of the various \
intensities at each point of the grid by the following order: Running every \
column for each row as the indices go from 1 to dim! *)

For[i = 1; k = 1, i <= dim, i++,
For[j = 1, j <= dim, j++,
list64[[k]] = gridintensity64[[i, j]]; k = k + 1
]]

Export["Intensity_64.dat", list64]

(*The inverse of average64 should appear as the coefficient in the negative \
exponential that expresses what's the probability that a given the intensity \
excedes a certain value of I*)

average64 = Mean[list64]

(*Now will start the study of the statistical properties of the intensities*)

MinIntensity64 = Min[list64]

MaxIntensity64 = Max[list64]

interval = 100

bin = (MaxIntensity64 - MinIntensity64)/interval

(*HistogramX will be the array that will keep the values of the intervals for \
the intensities. HistogramY will be the array that will keep the relevant \
probability of a given intensity interval*)

HistogramX = Table[0, {i, interval}];

HistogramY = Table[0, {i, interval}];

For[i = 1, i <= interval, i++,
HistogramX[[i]] = MinIntensity64 + (i - 1)*bin]

HistogramY = BinCounts[list64, {MinIntensity64, MaxIntensity64, bin}];

(*Let us normalize the previous results so that we can have probabilities*)

HistogramY = 1.0*HistogramY/(dim*dim);

IntensityHistogram64 = Table[0, {i, 2*interval}];

For[i = 1, i <= interval, i++,
IntensityHistogram64[[2*(i - 1) + 1]] = HistogramX[[i]];
IntensityHistogram64[[2*i]] = HistogramY[[i]] ]

IntensityHistogram64 = Partition[IntensityHistogram64, 2];

graphIntensityHistogram64 =
ListPlot[IntensityHistogram64, PlotLabel -> "Intensity Histogram 64*64"]

Export["Intensity_Histogram_64.dat", IntensityHistogram64]

Export["Intensity_Histogram_64.gif", graphIntensityHistogram64]

(* Calculus of the Probability Density Function of our generated intensity \
values*)

h = bin

AcumulatedIntensities64 = Table[0, {i, interval}];

ExcedeIntensity64 = Table[0, {i, 2*interval}];

For[i = 1, i <= interval, i++,
For[k = i, k <= interval, k++,
AcumulatedIntensities64[[i]] =
AcumulatedIntensities64[[i]] + HistogramY[[k]]  ]]

For[i = 1, i <= interval, i++,
ExcedeIntensity64[[2*(i - 1) + 1]] = HistogramX[[i]];
ExcedeIntensity64[[2*i]] = AcumulatedIntensities64[[i]] ]

ExcedeIntensity64 = Partition[ExcedeIntensity64, 2];

graphExcedeIntensity64=ListPlot[ExcedeIntensity64, PlotLabel ->
"Probability that the intensity exceeds I",PlotRange->{{0,MaxIntensity64},{0,1}}]

Export["Excede_intensity_64.dat", ExcedeIntensity64]

Export["Excede_intensity_64.gif", graphExcedeIntensity64]

grafcontour64 =
ListContourPlot[gridintensity64, PlotLabel -> "Contour Plot 64x64 grid"]

Export["Contour_Plot_64.gif", grafcontour64]

Correlation64 =
ListCorrelate[gridintensity64, gridintensity64, {-1, 1}, 0]/(dim*dim);

Correlation64Plot =
ListContourPlot[Correlation64, PlotLabel -> "Autocorrelation Function"]

Export["Correlation_Plot_64.gif", Correlation64Plot]

(*It looks like the expected autocorrelation but it is much more angulous \
than the real one and also the maximum is much more evident. This is due to \
size of the grid and the spacing we took between points. Nevertheless it \
seems to be in good agreement. *)

Please don’t make fun of my code as this was was written a long time ago and my Mathematica skills weren’t that good back then (they still aren’t but let’s just ignore that for the time being).

And in case you want to see the graphs I managed to produce here they are:

Not much I know but it is a prelude for things to come…

Posted in 00 General, 03 Programming | Tagged | 3 Comments

First post

In this page I’ll try to make openly available all the juicy details that don’t get to get published but are a kind of work process map.

Expect a kind of diary: day thoughts, methodology, partial results, plots, codes and whatever.

I just hope this blog will become a really interactive space, thus reader’s comments are greatly expected.

Posted in 00 General, 01 Announcements