Compute the sum with a dynamic re-ordering.
s = accsum_orderdynamic ( x , order )
a m-by-n, matrix of doubles
a 1-by-1 matrix of doubles, a positive integer, the order. order = 1 : search for the entry which makes the smallest |s+y(i)|, good for accuracy, order = 2 : search for the entry which makes the largest |s+y(i)|, bad for accuracy
a 1-by-1 matrix of doubles, the sum
Try to find an order which makes the sum perform bad/good. Finding the optimal ordering of a sum, which minimizes the intermediate sums, is a combinatorial problem which is too expensive to solve in general. A compromise is used here. For k from 1 to n, we search for i which minimizes (if order=1) or maximizes (if order=2) the term |s+x(i)|, among the entries from 1 to n-k+1. Then the entries #i and #n-k+1 are switched.
This algorithm is called "Psum" in the Chapter 4 "Summation" of SNAA.
// Test on simple data x = [-9.9 5.5 2.2 -3.3 -6.6 0 1.1] sum(x) s = accsum_orderdynamic ( x , 1 ) s = accsum_orderdynamic ( x , 2 ) // Test on difficult data path = accsum_getpath ( ); filename=fullfile(path,"demos","etaana.dat"); x=fscanfMat(filename); // 7.390949249267578125000 sum(x) // 0.3437500000000000000000 s = accsum_orderdynamic ( x , 1 ) // - 73.015625 s = accsum_orderdynamic ( x , 2 ) | ![]() | ![]() |
"Stability and numerical accuracy of algorithms", Nicolas Higham
"Handbook of Floating Point Computations", Muller et al
https://hpcrd.lbl.gov/SCG/ocean/NRS/ECMWF/img16.htm