1
$\begingroup$

I need to speed up this code

X = PauliMatrix[1];
Y = PauliMatrix[2];
Z = PauliMatrix[3];
t = π/2;
n = 4;
psi = (1/Sqrt[2^n])*{{1}, {1}, {1}, {1}, {1}, {1}, {1}, {-1}, {1}, {1}, {1},{-1}, {1}, {-1}, {-1}, {1}};  

For[θ = π/180, θ < π, θ += π/180,  
   For[ϕ = -π + π/180, ϕ <= π, ϕ += π/180,  
      CT = CoordinateTransformData["Spherical" -> "Cartesian","Mapping", {1, θ, ϕ}];  
      x = CT[[1]]; y = CT[[2]]; z = CT[[3]];  
      U = Cos[t]*IdentityMatrix[2] + I*Sin[t]*(x*X + y*Y + z*Z);
      Uall = KroneckerProduct[U, U, U, U];
      If[Abs[Total[(Transpose[psi].(Uall.psi))[[1]]]] >= .999,Print[N[U] // MatrixForm]]
   ]
]

I just started using Mathematica last week. The code works the way I want it to, but it takes about 20 minutes to run. I just need help speeding up this code.

Edit: I am trying to loop over points on the unit sphere as spherical coordinates. Then transform those points into Cartesian coordinates, then use those to create 2x2 matrices. Then do the kronecker product of that matrix n times. Lastly the If statement is to test if how far off Uall*psi is to equaling psi.

$\endgroup$

closed as off-topic by Sascha, corey979, Feyre, MarcoB, Yves Klett Dec 29 '16 at 7:23

  • The question does not concern the technical computing software Mathematica by Wolfram Research. Please see the help center to find out about the topics that can be asked here.
If this question can be reworded to fit the rules in the help center, please edit the question.

  • $\begingroup$ In the code snippet here, psi is undefined. $\endgroup$ – Jason B. Jul 13 '15 at 15:10
  • 1
    $\begingroup$ It might be easier to come up with something neater if you'll explain what you're trying to do here with your code. $\endgroup$ – J. M. will be back soon Jul 13 '15 at 15:25
  • 4
    $\begingroup$ I'm voting to close this question as off-topic because it is to localized and is not likely to help future visitors. $\endgroup$ – Sascha Dec 28 '16 at 13:09
2
$\begingroup$

Without knowing how psi is defined, I can't fully answer, but a few points.

Try to avoid For loops and use Do instead. So instead of writing

For[θ = π/180, θ < π, θ += π/180, 
For[ϕ = -π + π/180, ϕ <= π, ϕ += π/180,
  (* some code here *)
   ]
]

write

Do[
  (* some code here *)
  , {θ, π/180, π, π/180}
  , {ϕ, -π + π/180, π, π/180}]

Next, there's no reason to populate CT, x, U, and Uall at every iteration of the loop. Without defining any of the variables, you can enter the following code before the loop begins:

CT = CoordinateTransformData["Spherical" -> "Cartesian", 
  "Mapping", {1, θ, ϕ}];
x = CT[[1]]; y = CT[[2]]; z = CT[[3]];
U = Cos[t]*IdentityMatrix[2] + I*Sin[t]*(x*X + y*Y + z*Z);
Uall = KroneckerProduct[U, U, U, U];

This stores Uall as a symbolic matrix. Then you can build up the inner product as a compiled function to do everything much quicker.

This should be faster, hopefully it does what you need:

X = PauliMatrix[1];
Y = PauliMatrix[2];
Z = PauliMatrix[3];
t = π/2;
n = 4;
psi = Flatten[(1/
  Sqrt[2.0^
    n])*{{1}, {1}, {1}, {1}, {1}, {1}, {1}, {-1}, {1}, {1}, {1}, \
{-1}, {1}, {-1}, {-1}, {1}}];
CT = CoordinateTransformData["Spherical" -> "Cartesian", 
  "Mapping", {1, θ, ϕ}];
x = CT[[1]]; y = CT[[2]]; z = CT[[3]];
U = Cos[t]*IdentityMatrix[2] + I*Sin[t]*(x*X + y*Y + z*Z);
Uall = KroneckerProduct[U, U, U, U];
innerproduct = Compile[{{θ, _Real}, {ϕ, _Real}},
  Evaluate[Abs[(psi.(Uall.psi))]]
  ];
Do[
If[innerproduct[θ, ϕ] >= .999, 
  Print[N[U] // MatrixForm]]
, {θ, π/180, π, π/
  180.0}, {ϕ, -π + π/180, π, π/180.0}]
$\endgroup$
  • $\begingroup$ this works a lot faster, but the output is not the same as my original code $\endgroup$ – Onepiece79 Jul 13 '15 at 15:47
  • $\begingroup$ I might be missing your point, but your first suggestion intrigued me: on what grounds should replacing For with Do speed up the code? $\endgroup$ – MarcoB Jul 13 '15 at 15:49
  • $\begingroup$ Never mind the outputs are the same $\endgroup$ – Onepiece79 Jul 13 '15 at 16:06
  • $\begingroup$ @MarcoB It's not that it speeds up the code, just makes it more Mathematica and less C or Fortran. Also, easier to read $\endgroup$ – Jason B. Jul 13 '15 at 17:05
  • $\begingroup$ I think Table[] would be more appropriate here than Do[], actually. $\endgroup$ – J. M. will be back soon Jul 13 '15 at 18:10

Not the answer you're looking for? Browse other questions tagged or ask your own question.