La forma absolutamente óptimo es el uso de una cola de prioridad, de la siguiente manera:
PriorityQueue<Float> q = new PriorityQueue<Float>();
for(float x : list) q.add(x);
while(q.size() > 1) q.add(q.pop() + q.pop());
return q.pop();
(este código se supone que los números son positivos; generalmente la cola deben ser ordenados por valor absoluto)
Explicación: dada una lista de números, para sumarlos de la manera más precisa posible, debe esforzarse por hacer que los números eliminar la diferencia entre los pequeños y grandes. Es por eso que desea sumar los dos números más pequeños, aumentando así el valor mínimo de la lista, disminuyendo la diferencia entre el mínimo y el máximo en la lista y reduciendo el tamaño del problema en 1.
Lamentablemente no tengo ni idea cómo se puede vectorizar, teniendo en cuenta que estás usando OpenCL. Pero estoy casi seguro de que puede ser. Puede echar un vistazo al libro sobre algoritmos vectoriales, es sorprendente lo poderosos que son en realidad: Vector Models for Data-Parallel Computing
¿por qué esperas que el resultado sea menor que 1? ¡Estoy confundido! – lexu
Creo que él está diciendo que * una vez * el resultado pasa 1.0 los problemas comienzan a surgir. * Qué * problemas que no sé, pero así es como lo tomé. –
En Python, use 'math.fsum' (http://docs.python.org/library/math.html#math.fsum). – kennytm