# Count and NMinimize don't seem to work together

Initially I write down a 2x2 unitary (Uni) , make a tensor product 4 times (LocalUni) and apply it to an initial numerical matrix Rho, to obtain RhoLU, that depends on 12 parameters.

This is my code:

Uni[phi_, psi_,theta_] := {{E^(I*phi)*Cos[theta], E^(I*psi)*Sin[theta]}, {-E^(-I*psi)*Sin[theta], E^(-I*phi)*Cos[theta]}};
LocalUni[a1_, a2_, a3_, a4_, b1_, b2_, b3_, b4_, c1_, c2_, c3_, c4_] := KroneckerProduct[Uni[a1, b1, c1], KroneckerProduct[Uni[a2, b2, c2],  KroneckerProduct[Uni[a3, b3, c3], Uni[a4, b4, c4]]]]
RhoLU[a1_, a2_, a3_, a4_, b1_, b2_, b3_, b4_, c1_, c2_, c3_, c4_] := LocalUni[a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3,  c4].Rho.ConjugateTranspose[LocalUni[a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4]]


where Rho is just a large matrix with complex entries.

I look at the number of elements that are above the 0.01 threshold in my initial Rho matrix:

Count[Re[Flatten[Rho]], u_ /; Abs[u] > 0.01] + Count[Im[Flatten[Rho]], u_ /; Abs[u] > 0.01]


and I get 239.

Now what I want is to apply NMinimize to this last line , depending on the a1, a2... parameters, such that the total number of elements of the RhoLU matrix (so the Rho matrix after I apply the local unitaries) is as small as possible. What I tried is:

ELM = Count[Re[Flatten[RhoLU[a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4]]], u_ /; Abs[u] > 0.01] + Count[Im[Flatten[RhoLU[a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4]]],u_ /; Abs[u] > 0.01] ;
LeastElements = NMinimize[ELM,{a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4}]


The result is always

{0., a1->0, a2->0 ...}


I find this weird because if you write LocalUni in matrix form for all the parameters set to zero, you get an identity matrix (as you must), thus even if it does nothing and sets everything equal to zero, I should get at least 239, which is the number I got for my initial Rho, without any transformations.

## 1 Answer

Note what happens when you evaluate Abs[u] > 0.01, for a u with no value of its own:

In[1]:= ClearAll[u]; Abs[u] > 0.01
Out[1]= Abs[u] > 0.01


Nothing! Mathematica can't figure out a value for Abs[u] without knowing anything about u, so it leaves the expression unchanged. This means that a conditioned pattern like u_ /; Abs[u] > 0.01 isn't going to match a symbolic quantity if it can't figure out what its absolute value is, because a pattern with a Condition only matches if the expression actually evaluates to True. Fortunately, Mathematica provides a predicate, NumericQ, that tells you exactly what expressions have numeric values that you do things like take the absolute value of. You just need to make sure that you have a function doing the counting that doesn't get evaluated until its arguments have numerical values, like so:

ELM[args___?NumericQ] /; Length[{args}] == 12 :=
Count[ReIm[Flatten[RhoLU[args]]], u_ /; Abs[u] > 0.01, {2}];


Here, I've used the new ReIm function from Mathematica 10.1, and a level specification for Count; I'm also just forwarding the args as a sequence without naming all of them. These sorts of Mathematica idioms can greatly simplify your code.

Once you have ELM, you have to make sure it gets the right arguments from NMinimize. With a random choice of Rho, I get:

RandomSeed[137];
Rho = RandomComplex[{}, {16, 16}];
NMinimize[
ELM[a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4],
{a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4}]

{486., {a1 -> 0.550963, a2 -> 0.0363448, a3 -> 1.54076,
a4 -> -0.940581, b1 -> 0.575881, b2 -> 0.581068, b3 -> -0.262193,
b4 -> -0.913848, c1 -> -0.632942, c2 -> -0.822271, c3 -> -0.222135,
c4 -> -0.686457}}

• It works now in the sense that it does evaluate NMinimize. But it gives: NMinimize::nnum: The function value ELM is not a number at {a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4} = {0.532215,0.278858,0.773638,0.985709,-0.221322,0.385068,0.948722,0.429215,0.562274,0.917671,-0.242253,0.257385}. >> General::stop: Further output of NMinimize::nnum will be suppressed during this calculation. >> Nov 20 '15 at 21:18
• Well, does ELM evaluate to a number when you apply it to those values? (It might help if you'd put up a sample value for Rho somewhere....) Nov 20 '15 at 22:51
• ELM does evaluate to a number and Rho is just a matrix with complex entries, nothing special about it. Nov 21 '15 at 14:15
• Now I see my error, I wasn't giving ELM the proper arguments in NMinimize. Now it all works as needed. Thank you Pillsy. Nov 21 '15 at 15:00