Я хотел бы реализовать следующую наивную (первого порядка) функцию конечных разностей:
finite_difference :: Fractional a => a -> (a -> a) -> a -> a
finite_difference h f x = ((f $ x + h) - (f x)) / h
Как вы, возможно, знаете, есть одна тонкая проблема: нужно убедиться, что (x + h)
и x
отличаются точно представимым числом. В противном случае результат будет иметь огромную ошибку, вызванную тем фактом, что (f $ x + h) - (f x)
предполагает катастрофическую отмену (и нужно тщательно выбирать h
, но это не моя проблема).
В C или C++ проблема может быть решена так:
volatile double temp = x + h;
h = temp - x;
а модификатор volatile
отключает любую оптимизацию, относящуюся к переменной temp
, поэтому мы уверены, что «умный» компилятор не будет оптимизировать эти две строки.
Я еще недостаточно знаю Haskell, чтобы знать, как это решить. я боюсь, что
let temp = x + h
hh = temp - x
in ((f $ x + hh) - (f x)) / h
будет оптимизирован Haskell (или бэкендом, который он использует). Как мне получить здесь эквивалент volatile
(если возможно, не жертвуя ленью)? Я не против конкретных ответов GHC.
h
будет происходить из ленивых бесконечных списков. Но что касается именно этой функции, вы правы, я не сразу это понял (и пытаюсь познакомиться с языком). - person Alexandre C.   schedule 12.04.2011