1
$\begingroup$

I would like to know if there is a way to make Mathematica to use at most certain digit number. For example, Suppose I want to calculate 2*Pi.

x=N[Pi]
y=2*x

Which will give you,

3.14159
6.28319

Here, Mathematica used 6 digits numbers to do the calculations. What I want to do is to limit Mathematica to use at most 3 digits numbers for the calculation. Also, I would like to apply this rule "globally" (not sure if I understand this term correctly, but what I want to say is to apply this rule to my entire code).

I have looked at a documentation about $MaxPrecision, but I am not sure how to apply it in global.

Eventually, I am going to use this command to solve eigenvalues problem of large matrices. With the arbitrary precision, it takes too long for Mathematica to handle it, so I am trying to optimize it as much as possible.

Thank you in advance!

$\endgroup$
10
$\begingroup$

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 Images 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 Eigensystems 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}

$\endgroup$
  • $\begingroup$ Thank you very much for your help! I think I need to study more about Arnoldi method to optimize my code. Thanks again and have a good one. $\endgroup$ – Ricky the Confused Jul 20 '18 at 3:07
  • $\begingroup$ You're welcome! $\endgroup$ – Henrik Schumacher Jul 20 '18 at 5:01

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.