Detect and Overcome Cancellation Errors in MATLAB

by Pavel Holoborodko on July 9, 2012

Rounding and cancellation errors are major sources of accuracy loss in numerical computing. To detect these effects researchers have to conduct rigorous analysis of every operation in the algorithm both on the theoretical and computational level.

Multiprecision Computing Toolbox allows users to save time by applying a simple procedure to detect accuracy loss in their MATLAB programs. Using the toolbox researcher is able to re-run computations in elevated precision – with little or no modifications to existing source code.

If the results change significantly with increase of precision, chances are there is numerical instability somewhere in the computations. Otherwise computations are stable and time consuming analysis can be safely skipped.

Accuracy verification is one of the classic applications of the toolbox. As an illustration, we will share an example provided by one of the toolbox users who was able to detect and overcome a cancellation error in his computations using the toolbox.

Example

Our task is to find zeros of the following function:

    \[ f(x) = \sin(x)^2+\cos(x)^2+2\cdot\cos(x)\cdot\cosh(x)+\cosh(x)^2-\sinh(x)^2,\qquad 0<x<100 \]

Standard MATLAB function fzero solves this easily for any x < 40:

f = @(x) sin(x).^2+cos(x).^2+2*cos(x).*cosh(x)+cosh(x).^2-sinh(x).^2;
 
x = fzero(f, 5)
x =
          4.69409113297418
 
x = fzero(f, 10)
x =
          10.9955407348782
 
x = fzero(f, 15)
x =
          14.1371683911517
...
x = fzero(f, 30)
x =
          29.8449784514733

However for bigger values of x, fzero demonstrates strange behavior…

{ 0 comments }

The latest version of the Multiprecision Computing Toolbox introduces new routines to compute the nodes and weights of classical Gaussian quadrature rules with any required accuracy. A summary of the supported functionality is outlined below.

The Gaussian quadrature is targeted to approximate an integral by taking the weighted sum of integrand values sampled at special points (called abscissas). The abscissas and weights are calculated in a special way so that the rule provides a precise answer for all polynomials up to certain degree.

    \[ \int_a^b \omega(x)f(x)\,\mathrm{d}x \approx \sum_{i=1}^{n}{w_i\,f(x_i)} \]

The most common case, the Gauss-Legendre quadrature, occurs when the weight function \omega(x) = 1. However if the integrand has a factor (weight) of a special form, then a more efficient quadrature can be applied. This is beneficial for both accuracy and computational speed.

Read More

{ 0 comments }

New World Record – 110,000,000th Bernoulli Number

by Pavel Holoborodko on May 9, 2012

Bernoulli numbers are used extensively in many areas of mathematics and applied science. In particular, the Multiprecision Computing Toolbox relies on them for the evaluation of various special functions.

A few months ago, while our team was developing routines for the Gamma function, we found an excellent program from David Harvey for the efficient computation of Bernoulli numbers. The program is based on an original, parallelizable algorithm that is tailored to take advantage of modern multi-core CPU architectures.

We ran the program to compute the 110,000,000th Bernoulli number (the previous world record was the 100,000,000th). The computation took 15 days, and we used our Intel Xeon 5430 (Quadcore), 12GB ECC RAM with Ubuntu 10.04 64-bit as a host system.

The final result, B_{110\,000\,000} occupies 700MB in uncompressed, textual format. In its shortened form:

 \displaystyle{-\frac{2678712663617147865\dots17188572196384102833}{7386785024850234755289860612029729346078645764469688942653855164197093332104883640990}}

Contact us if you are interested in downloading all of the digits of the B_{110\,000\,000} number.

Bernoulli numbers can be computed in MATLAB using function mp.BernoulliNumber from our toolbox:

>> mp.Digits(50);
>> b = mp.BernoulliNumber([0:2:26]);
>> b'
                                                     1    
   0.1666666666666666666666666666666666666666666666667    
  -0.0333333333333333333333333333333333333333333333333    
   0.0238095238095238095238095238095238095238095238095    
  -0.0333333333333333333333333333333333333333333333333    
   0.0757575757575757575757575757575757575757575757576    
  -0.2531135531135531135531135531135531135531135531136    
   1.1666666666666666666666666666666666666666666666667    
  -7.0921568627450980392156862745098039215686274509804    
   54.971177944862155388471177944862155388471177944862    
  -529.12424242424242424242424242424242424242424242424    
   6192.1231884057971014492753623188405797101449275362    
  -86580.253113553113553113553113553113553113553113553    
   1425517.1666666666666666666666666666666666666666667

{ 0 comments }

Krylov Subspace Methods in Arbitrary Precision

by Pavel Holoborodko on April 19, 2012

The Krylov subspace methods are widely used for solving large, complex linear systems. These methods avoid slower matrix-matrix operations and only rely on efficient matrix-vector and vector-vector multiplication. The well known Krylov subspace methods are the CG (conjugate gradient), GMRES (generalized minimum residual), BiCGSTAB (biconjugate gradient stabilized), and MINRES (minimal residual), among others.

Although the Krylov subspace methods demonstrate excellent convergence for many types of problems, they may stagnate or do not converge in some cases[1], [2], [3]. Usually these situations are alleviated by selecting a good pre-conditioner. Another approach is to conduct the computations with a higher accuracy, using multiple precision arithmetic.

Toolbox provides a comprehensive set of routines for iterative solvers – BiCG, BiCGSTAB, BiCGSTABL, CGS, GMRES, MINRES and PCG. All functions are capable of working with arbitrary precision sparse and dense matrices. Methods support all special cases and parameters including function handles and preconditioners.

Arbitrary precision iterative solvers can be called using the usual syntax:

x = solver(A,b)
solver(A,b,tol)
solver(A,b,tol,maxit)
solver(A,b,tol,maxit,M)
solver(A,b,tol,maxit,M1,M2)
solver(A,b,tol,maxit,M1,M2,x0)
[x,flag] = solver(A,b,...)
[x,flag,relres] = solver(A,b,...)
[x,flag,relres,iter] = solver(A,b,...)
[x,flag,relres,iter,resvec] = solver(A,b,...)

Where actual name of the solver (bicg, bicgstab, minres, etc.) should be used instead of 'solver'. Please note, some solvers have method-specific parameters (e.g. number of restarts in GMRES). Refer to MATLAB documentation for more details.

As a quick example, let’s solve WEST0479 matrix by BiCGSTAB assuming true solution is all 1‘s:

mp.Digits(34);   % Use quadruple precision
 
load west0479;
A = west0479;
b = A*ones(size(A,2),1);
maxit = 30;
tol = mp('eps');
 
% Solve without preconditioner:
[x0,fl0,rr0,it0,rv0] = bicgstab(mp(A),mp(b),tol,maxit);
 
% Compute ILUTP in double precision
[L,U] = ilu(A,struct('type','ilutp','droptol',1e-6));
 
% Apply preconditioner:
[x1,fl1,rr1,it1,rv1] = bicgstab(mp(A),mp(b),tol,maxit,mp(L),mp(U));

By definition, preconditioner is not required to be very accurate, we compute it using the double precision and convert its factors to multiprecision afterwards to save time. Secondly, we use machine epsilon matching to requested level of precision as tolerance – it can be retrieved by mp('eps') or eps('mp') commands:

> mp.Digits(34);
>> mp('eps')
ans = 
    1.925929944387235853055977942584927e-34
 
>> eps('mp')
ans = 
    1.925929944387235853055977942584927e-34
 
>> mp.Digits(50);
>> mp('eps')
ans = 
    1.069105884036878258456214586860592751526078752042e-50
 
>> eps('mp')
ans = 
    1.069105884036878258456214586860592751526078752042e-50

Plots below show relative residual per iteration in each case:

figure;
semilogy(1:size(rv0,1),rv0'/norm(b),'-o','MarkerSize',4);
xlabel('Iteration number');
ylabel('Relative residual');
title('BiCGSTAB');
 
figure;
semilogy(1:size(rv1,1),rv1/norm(b),'-o','MarkerSize',4);
xlabel('Iteration number');
ylabel('Relative residual');
title('BiCGSTAB + ILUTP Preconditioner');

Quadruple precision BiCGSTAB without preconditioner

Quadruple precision BiCGSTAB with preconditioner

Preconditioner allows the solver to reach the full quadruple precision accuracy in 17 steps.

To demonstrate the advantages of arbitrary precision calculations over the standard double, we examine one of the examples from the special cases listed in [2]. It is known that the following Toeplitz matrix is very difficult to solve with the Krylov subspace methods when the parameter \gamma is large:

    \[ A = \begin{bmatrix}   2     & 1 &   &   &  &  \\   0     & 2 & 1 &   &  &  \\   \gamma& 0 & 2 & 1  &  &  \\         &\gamma& 0      & 2      & \ddots  &  \\         &      & \ddots & \ddots &  \ddots  & \\ \end{bmatrix}   \]

We apply the BiCG (biconjugate gradient) iterative solver for the 200×200 matrix, with \gamma=2.5, zero starting vector \bold{x}_0 = 0, unity right-hand side vector \bold{b} = (1,1, \ldots, 1)^\textrm{T}, and maximum number of iterations set to 400 steps:

n = 200;
g = 2.5;
A = spdiags(repmat([g 0 2 1],n,1), -2:1, n, n);
b = ones(n,1);
x = zeros(n,1);
 
tol = 2*eps;  
maxit = 2*n; 
 
[x0,flag0,rr0,iter0,rv0] = bicg(A,b,tol,maxit,[],[],x);
figure;
semilogy(0:length(rv0)-1,rv0/norm(b),'b');
hold on;
 
mp.Digits(75);
[x1,flag1,rr1,iter1,rv1] = bicg(mp(A),mp(b),mp('eps*1e+5'),maxit,[],[],mp(x));
semilogy(0:length(rv1)-1,rv1/norm(b),'r');
 
mp.Digits(150);
[x2,flag2,rr2,iter2,rv2] = bicg(mp(A),mp(b),mp('eps*1e+5'),maxit,[],[],mp(x));
semilogy(0:length(rv2)-1,rv2/norm(b),'k');
 
mp.Digits(300);
[x3,flag3,rr3,iter3,rv3] = bicg(mp(A),mp(b),mp('eps*1e+5'),maxit,[],[],mp(x));
semilogy(0:length(rv3)-1,rv3/norm(b),'g');
 
legend('double','75-digits','150-digits','300-digits');
xlabel('iteration number');
ylabel('relative residual');
title('BiCG')
hold off;

Arbitrary precision BiCG without preconditioner

The BiCG method implemented with the double arithmetic does not converge under these settings. The multiprecision BiCG is able to provide a solution with acceptable accuracy in 200 iterations. Actually it is very interesting to observe the fast convergence around 200-th iteration, as it is predicted by theory.

References

  1. Greenbaum, A., Iterative Methods for solving Linear Systems, SIAM, Philadelphia, 1997. ^
  2. Hasegawa, H., Utilizing the Quadruple-Precision Floating-Point Arithmetic Operation for the Krylov Subspace Methods, Talk at the Eighth SIAM Conference on Applied Linear Algebra, July 15-19, 2003, Williamsburg, Viginia, U.S.A. Mathematics of Computation, 66(219), 1133-1145. ^
  3. Barrett, R., Berry, M., Chan, T., Demmel, J., Donato, J., Dongarra, J., Eijkhout, V., Pozo, R., Romine, C., and van der Vorst, H., Templates for the Solution of Linear Systems: Building Blocks for Iterative Methods, SIAM, Philadelphia, 1994.^

{ 0 comments }

Fast Fourier Transform in Arbitrary Precision

by Pavel Holoborodko on April 11, 2012

UPDATE (December 25, 2017): Fast Fourier Transform (FFT) routines have been updated with various speed optimizations, including multi-core parallelism, extended set of small FFT with minimum number of arithmetic operations, etc. Now toolbox uses split-radix for power-of-two, mixed-radix Stockham framework for composite and Bluestein algorithm for prime lengths FFT. All algorithms have been optimized for parallel execution and quadruple/multi-precision modes.

We do not use Kiss FFT library anymore, since it doesn’t allow parallel optimizations. Instead we have developed our own C++ library, focused on computations with arbitrary precision and speed.


We released our newest update a few days ago, and in it we have further upgraded the Multiprecision Computing Toolbox to now include Fast Fourier Transform functions capable of computing in arbitrary precision. The newly introduced FFT functions are optimized by performance, and are fully compatible with all of MATLAB’s equivalent routines.

All special cases of the functions are supported:

Y = fft(x)
Y = fft(X,n)
Y = fft(X,[],dim)
Y = fft(X,n,dim)
y = ifft(X)
y = ifft(X,n)
y = ifft(X,[],dim)
y = ifft(X,n,dim)
y = ifft(..., 'symmetric')
y = ifft(..., 'nonsymmetric')


Both the direct and inverse transforms are optimized by speed, taking into account particular cases of real and conjugate complex sequences. Additionally, we employ specific optimization techniques when the input array length is of power of 2, or a composite number with simple factors 2,3,4, and 5.
See example

{ 0 comments }

Matrix Functions, Null Space, and Hessenberg Matrices

by Pavel Holoborodko on April 4, 2012

The recently released Multiprecision Computing Toolbox version 3.3.2 introduces multiple new routines and features for advanced numerical computing in arbitrary precision.

  • Matrix functions, including logarithm, square root, exponential, trigonometric, and a general matrix function
    funm	% Evaluate general matrix function	
    expm	% Matrix exponential					
    sqrtm	% Matrix square root					
    logm	% Matrix logarithm					
    sinm	% Matrix sine							
    cosm	% Matrix cosine						
    sinhm	% Matrix hyperbolic sine				
    coshm	% Matrix hyperbolic cosine
  • Special cases of an “economy sized” SVD decomposition
    [U,S,V] = svd(X,0)
    [U,S,V] = svd(X,'econ')
  • Kernel(null space) matrices, and matrices in Hessenberg form
    null	% Null space
    hess	% Hessenberg form of matrix
  • The formatted conversion of multiprecision entities into a string, and to standard data types
    num2str	% Convert number to string
    cast	% Cast variable to different data type
    double	% Convert to double precision
    int16	% Convert to 16-bit signed integer
    int32	% Convert to 32-bit signed integer
    int64	% Convert to 64-bit signed integer
    int8	% Convert to 8-bit signed integer
    single	% Convert to single precision
    uint16	% Convert to 16-bit unsigned integer
    uint32	% Convert to 32-bit unsigned integer
    uint64	% Convert to 64-bit unsigned integer
    uint8	% Convert to 8-bit unsigned integer
  • Logical Operations
    all	% Determine whether all array elements are nonzero or true
    any	% Determine whether any array elements are nonzero
    not	% Find logical NOT of array or scalar input
    xor	% Logical exclusive-OR

Examples

{ 0 comments }

Basic Numerical Methods

by Pavel Holoborodko on February 1, 2012

This past month, our development team successfully finished porting some of MATLAB’s basic numerical methods to the Multiprecision Computing Toolbox, enabling calculations in the arbitrary precision. At this point in time, the following routines for numerical integration, optimization, and ordinary differential equations are now available:

% Integration
quad	        % Numerically evaluate integral, adaptive Simpson quadrature
quadgl	        % Numerically evaluate integral, fixed Gauss-Legendre quadrature
dblquad	        % Numerically evaluate double integral over rectangle
triplequad	% Numerically evaluate triple integral
 
% Optimization
fminsearch	% Find minimum of unconstrained multivariable function (Nelder–Mead simplex search)
fzero	        % Find root of continuous function of one variable
optimset	% Create or edit optimization options structure
optimget	% Optimization options values
 
% Ordinary differential equations
ode45	        % Solve initial value problems for ordinary differential equations
odeget	        % Ordinary differential equation options parameters
odeset	        % Create or alter options structure for ordinary differential equation solvers

All new functions are fully compatible with MATLAB’s built-in analogs. In fact, most of the listed functions above are simply MATLAB’s codes ported to the multiprecision arithmetic with the aid of the Toolbox.
Usage examples

{ 0 comments }

Exponential, Logarithmic, Sine, and Cosine Integrals

by Pavel Holoborodko on November 22, 2011

The Multiprecision Computing Toolbox version 3.1.6 introduces multiple new routines for computing special functions in arbitrary precision:

expint(z, n)    % Exponential Integral, En(z)
eint(x)         % Exponential Integral (in terms of Cauchy principal value)
logint(x)       % Logarithmic Integral
cosint(z)       % Cosine Integral
sinint(z)       % Sine Integral
chint(z)        % Hyperbolic Cosine Integral
shint(z)        % Hyperbolic Sine Integral

The specific details of the implementation are given below.
Continue Reading

{ 0 comments }

Gauss-Kronrod Quadrature Nodes and Weights

by Pavel Holoborodko on November 7, 2011

The Gauss–Kronrod quadrature[1] includes two distinct sets of abscissae – Gauss nodes interleaved with Kronrod nodes. The special geometry of this system enables very efficient error estimation. In the beginning, the integral is approximated using Gauss quadrature. Then, the already evaluated function values are reused to produce higher order approximation, in combination with new values sampled at the Kronrod nodes. The difference between the two rules is a good indicator of how close the estimation is to the actual behavior of the integral. This technique is normally used as the stopping criteria in many adaptive numerical integration methods.

Here we focus on the Kronrod nodes computing in arbitrary precision, while using an efficient algorithm previously proposed by Laurie[2]. (See [3], [4] for other methods).
Read More

{ 4 comments }

Computing Eigenvalues in Extended Precision

by Pavel Holoborodko on October 12, 2011

Eigenvalues and eigenvectors play important role in many real-world applications, including control systems modeling, partial differential equations, data mining and clusterization, chemistry, vibration analysis, to name a few examples.

The main practical difficulty is that eigenproblem might be ill-conditioned and hard to compute even when matrix itself is well-conditioned.

This comes from the fact that computing eigenvalues is equivalent to finding roots of a polynomial, which is proven to be unavoidably ill-conditioned problem (even when roots are well-separated, as shown by J.H. Wilkinson [1-3]) .

More precisely, conditioning of an eigenproblem depends on eigenvalues clustering, magnitude and angles between the eigenvectors. All the properties are inherent to the problem and ill-conditioning, if it is present, cannot be easily alleviated or even detected beforehand. The only case when it is considered stable is computing eigenvalues of a symmetric matrix.

At the moment the only reliable way of dealing with ill-conditioned eigenproblems is to use the extended-precision computations. In fact, there is no other alternative in contrast to solving systems of linear equations where various pre-conditioners can be used to improve the conditioning.

Here we want to show two examples of such problems and how toolbox solves them in comparison to MATLAB.

Read More

{ 14 comments }