Сегодня мы сконструируем числовую систему, умеющую оперировать с приближёнными значениями.
Математика, как известно, наука точная, тогда как мир вне нашего сознания полон неожиданностей, приближений и погрешностей. И математикам неизбежно пришлось приспособиться к этому, выработав инструменты для работы с величинами, которые известны лишь приблизительно.
Любое измерение имеет некоторую погрешность той или иной природы. Это приводит к необходимости говорить не о значении числа, о паре чисел: значении и абсолютной погрешности (x, ∆x), которую мы привычно обозначаем так: x ± ∆x.
Давайте вспомним как можно оценить значение некоторой функции от приближённой величины f(x ± ∆x). Малые изменения аргумента функции приводят к малым изменениям её значения, которые, в свою очередь, пропорциональны производной функции в точке x. Если функция гладкая, эти соображения приводят нас к линейному приближению значения функции:
Это хорошо известные основы математического анализа, на которых базируются методы приближённых вычислений. Однако линейные приближения для результатов арифметических вычислений с приближенными числами, можно построить, не прибегая к дифференциальному анализу.
Наши достижения в области алгебростроения позволяют применить параболическую арифметику дуальных чисел к задаче вычисления алгебраических выражений с известной абсолютной погрешностью. Напомню, что дуальные числа строятся, как расширение вещественных чисел нетривиальным решением уравнения x² = 0, которую можно интерпретировать как бесконечно малую величину ε, обращающуюся в ноль, при возведении в степень больше первой. Таким образом, мы можем моделировать приближённую величину, как дуальное число, и перейти к его линейному представлению в виде матрицы:
Как мы уже видели, дуальные числа умеют производить автоматическое дифференцирование, так что почти всю возню с производными мы можем перепоручить матрицам.
- При сложении абсолютные погрешности складываются:
- При перемножении приближенных величин, складываются их относительные погрешности δx = ∆x/x. Абсолютная погрешность результата при этом равна произведению результата и его относительной погрешности
Возведение в степень n увеличивает относительную погрешность в n раз.
Как видим, с операциями сложения и умножения матричное представление справляется отлично, так что мы получили качественное полукольцо вещественных чисел с погрешностью.
А как обстоят дела с вычитанием и делением? Или спросим как алгебраисты: как должны строиться противоположные и обратные элементы в нашей числовой системе?
Здесь придется вводить определённые искусственные правила, не вытекающие напрямую только из линейного представления дуальных чисел. Если следовать дуальной арифметике, то можно получить следующий результат:
Но увы, погрешности при вычитании тоже растут: невозможно повысить точность просто складывая или вычитая неточные значения, для этого используются иные методы, выходящие за рамки алгебры.
Так что погрешности не бывают отрицательными, и, следовательно, не образуют группу по сложению. Это можно оправдать симметричностью погрешности относительно ожидаемого значения числа, а формально сказать, что знаки "плюс-минус" и "минус-плюс" тождественны друг другу:
Раз линейная алгебра сама не справляется, придётся нам искусственно определить представление для противоположного элемента нашей арифметики следующим образом:
Тогда вычисление разности двух значений с погрешностью будет вычисляться корректно:
С такой операцией вычитания мы превращаем арифметику чисел с погрешностью в кольцо.
В рамках линейного представления делению (умножению на обратный элемент) соответствует умножение на обратную матрицу. Для этого необходимо чтобы матрица, представляющая число была обратима. Условие обратимости — отличие от нуля определителя, который для представления числа x ± ∆x равен x². Отсюда делаем вывод: любое ненулевое число обратимо, тогда как на ноль или на ε делить нельзя. В этом состоит отличие этой арифметики от арифметик эллиптического или гиперболического типов, в которых числа с нулевой вещественной частями были обратимыми.
Поскольку в нашей арифметике есть нетривиальные делители нуля: нули с различной погрешностью, то наше кольцо в поле превратить не удастся, но это не страшно. Кольцо — тоже хорошее дело!
Давайте обратим матрицу для произвольного ненулевого элемента нашей арифметики:
При этом опять вылезает некорректная отрицательная погрешность. Но переопределять обращение матриц мы не будем, а вместо этого, так же как с вычитанием, переопределим обращение числа с погрешностью следующим образом:
Вот так будет выглядеть деление для двух приближённых значений:
Введя простое правило: во всех обратных операциях погрешность формально меняет знак, мы получаем полноценную алгебру, имеющую линейное представление.
Использование матриц вместо пар x ± ∆x может показаться усложнением, но матричная алгебра, в отличие от реализации дуальных чисел, есть в инструментарии большинства языков программирования, в пакетах символьных вычислений и даже в некоторых калькуляторах (как например в том, которым я пользуюсь на своём телефоне). Линейное представление позволяет легко производить оценку погрешностей, пользуясь любым из этих инструментов без необходимости из перепрограммирования.
Примеры
Решим пару задач в "ванильном" Julia, без использования каких-то дополнительных библиотек:
1. Размеры комнаты 5 м × 6 м × 2,7 м сняли с помощью рулетки с абсолютной точностью в 0.5 см. Каков объём комнаты?
Как видим, погрешность в измеренном таким образом объёме составит треть кубического метра.
2. А вот задачка с решением из сборника задач по приближённым вычислениям:
Решим этот же пример с помощью матриц:
Обработка экспериментальных данных, конечно, не ограничивается арифметикой, нужны и корни различных степеней, и трансцендентные функции. Для них легко ввести общее правило, с которого мы и начали наш разговор: