I've been employing this pair of statements
z = Partition[Y1.Transpose[Y1], {2, 2}];
If[
PositiveDefiniteMatrixQ[
ArrayFlatten @ {{z[[1, 1]], z[[2, 1]]}, {z[[1, 2]], z[[2, 2]]}}]
== True,
r = r + 1];
in a larger program, where Y1
is a $4 \times 4$ matrix.
I'm testing the positive-definiteness of the "partial transpose" of z
, in line with the quantum-information-theoretic Peres-Horodecki test for separability.
Can I eliminate the use of the variable z
?
Can this task be accomplished in one command?
Can Flatten
be employed for such a purpose?
Presumably, such a compression would lead to somewhat faster execution.
In light of the very detailed answer of Henrik Schumacher, I'm now including the larger program in which the pair of statements was embedded. He remarked: "Notice that a main part of the speed up comes from processing many matrices at once." I'd don't know whether such "processing" is possible/feasible in the framework of the larger program, since the generation of the matrices Y1 involves a number of other matrices, as well as a Check for an Orthogonalize error (for which, if it occurs I redo the calculation with added precision).
sp2 = x /. Solve[x^(37) == x + 1, x][[1]]; G = Array[1, 36]; Do[
G[[i]] = N[i95/sp2^i], {i, 1, 36}]; rB = 0; hw = TimeUsed[]; Do[
P = InverseCDF[NormalDistribution[0, 1], FractionalPart[G]];
Label[wuh];
Y1 = Check[(Orthogonalize[ArrayReshape[Take[P, {1, 16}], {4, 4}]] +
IdentityMatrix[4]).(ArrayReshape[Take[P, {17, 36}], {4, 5}]),
err; G1 = Array[1, 36]; Do[G1[[i]] = N[i95/sp2^i, 32], {i, 1, 36}];
P = InverseCDF[NormalDistribution[0, 1], FractionalPart[G1]];
Goto[wuh]]; z = Partition[Y1.Transpose[Y1], {2, 2}];
If[PositiveDefiniteMatrixQ[
ArrayFlatten@{{z[[1, 1]], z[[2, 1]]}, {z[[1, 2]], z[[2, 2]]}}] ==
True, rB = rB + 1];
If[Mod[i95, 1000000] == 0,
Print[{TimeUsed[] - hw, i95, rB, rB/i95, N[rB/i95, 20]}];
hw = TimeUsed[]], {i95, 1, 100}]