Why You Do Not Usually Need to Know about Internals
Most of the documentation provided for
Mathematica is concerned with explaining
what Mathematica does, not
how it does it. But the purpose of this is to say at least a little about how
Mathematica does what it does. "
Some Notes on Internal Implementation" gives more details.
You should realize at the outset that while knowing about the internals of
Mathematica may be of intellectual interest, it is usually much less important in practice than you might at first suppose.
Indeed, one of the main points of
Mathematica is that it provides an environment where you can perform mathematical and other operations without having to think in detail about how these operations are actually carried out inside your computer.
Thus, for example, if you want to factor the polynomial
x15-1, you can do this just by giving
Mathematica the command
Factor[x^15-1]; you do not have to know the fairly complicated details of how such a factorization is actually carried out by the internal code of
Mathematica.
Indeed, in almost all practical uses of
Mathematica, issues about how
Mathematica works inside turn out to be largely irrelevant. For most purposes it suffices to view
Mathematica simply as an abstract system which performs certain specified mathematical and other operations.
You might think that knowing how
Mathematica works inside would be necessary in determining what answers it will give. But this is only very rarely the case. For the vast majority of the computations that
Mathematica does are completely specified by the definitions of mathematical or other operations.
Thus, for example,
3^40 will always be
12157665459056928801, regardless of how
Mathematica internally computes this result.
There are some situations, however, where several different answers are all equally consistent with the formal mathematical definitions. Thus, for example, in computing symbolic integrals, there are often several different expressions which all yield the same derivative. Which of these expressions is actually generated by
Integrate can then depend on how
Integrate works inside.
This is an equivalent expression that might have been generated if Integrate worked differently inside.
Out[2]= |  |
|
In numerical computations, a similar phenomenon occurs. Thus, for example,
FindRoot gives you a root of a function. But if there are several roots, which root is actually returned depends on the details of how
FindRoot works inside.
This finds a particular root of cos (x)+sin (x).
Out[3]= |  |
|
With a different starting point, a different root is found. Which root is found with each starting point depends in detail on the internal algorithm used.
Out[4]= |  |
|
The dependence on the details of internal algorithms can be more significant if you push approximate numerical computations to the limits of their validity.
Thus, for example, if you give
NIntegrate a pathological integrand, whether it yields a meaningful answer or not can depend on the details of the internal algorithm that it uses.
NIntegrate knows that this result is unreliable, and can depend on the details of the internal algorithm, so it prints warning messages.
Out[5]= |  |
|
Traditional numerical computation systems have tended to follow the idea that all computations should yield results that at least nominally have the same precision. A consequence of this idea is that it is not sufficient just to look at a result to know whether it is accurate; you typically also have to analyze the internal algorithm by which the result was found. This fact has tended to make people believe that it is always important to know internal algorithms for numerical computations.
But with the approach that
Mathematica takes, this is rarely the case. For
Mathematica can usually use its arbitrary-precision numerical computation capabilities to give results where every digit that is generated follows the exact mathematical specification of the operation being performed.
Even though this is an approximate numerical computation, every digit is determined by the mathematical definition for  .
Out[6]= |  |
|
Once again, every digit here is determined by the mathematical definition for sin (x).
Out[7]= |  |
|
If you use machine-precision numbers, Mathematica cannot give a reliable result, and the answer depends on the details of the internal algorithm used.
Out[8]= |  |
|
It is a general characteristic that whenever the results you get can be affected by the details of internal algorithms, you should not depend on these results. For if nothing else, different versions of
Mathematica may exhibit differences in these results, either because the algorithms operate slightly differently on different computer systems, or because fundamentally different algorithms are used in versions released at different times.
This is the result for sin (1050) on one type of computer.
Out[9]= |  |
|
Here is the same calculation on another type of computer.
Out[10]= |  |
|
And here is the result obtained in Mathematica Version 1.
Out[11]= |  |
|
Particularly in more advanced applications of
Mathematica, it may sometimes seem worthwhile to try to analyze internal algorithms in order to predict which way of doing a given computation will be the most efficient. And there are indeed occasionally major improvements that you will be able to make in specific computations as a result of such analyses.
But most often the analyses will not be worthwhile. For the internals of
Mathematica are quite complicated, and even given a basic description of the algorithm used for a particular purpose, it is usually extremely difficult to reach a reliable conclusion about how the detailed implementation of this algorithm will actually behave in particular circumstances.
A typical problem is that
Mathematica has many internal optimizations, and the efficiency of a computation can be greatly affected by whether the details of the computation do or do not allow a given internal optimization to be used.