I have several matrices (2D matrices) sizes can go up to 30000*30000 and I need to do matrix multiplications. However, even if I use 16 Digits the calculation take extremely long compare to MATLAB. I am not expecting Mathematica to be faster but not 100 times slower.
So for MATLAB I create
A=rand(300,300);
tic
A*A;
toc
and it takes only 0.004 seconds with format long ( double precision)
taking 13 seconds and there is no time difference if I increase the WorkingPrecision to 30. But more interestingly if I put the working precision to 6 digits (single precision) time consumed is same. An example.
The difference between g and f far being zero. I don’t understand why I get different results in here.
I can’t imagine doing such a calculation with really large matrices. I am certain that something is not right in my Mathematica approach. What is the way to speed up matrix multiplication in Mathematica.
I think that WolkingPrecision → 16 means that 16 digits are exact, i.e. Mma is working with more digits than 16 (more than two words) to guarantee specified exactitude. When working with double precision, only double words are used. It’s only a supposition, not a certainty…
Apropos,
In[4]:= a = RandomReal[{-10., 10.}, {10000, 10000}];
a.a; // AbsoluteTiming
$Version
Out[5]= {91.8452, Null}
Out[6]= "10.4.1 for Microsoft Windows (64-bit) (April 11, 2016)"
I think being exact is not an easy concept. My problem, I want to work with double precision (at least) and when I am working with double precision I expect a similar performance from Mathematica that of MATLAB for simple (highly parallelizable) calculation like matrix multiplication.
a = RandomReal[{-10, 10}, {10000, 10000}];
AbsoluteTiming[f = a.a;]
this takes around 17 seconds. It is 6 digits, same as your example. With MATLAB double precision calculation takes 17 sec.
10.3.1 for Mac OS X x86 (64-bit) (December 9, 2015)
a = RandomReal[{-10, 10}, {300, 300}, WorkingPrecision -> n];
for whatever n, the numbers that are generated are so-called arbitrary precision numbers. When you don’t use a WorkingPrecision option:
a = RandomReal[{-10, 10}, {300, 300}];
it will create machineprecision numbers:
MachineNumberQ[a[[1,1]]]
Evaluates to True. While in the former case (independent of n) it is False.
Machine precision numbers do not track the precisions of numbers, while arbitrary precision does. This makes a HUGE difference! On most modern machine a MachinePrecision number will be a ‘double precision floating point’:
$MachinePrecision
15.9546 (53 Log10[2])
By default this will be used. Note that Mathematica only SHOWS 6 digits by default on screen! i.e. RandomReal[] gives 0.531239 (but in reality it has all 53 bits set randomly)…
Well, there is nothing wrong with machine precision but also I know several problems more is required. Also one migh ask, why Wolfram developed extended precision ? I am trying find the best use of the tool that I have.
Thank you for the reply. I was getting similar times for the example that you also showed but I did not know that Mathematica was only showing 6 digits instead of machine precision. How can I make displaying full digits?
From your response I can see that it does not matter 6 for 60 digits with WorkingPrecision there is a cost of keeping track and that is quite huge.
Arbitrary precision is sometimes useful for certain applications. In most cases however double precision is more than enough for most applications. The main problem is that it can’t use the very efficient multiplication algorithms in the CPU, and have to resort to different algorithm with overhead. The WorkingPrecision does matter in performance:
a = RandomReal[{-10, 10}, {50, 50}, WorkingPrecision -> 6];
AbsoluteTiming[a.a;]
a = RandomReal[{-10, 10}, {50, 50}, WorkingPrecision -> 60];
AbsoluteTiming[a.a;]
a = RandomReal[{-10, 10}, {50, 50}, WorkingPrecision -> 600];
AbsoluteTiming[a.a;]
a = RandomReal[{-10, 10}, {50, 50}, WorkingPrecision -> 6000];
AbsoluteTiming[a.a;]
But only for really large amounts of digits…
You can use e.g.
NumberForm[%, 20]
to see all the digits. Or change the default in the preferences:
Basically by default it uses MachinePrecision, good for 16 digits of precision (on most modern computers). If you want more, we can, using what Mathematica calls ‘arbitrary precision’. This however prohibits very efficient CPU function calls that work very nicely with doubles…