Xnum - a high precision math package for Scilab
Xnum is a arbitrary precision mathematical package for the Scilab mathematical software package. It allows mathematical calculations to be performed up to a maximum precision of 200 digits.INDEX
Xnum manual, pdf
Xnum download page
Xnum online manual
Xnum for Scilab (zip file)
You might notice that at the top of the download page there is a warning that the Xnum package does not work on systems later than Windows XP. This might be true for those who download the windows packages, but the Xnum add on when embedded within Scilab runs on any system running Scilab, and that includes Windows Vista and Windows 7.
At the time I am writing this, the Xnum package will only work with the 32 bit version of Scilab (not the 64 bit version). For this reason I am running 32 bit Scilab even though I have a 64 bit computer.
The Xnum add on is a DLL (a small code package) that must be loaded into Scilab every time you start up Scilab. From the console you must first change to the root (bottom) directory of the unzipped Xnum files. From the File menu choose 'Change Current Directory'.
From the Applications menu choose 'Editor' to start up the Scilab editor. In the Editor select 'Open' to open the file 'xnum_loader.sce'. Using the 'Execute' menu in the Editor, select 'Load into Scilab' to run the executable file.
I avoid doing the steps I just described by using absolute file paths (so I don't have to change the directory). I have a small file with the following two lines of Scilab code:
I then choose 'Execute file without echo' from the menu and this auto loads Xnum into Scilab.
If the Xnum dll has loaded successfully the Consol will report that the DLL code has been loaded and successfully linked to the Scilab program. Xnum is now ready to be used in calculations.
Xnum operates on all numbers as strings (and not floating point numbers). X= 231.09 is a floating point number. If we wrap the input in quotes, this denotes a string variable in Scilab. Therefore the Xnum version of this variable becomes X= '231.09'. If we want to convert the result of an Xnum calculation back into a floating point number we use the function 'strdbl' as in Y = strdbl(X), where Y is a floating point number and X is a string. We can also convert a floating point number into a string representation using the function dblstr, Y = dblstr(X), where X is floating point number and Y is a string representation of this number. If double precision floating numbers are included in an Xnum calculation, the number is automatically converted into a string before the calculation begins. Therefore if calculations are to be performed repeatedly within a loop structure it makes sense to convert all floating point numbers to strings to prevent the possible costly waste of time involved in repeatedly converting floating point numbers into strings.
Given that Xnum only works with string variables the normal mathematical operators are not used in Xnum calculations, and in their place one of dozens of specialized Xnum functions are employed. There is a list of these functions in the Xnum manual.
Xnum functions can be Scilab functions renamed with a preceding 'x' (examples include xsqrt, xsin, xcos, etc). Xnum also replaces + - * / with special xnum functions (xadd, xsub, xmul, xdiv, etc).
Therefore x = 1 + 2 when translated to Xnum code, becomes x = xadd(1, 2, 200). The final number '200' is the arbitrary precision of the calculation - here we are saying that we want the results of the addition of 1 and 2 up to a precision of 200 digits (which in this case would be excessive since the answer is 3, which is one digit). If no value is input in the optional third field for the precision of the function, then the function uses the default value, which seems to be approximately equivalent to a quadruple precision floating point value.
Consider the following example. The code used to calculate the ratio for Gravitational Time Dilation, using floating point numbers, is…
// gravitational time dilation ratio
t0 = sqrt(1 - ((2 * G * M) / (R * c^2)));
The Xnum code for the same calculation is as follows:
t0 = xsqrt( xsub(1, xdiv(xmul(xmul(2, G, 200), M, 200), xmul(R, xpow(c, 2, 200), 200), 200), 200), 200);
It might help to clarify the code a little if we eliminate the optional precision variable (200), in which case the Xnum code appears as follows:
t0 = xsqrt( xsub(1, xdiv(xmul(xmul(2, G), M), xmul(R, xpow(c, 2)))));
Let's assume that we wish to multiply three variables, X = 2 * G * M. In Xnum this becomes,
xmul(xmul(2, G), M).
The xmul function can only accept two input variables, so first we multiply 2 * G (the innermost brackets) and then we multiply this result by M (the outmost brackets).
C squared (c^2) becomes xpow(c, 2) for xpow is the 'power function' in Xnum.
Consider the translation of the following floating point code : sqrt(1 - (2 * G)). In Xnum translation this becomes:
xsqrt(xsub(1, xmul(2, G)));
sqrt(1 - ((2 * G) / (R * c^2)))
xsqrt(xsub(1, xdiv(xmul(2, G), xmul(R, xpow(c, 2)))));
I use brackets to enforce rules of precedence on mathematical calculations in Scilab and this technique just naturally works correctly with Xnum. If you follow the brackets from left to right then you understand how to organize the Xnum functions correctly. It is at this point that the Scilab Editor auto-highlight feature for bracketing proves very valuable, for it always highlights the code in between two brackets and provides instant feedback so that the user does not get confused and lost in brackets.
Because Xnum uses strings as input, variables must initialized as string values.
X = emptystr(1, 1000);
X = emptystr(3, 1000);
The first line of code creates a vector consisting of one row of 1000 empty string variables. The second line of code creates a matrix with 3 rows of 1000 empty strings. I have found when using Xnum that it is important to allocate memory for the Xnum strings before doing calculations in a loop, for the allocation of string memory dynamically in code is so computationally intensive that it slows down Xnum calculations by a large amount of time.
It is not possible to create graphs in Scilab directly from Xnum variables (since Xnum variables are strings). The purpose of Xnum is to perform intensive calculations without accumulating errors caused by loss of precision. When the calculations are complete the final Xnum results can be converted to floating point values for graphing purposes, and these values will be more accurate than values that might have been produced using normal double precision floating point variables (for errors in precision would have accumulated, and the end result of the two calculations will be noticeably different for that reason).
QuPat is another enhanced precision math package for Scilab that uses 'quadruple precision' floating point numbers rather than strings as input. One of the advantages of QuPat is that it is faster than Xnum, which works with string representations of numbers. The advantage of Xnum is that, while it is slower, it is capable of doing calculations at an arbitrary precision (up to 200 digits) while QuPat is restricted to quadruple precision floating point.
QuPat package for Scilab
The Living Resurrection: A Manifesto