0
$\begingroup$

I have a the following script, which essentially minimizes the function $h$ with respect to all the variables $a[\alpha][s][j][n]$, where $\alpha,s\in\lbrace0,1\rbrace$, $j \in \lbrace ,\ldots,\text{nMol}-1\rbrace$ and $n \in \lbrace ,\ldots,\text{nEl}-1\rbrace$.

The minimization is done with additional constraints for the variables $a$.

j1 = 1;
j2 = 1;
Δ = 4;
u = 3;
nMol = 2;
nEl = 2;

h = Sum[-2*j2*Re[Conjugate[a[0][s][j][n]] * a[1][s][j][n]] - 
     2*j1*Re[Conjugate[a[0][s][j + 1][n]]*a[1][s][j][n] ] + 
     0.5*(1 + (2*s - 1)*(-1)^j)*Δ*
      Sum[Abs[a[α][s][j][n] ]^2, {α, 0, 1}], {s, 0, 
     1}, {j, 0, nMol - 2}, {n, 0, nEl - 1}] + 
   u*Sum[(Sum[Abs[a[α][0][j][n]]^2, {n, 0, nEl - 1}])*(Sum[
        Abs[a[α][1][j][n]]^2, {n, 0, nEl - 1}]), {j, 0, 
      nMol - 1}, {α, 0, 1}] + 
   Sum[-2*j2*
      Re[Conjugate[a[0][s][nMol - 1][n]] * a[1][s][nMol - 1][n]] - 
     2*j1*Re[Conjugate[a[0][s][0][n]]*a[1][s][nMol - 1][n] ] + 
     0.5*(1 + (2*s - 1)*(-1)^(nMol - 1))*Δ*
      Sum[Abs[a[α][s][nMol - 1][n] ]^2, {α, 0, 1}], {s, 
     0, 1}, {n, 0, nEl - 1}];

con[n_, m_] := 
 KroneckerDelta[n, m] == 
  Sum[Conjugate[a[α][s][j][n]]*a[α][s][j][m], {α,
     0, 1}, {s, 0, 1}, {j, 0, nMol - 1}]
allCon = Table[con[i, j], {i, 0, nEl - 1}, {j, 0, nEl - 1}];
vars = Table[
    a[α][s][j][n], {α, 0, 1}, {s, 0, 1}, {j, 0, 
     nMol - 1}, {n, 0, nEl - 1}] // Flatten;

res = NMinimize[{h, allCon}, vars]

The number of variables $a[\alpha][s][j][n]$ goes as $2\times 2 \times \text{nMol} \times \text{nEl}$, so that for $\text{nMol}=\text{nEl}=20$ one has to deal with $1600$ variables. Of course, this takes long time!

I now want to make this faster. I don't know how much faster this can get, because I lack the experience with mathematica.

I read that one can use the Compile function to gain some speedup. I tried to implement a compiled version of the function $h$ but I failed. Especially, it seems like one has to enter all variable names and their type into the Compile function - which is a rather inconvenient thing to do for 1600 variables.

So my question is basically: How can I make the constrained minimization faster? How do I use the compile function in this context?

I use mathematica 10, if that is a necessary information.

What I tried:

ceqn = Compile[Evaluate[{#, _Complex} & /@ vars], Evaluate[h], 
   "RuntimeOptions" -> {"EvaluateSymbolically" -> False}];

NMinimize[{ceqn @@ vars, allCon}, vars]

This, however, is slower than the uncompiled version. What can I do to speed things up?

$\endgroup$
  • $\begingroup$ Try ceqn @@ vars instead of ceqn. The arguments must be inserted. After that you may want to try reformulating everything in terms of array arithmetic, since your a seems to be a 4-dimensional array. $\endgroup$ – Szabolcs Oct 7 '16 at 9:15
  • $\begingroup$ Thank you, ceqn @@ vars works! BUT: The compiled function is slower than the uncompiled :/ How do I fix this and how do I rewrite this using arrays? $\endgroup$ – Merlin1896 Oct 7 '16 at 9:23
  • $\begingroup$ You have a lot of code here and I don't have time to go through all of it and check if array operations would work. It looks like you are doing elementwise operations on arrays and summing along one array index. We can sum along a single array index using the second argument of Total. Element-wise arithmetic works on arrays as normal. The missing piece is getting NMinimize to pass an array into your function. Do this with something like NMinimize[f[x], x \[Element] FullRegion[4]] e.g. for a 4 dimensional array $\endgroup$ – Szabolcs Oct 7 '16 at 10:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.