# linear algebra – Contradictions between PositiveDefiniteQ, Det and Inverse in Mathematica

A few words before the work example. Below we find 2 functions that should theoretically transform any matrix into its closest Symmetric Positive Definite (SPD) matrix: `positivizeMatrix`, and `positivizeMatrix2`. The difference between the two is that the second has the additional condition `Det[res]<= 0`. Any SPD is also invertible.

``````In: = positivizeMatrix[X_] : = Module[{res},
res = 0.5*(X + Transpose[X])

(* This method only works for Hermitian matrices *)

Yes[Donot[PositiveDefiniteMatrixQ[Not[PositiveDefiniteMatrixQ[Nepas[PositiveDefiniteMatrixQ[Not[PositiveDefiniteMatrixQ[res]],

auxsystDP = Eigensystem[res];

duDP = DiagonalMatrix[auxsystDP[]];

wDP = ReplacePart[duDP, {i_, i_} /; duDP[[i, i]] <= 0 :> 0];

res = transpose[auxsystDP[]].wDP.auxsystDP[];
(* Electronic system of eigenvectors online and in color *)

lenRes = Length[res];

powerDP = 20;

While[Donot[PositiveDefiniteMatrixQ[Not[PositiveDefiniteMatrixQ[Nepas[PositiveDefiniteMatrixQ[Not[PositiveDefiniteMatrixQ[res]],

res = res + IdentityMatrix[lenRes]* \$ MachineEpsilon * 2 ^ (- powerDP);
(* Adding the smallest nugget possible.
It may not be a good idea. He still creates machines
Precision problems ... See below. *)

powerDP--;
]; ,
res
];

(* Theoretically, the next block of code should not be needed,
but because of the precision of the digital machine, we sometimes need it *)

Yes[Donot[SymmetricMatrixQ[Not[SymmetricMatrixQ[Nepas[SymmetricMatrixQ[Not[SymmetricMatrixQ[res]],
res = 0.5 * (res + Transpose[res])
];

res
];

In: = positivizeMatrix2[X_] : = Module[{res},
res = 0.5*(X + Transpose[X])
(* This method only works for Hermitian matrices *)

Yes[Donot[PositiveDefiniteMatrixQ[Not[PositiveDefiniteMatrixQ[Nepas[PositiveDefiniteMatrixQ[Not[PositiveDefiniteMatrixQ[res]]|| Det[res] <= 0,

auxsystDP = Eigensystem[res];

duDP = DiagonalMatrix[auxsystDP[]];

wDP = ReplacePart[duDP, {i_, i_} /; duDP[[i, i]] <= 0 :> 0];

res = transpose[auxsystDP[]].wDP.auxsystDP[];
(* Electronic system of eigenvectors online and in color *)

lenRes = Length[res];

powerDP = 20;

While[Donot[PositiveDefiniteMatrixQ[Not[PositiveDefiniteMatrixQ[Nepas[PositiveDefiniteMatrixQ[Not[PositiveDefiniteMatrixQ[res]]|| Det[res] <= 0,

res = res + IdentityMatrix[lenRes]* \$ MachineEpsilon * 2 ^ (- powerDP);
(* Adding the smallest nugget possible.
It may not be a good idea. He still creates machines
Precision problems ... See below. *)

powerDP--;
]; ,
res
];

(* Theoretically, the next block of code should not be needed,
but because of the precision of the digital machine, we sometimes need it *)

Yes[Donot[SymmetricMatrixQ[Not[SymmetricMatrixQ[Nepas[SymmetricMatrixQ[Not[SymmetricMatrixQ[res]],
res = 0.5 * (res + Transpose[res])
];

res
];
``````

The examples use 3 by 3 matrices where each component is between 0 and 50. I have assumed that this would not be at the limit of the accuracy of the machine.
Now, for the results:

``````In: = SeedRandom;
list = RandomReal[{0, 50}, {10000, 3, 3}];

In: = res1 = ParallelMap[positivizeMatrix[#] &, listing];
res2 = ParallelMap[positivizeMatrix2[#] &, listing];

In: = ParallelMap[PositiveDefiniteMatrixQ, res1] // Total

Outside= 10000 true

In: = ParallelMap[Det[#] > 0 &, res1]// Total

Outside= 1749 False + 8251 True

In: = ParallelMap[Det[#] > 0 &, res2]// Total

Outside= 10000 true
``````

This means that I have to add the additional condition of Det[res]<= 0.

Now the problem with Inverse, with matrices that have positive Det:

``````In: = ParallelMap[Quiet[Inverse[#]]&, res2]// Total;

During the evaluation of In: = Inverse :: sing: Matrix {{39.1928,33.6862,14.4105}, {33.6862, <<18>>, <<18>>}, {14.4105,32.7791,25.9402}} is in the singular.

During the evaluation of In: = Inverse :: sing: Matrix {{21.7121,15.7919, 28.2016}, {15.7919, <<18>>, <<18>>}, {28.2016,27.5316,40.2261}} is in the singular.

During the evaluation of In: = Inverse :: sing: Matrix {{29.7926,31.3398.32.2753}, {31.3398, <<18>>, <<18>>}, {32.2753,33.9515,34.9649}} is in the singular.

During the evaluation of In: = General :: stop: Subsequent outputs of Inverse :: sing will be removed during this calculation.
``````

My point is this: what criteria can I use in my positivizeMatrix function to be sure that, whatever the matrix obtained, it can be used for Inverse and for any other built-in Mathematica function that should theoretically work with matrices SPD?

P.S: Even if the components remain between 0 and 10, the problem persists. I have just tried. The results are similar, I will not change the text above. However, I wonder if this is really a problem of precision of the machine …

Posted on