I would strongly discourage to do that globally (e.g. by setting $MaxPrecision
) because this will -- ironically -- enforce calculations in arbitrary extended precision mode. The latter is less performant because it is implemented in software.
Since hardware supported single precision floating point arithmetic (involving 32 bit floats) is supported only in some instances (e.g. for Image
s and some CUDA-related functions), the best you can do is to enforce computations to be performed in machine precision (double precision floating point arithmetic with 64 bit floats). In general, this is the way to be as close to hardware implementation (and thus as performant) as possible. Most importantly, this allows you to use vectorization for various linear algebra tasks. Modern hardware and the low level libraries are really optimized for that.
The simplest ways to use hardware supported double precision calculation is by (i) applying N
as early as possible or by (ii) having any number in double precision appearing in code as a number of least precision, e.g., the number 1.
in 1. Pi
.
PS.: Evaluating
x = N[Pi];
FullForm[x]
3.141592653589793`
will reveal to you that computations will be performed with (almost) 16 digits. However, per default, only 6 digits are shown in the notebook -- mainly in order to prevent spamming the output cells.
PPS.: You can enforce iterative algorithms to terminate earlier by reducing the accuracy goals. As for Eigensystem
s of large positive definite matrices, you might be interested in the method "Arnoldi"
with its suboptions. The accuracy of the results is set with the suboption Tolerance
. Here a short example; I would suggest to read the method section on the documentation page of Eigensystems
for information on further fine-tuning.
n = 2000;
k = 10;
A = RandomReal[{-1, 1}, {n, n}];
A = Transpose[A].A;
{Λ0, U0} = Eigensystem[A, k]; // RepeatedTiming // First
{Λ1, U1} = Eigensystem[A, k, Method -> {"Arnoldi", Tolerance -> 10^(-12)}]; // RepeatedTiming // First
{Λ2, U2} = Eigensystem[A, k, Method -> {"Arnoldi", Tolerance -> 10^(-4)}]; // RepeatedTiming // First
{Max[Abs[Λ1 - Λ0]], Max[MapThread[{x, y} \[Function] Min[Norm[x - y], Norm[x + y]], {U1, U0}]]}
{Max[Abs[Λ2 - Λ0]], Max[MapThread[{x, y} \[Function] Min[Norm[x - y], Norm[x + y]], {U2, U0}]]}
0.795
0.172
0.107
{1.45519*10^-11, 7.47694*10^-12}
{0.0000251159, 0.000531061}
NumericalMath`FixedPrecisionEvaluate
might be of interest. $\endgroup$