Расширение double-арифметики

Федеральное государственное образовательное бюджетное учреждение

Высшего образования

«ФИНАН

«ФИНАНСОВЫЙ УНИВЕРСИТЕТ ПРИ ПРАВИТЕЛЬСТВЕ

РОССИЙСКОЙ ФЕДЕРАЦИИ»

Департамент анализа данных, принятия решений и финансовых технологий

 

С.А.Зададаев

 

 

Расширение double-арифметики (RStudio)

Учебно-методические рекомендации для проведения

семинара №30 по компьютерному практикуму

 

Для бакалавров направления 38.03.01 «Экономика»

 

 

Электронное издание

 

 

Москва 2018


Расширение double-арифметики

   В данной части мы познакомимся с вычислениями в семантике обыкновенных дробей, которые позволяют сохранить точность результатов при оперировании с целыми или рациональными числами.

Алгебраически точное решение матричных уравнений*

    В языке R разработана специальная библиотека gmp, которая позволяет оперировать не с десятичным форматом чисел, а с алгебраическим.

    Поясним смысл сказанного, предварительно загрузив библиотеку gmp через меню Tools/Install Packages… и активировав ее кодом:

library(gmp)                   # Библиотека расширенных типов целых и рациональных чисел

    Теперь попробуем продемонстрировать разницу между обычной double арифметикой as.numeric и расширенной с помощью специальных типов as.bigz и as.bigq.

Задание 1. Вычислить с максимальной точностью число .

Решение. Подключим максимальную выводимую на экран точность double арифметики:

options(digits = 22)    # Выводим на экран консоли максимальное число разрядов

и вычислим число :

2^200

с результатом, записанным с помощью digits = 22 символов:

> options(digits = 22)> 2^200[1] 1.6069380442589903e+60

    Это означает, что число  мы представляем себе примерно, как:

число из 61 цифры, первые 17 из которых мы видим, как значащие.

    А остальные 44 цифры, вместо которых стоят нули, чему равны? Ответить на это вопрос здесь невозможно, т.к. мы использовали обычную double арифметику, и памяти, выделяемой на такие числа, недостаточно для получения более точного ответа.

    Попробуем теперь воспользоваться специальным типом данных bigz, который выделяет под такие вычисления практически неограниченную память в рамках физически доступной на каждом конкретном компьютере (bigz – дословно «большие целые»):

as.bigz(2^200)       # Вычислить выражение со всеми значащими цифрами

as.bigz(2)^200       # То же самое

с абсолютно точным результатом:

> as.bigz(2^200) # Вычислить выражение со всеми значащими цифрами Big Integer ('bigz'):[1] 1606938044258990275541962092341162602522202993782792835301376

в котором хорошо видны все 61 значащие цифры числа!

    Далее прокомментируем идею абсолютной точности рациональных чисел в алгебраической форме, т.е. чисел, которые можно представить в виде несократимой дроби .

    Потеря точности при вычислении таких дробей связана с возникновением периодических десятичных дробей, которые неизбежно приходится где-то обрывать. Однако, если результаты, включая промежуточные, представлять в виде обыкновенных дробей, то точность будет сохраняться – эту идею как раз и использует в своих алгоритмах специальный тип данных bigq (bigq – ­дословно «большие рациональные»).

Задание 2. Для матрицы A

найти обратную матрицу с максимальной точностью.

Решение. Считаем матрицу из Excel (см. Рис.1)

Рис.1

# В excel сформировать таблицу чисел и скопировать в буфер обмена 

Data <- read.table("clipboard", h=FALSE, dec=",", sep = "\t") # Чтение из буфера обмена excel-формата

A <- data.matrix(Data)      # Объявить таблицу чисел матрицей в R

A                                   # Посмотреть результат

и для сравнения укажем, что обычная максимальная точность double-арифметики дала бы такой ответ для обратной матрицы:

solve(A) # Найти обратную матрицу в десятичном представлении

с результатом:

> solve(A) # Найти обратную матрицу в десятичном представлении             [,1]           [,2]            [,3]V1 0.27272727272727276 0.18181818181818188 -0.09090909090909087V2 0.18181818181818188 0.45454545454545464 0.27272727272727282V3 1.00000000000000022 1.00000000000000022 1.00000000000000022

    В случае представления результата через обыкновенные дроби типа bigq имеем:

solve(as.bigq(A)) # Найти обратную матрицу в обыкновенных дробях

solve.bigq(A)       # Tо же самое

с результатом:

> solve(as.bigq(A)) # Найти обратную матрицу в обыкновенных дробяхBig Rational ('bigq') 3 x 3 matrix: [,1] [,2] [,3] [1,] 3/11 2/11 -1/11[2,] 2/11 5/11 3/11 [3,] 1 1 1

    Проверим, насколько точной получится единичная матрица , если перемножить :

A%*%solve(as.bigq(A))   # Проверка точности

с абсолютно точным результатом:

> A%*%solve(as.bigq(A)) # Проверка точностиBig Rational ('bigq') 3 x 3 matrix: [,1] [,2] [,3][1,] 1 0 0 [2,] 0 1 0 [3,] 0 0 1

 

Задание 3. Решить систему уравнений

                          

в обыкновенных дробях.

Решение. Матрица коэффициентов системы совпадает с матрицей A из предыдущего примера

,

а столбец правой части .

Для сравнения приводим два решения: приближенное и точное:

B <- 1:3                       # Задаем вектор B(1, 2, 3)

solve(A, B)                  # Находим решение системы AX=B в десятичном представлении

solve.bigq(A, B)            # Находим решение системы AX=B в обыкновенных дробях

A%*%solve.bigq(A, B) # Проверяем второй результат (должен получиться столбец B)

Результаты приведены на рис. 2

Рис.2


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: