In R
, the package Rmpfr
package provide
some functions for arbitrary-precision arithmetic. The way it is done is
to allow for using more memory for storing numbers. This is very good
for some use-cases, e.g. the example in Rmpfr
’s a vignette
“Accurately Computing log (1 − exp (−|a|))”.
Here, we demonstrate how to do investigate other aspects of
arbitrary-precision arithmetic using Ryacas
, e.g. solving
systems of linear equations and matrix inverses.
First see the problem when using floating-point arithmetic:
## [1] -2.775558e-17
## [1] "0"
# always work well; often
# it is better to represent as
# rational number if possible
# (1/3 - 1/5) = 5/15 - 3/15 = 2/15
(1/3 - 1/5) - 2/15
## [1] -2.775558e-17
## [1] "0"
The yacas
function N()
gives the numeric (floating-point) value for a precision.
## [1] "1/3"
## [1] "0.3333333333"
## [1] "0.3"
## [1] "0.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333"
Consider the polynomial (x − 1)7 with root 1 (with multiplicity 7). We can consider it both in factorised form and in expanded form:
## expression((x - 1)^7)
## expression(x^7 - 7 * x^6 + 21 * x^5 - 35 * x^4 + 35 * x^3 - 21 *
## x^2 + 7 * x - 1)
Mathematically, these are the same objects, but when it comes to numerical computations, the picture is different:
## [1] 1e-21
## [1] 8.881784e-15
We can of course also evaluate the polynomials in the different forms
in yacas
using WithValue()
:
## [1] "WithValue(x, 1.001, (x-1)^7)"
## [1] "0"
#... to get result symbolically, use instead the number as a fraction
pol_val <- paste0("WithValue(x, 1001/1000, ", pol, ")")
pol_val
## [1] "WithValue(x, 1001/1000, (x-1)^7)"
## [1] "1/1000000000000000000000"
## [1] "1000000000000000000000"
## [1] "21"
## [1] "WithValue(x, 1001/1000, Expand((x-1)^7))"
## [1] "1/1000000000000000000000"
The reason for the difference is the near cancellation problem when using floating-point representation: Subtraction of nearly identical quantities. This phenomenon is illustrated in the plot below.
This example could of course have been illustrated directly in
R
but it is convenient that Ryacas
provides
expansion of polynomials directly so that students can experiment with
other polynomials themselves.
In R
’s solve()
help file the Hilbert matrix
is introduced:
We will now demonstrate the known fact that it is ill-conditioned (meaning e.g. that it is difficult to determine its inverse numerically).
First we make the Hilbert matrix symbolically:
hilbert_sym <- function(n) {
mat <- matrix("", nrow = n, ncol = n)
for (i in 1:n) {
for (j in 1:n) {
mat[i, j] <- paste0("1 / (", (i-1), " + ", j, ")")
}
}
return(mat)
}
## [,1] [,2] [,3] [,4] [,5] [,6] [,7]
## [1,] 1.0000000 0.5000000 0.3333333 0.25000000 0.20000000 0.16666667 0.14285714
## [2,] 0.5000000 0.3333333 0.2500000 0.20000000 0.16666667 0.14285714 0.12500000
## [3,] 0.3333333 0.2500000 0.2000000 0.16666667 0.14285714 0.12500000 0.11111111
## [4,] 0.2500000 0.2000000 0.1666667 0.14285714 0.12500000 0.11111111 0.10000000
## [5,] 0.2000000 0.1666667 0.1428571 0.12500000 0.11111111 0.10000000 0.09090909
## [6,] 0.1666667 0.1428571 0.1250000 0.11111111 0.10000000 0.09090909 0.08333333
## [7,] 0.1428571 0.1250000 0.1111111 0.10000000 0.09090909 0.08333333 0.07692308
## [8,] 0.1250000 0.1111111 0.1000000 0.09090909 0.08333333 0.07692308 0.07142857
## [,8]
## [1,] 0.12500000
## [2,] 0.11111111
## [3,] 0.10000000
## [4,] 0.09090909
## [5,] 0.08333333
## [6,] 0.07692308
## [7,] 0.07142857
## [8,] 0.06666667
## [,1] [,2] [,3] [,4] [,5]
## [1,] "1 / (0 + 1)" "1 / (0 + 2)" "1 / (0 + 3)" "1 / (0 + 4)" "1 / (0 + 5)"
## [2,] "1 / (1 + 1)" "1 / (1 + 2)" "1 / (1 + 3)" "1 / (1 + 4)" "1 / (1 + 5)"
## [3,] "1 / (2 + 1)" "1 / (2 + 2)" "1 / (2 + 3)" "1 / (2 + 4)" "1 / (2 + 5)"
## [4,] "1 / (3 + 1)" "1 / (3 + 2)" "1 / (3 + 3)" "1 / (3 + 4)" "1 / (3 + 5)"
## [5,] "1 / (4 + 1)" "1 / (4 + 2)" "1 / (4 + 3)" "1 / (4 + 4)" "1 / (4 + 5)"
## [6,] "1 / (5 + 1)" "1 / (5 + 2)" "1 / (5 + 3)" "1 / (5 + 4)" "1 / (5 + 5)"
## [7,] "1 / (6 + 1)" "1 / (6 + 2)" "1 / (6 + 3)" "1 / (6 + 4)" "1 / (6 + 5)"
## [8,] "1 / (7 + 1)" "1 / (7 + 2)" "1 / (7 + 3)" "1 / (7 + 4)" "1 / (7 + 5)"
## [,6] [,7] [,8]
## [1,] "1 / (0 + 6)" "1 / (0 + 7)" "1 / (0 + 8)"
## [2,] "1 / (1 + 6)" "1 / (1 + 7)" "1 / (1 + 8)"
## [3,] "1 / (2 + 6)" "1 / (2 + 7)" "1 / (2 + 8)"
## [4,] "1 / (3 + 6)" "1 / (3 + 7)" "1 / (3 + 8)"
## [5,] "1 / (4 + 6)" "1 / (4 + 7)" "1 / (4 + 8)"
## [6,] "1 / (5 + 6)" "1 / (5 + 7)" "1 / (5 + 8)"
## [7,] "1 / (6 + 6)" "1 / (6 + 7)" "1 / (6 + 8)"
## [8,] "1 / (7 + 6)" "1 / (7 + 7)" "1 / (7 + 8)"
## {{ 1, 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8},
## { 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8, 1/9},
## { 1/3, 1/4, 1/5, 1/6, 1/7, 1/8, 1/9, 1/10},
## { 1/4, 1/5, 1/6, 1/7, 1/8, 1/9, 1/10, 1/11},
## { 1/5, 1/6, 1/7, 1/8, 1/9, 1/10, 1/11, 1/12},
## { 1/6, 1/7, 1/8, 1/9, 1/10, 1/11, 1/12, 1/13},
## { 1/7, 1/8, 1/9, 1/10, 1/11, 1/12, 1/13, 1/14},
## { 1/8, 1/9, 1/10, 1/11, 1/12, 1/13, 1/14, 1/15}}
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 64 -2016 20160 -92400 221760 -288288
## [2,] -2016 84672 -952560 4656960 -11642401 15567553
## [3,] 20160 -952560 11430720 -58212002 149688006 -204324129
## [4,] -92400 4656960 -58212002 304920013 -800415033 1109908845
## [5,] 221760 -11642401 149688006 -800415033 2134440086 -2996753877
## [6,] -288288 15567553 -204324129 1109908846 -2996753878 4249941857
## [7,] 192192 -10594585 141261126 -776936192 2118916882 -3030051135
## [8,] -51480 2882880 -38918882 216216009 -594594023 856215391
## [,7] [,8]
## [1,] 192192 -51480
## [2,] -10594584 2882880
## [3,] 141261126 -38918882
## [4,] -776936191 216216009
## [5,] 2118916881 -594594022
## [6,] -3030051135 856215390
## [7,] 2175421325 -618377781
## [8,] -618377781 176679366
## {{ 64, -2016, 20160, -92400, 221760, -288288, 192192, -51480},
## { -2016, 84672, -952560, 4656960, -11642400, 15567552, -10594584, 2882880},
## { 20160, -952560, 11430720, -58212000, 149688000, -204324120, 141261120, -38918880},
## { -92400, 4656960, -58212000, 304920000, -800415000, 1109908800, -776936160, 216216000},
## { 221760, -11642400, 149688000, -800415000, 2134440000, -2996753760, 2118916800, -594594000},
## { -288288, 15567552, -204324120, 1109908800, -2996753760, 4249941696, -3030051024, 856215360},
## { 192192, -10594584, 141261120, -776936160, 2118916800, -3030051024, 2175421248, -618377760},
## { -51480, 2882880, -38918880, 216216000, -594594000, 856215360, -618377760, 176679360}}
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 64 -2016 20160 -92400 221760 -288288
## [2,] -2016 84672 -952560 4656960 -11642400 15567552
## [3,] 20160 -952560 11430720 -58212000 149688000 -204324120
## [4,] -92400 4656960 -58212000 304920000 -800415000 1109908800
## [5,] 221760 -11642400 149688000 -800415000 2134440000 -2996753760
## [6,] -288288 15567552 -204324120 1109908800 -2996753760 4249941696
## [7,] 192192 -10594584 141261120 -776936160 2118916800 -3030051024
## [8,] -51480 2882880 -38918880 216216000 -594594000 856215360
## [,7] [,8]
## [1,] 192192 -51480
## [2,] -10594584 2882880
## [3,] 141261120 -38918880
## [4,] -776936160 216216000
## [5,] 2118916800 -594594000
## [6,] -3030051024 856215360
## [7,] 2175421248 -618377760
## [8,] -618377760 176679360
## [,1] [,2] [,3] [,4] [,5]
## [1,] 0.0000012595 -6.280053e-05 0.0007762981 -0.004023341 0.01045849
## [2,] -0.0000634834 3.150850e-03 -0.0388042819 0.200490239 -0.51978479
## [3,] 0.0007913917 -3.913434e-02 0.4805039167 -2.476326779 6.40613982
## [4,] -0.0041300914 2.036124e-01 -2.4937464967 12.824575186 -33.11633968
## [5,] 0.0107986356 -5.310077e-01 6.4897316694 -33.314724684 85.89412045
## [6,] -0.0149156042 7.318508e-01 -8.9280686677 45.760925531 -117.82621908
## [7,] 0.0104020056 -5.094212e-01 6.2047709525 -31.759819388 81.68062663
## [8,] -0.0028846884 1.410395e-01 -1.7154899687 8.770542115 -22.53314412
## [,6] [,7] [,8]
## [1,] -0.01437405 0.00998076 -0.002757407
## [2,] 0.71275051 -0.49393205 0.136219052
## [3,] -8.76787683 6.06612584 -1.670521952
## [4,] 45.25378895 -31.26587522 8.599618167
## [5,] -117.21701336 80.88934231 -22.225065231
## [6,] 160.60632944 -110.71761990 30.392856956
## [7,] -111.22357941 76.60545301 -21.011935592
## [8,] 30.65552807 -21.09724677 5.782607675
## [1] 160.6063
## [1] 5.603513e-08
As seen, already for n = 8 is the numeric solution inaccurate.