Вычисление относительной погрешности для функции. |
1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!
Вычисление относительной погрешности для функции. |
Krjuger |
12.04.2011 17:19
Сообщение
#1
|
Профи Группа: Пользователи Сообщений: 652 Пол: Мужской Реальное имя: Алексей Репутация: 20 |
В общем это некое продолжение моей прошлой темы,только обрастающее новыми подробностями.
У меня дана функция x(expx-1).Я эту функцию раскладываю я ряд Тейлора и получаю сумма от 1 до N от xn+1/n!. Чтобы найти относительную погрешность мне надо а -n ый член разделить на сумму ряда,все это по модулю.Ну в общем то ,я думаю, вы и так понимаете как это делать.Суть заключается в том,у меня опять есть ограниченная разрядность мантисы и мне надо посмотреть как она будет влиять на результат.И как будет меняться N при которых мы будем выходить за граници возможностей нашей машины. Я немного абстрагировался от этой задачи.что я сделал, при помощи маткада я посчитал,при каком N будет достигаться относительная погрешность на грани машинного эпсилон 10-16,это N =24.Да забыл сказать,что точка в которой мы раскладываем ряд у меня дана.Это -2.3.Затем я высчитал значение этой погрешности она составила 8.602898672363349*10^-16.Дальше я посомтрел как оно себя будет вести при разрядах мантисы от 10 до 25,при фиксированных исходных данных.Для рязрядности с 10 до 16 я получил ожидаемый результат,но дальше начало твориться что то вообще непонятное.Ну или точнее я не могу понять, как это интерпретировать. Файл с самой программой тоже прикрепляю. Прикрепленные файлы ChMet_Laba_1.cpp ( 1.24 килобайт ) Кол-во скачиваний: 221 |
Krjuger |
12.04.2011 19:56
Сообщение
#2
|
Профи Группа: Пользователи Сообщений: 652 Пол: Мужской Реальное имя: Алексей Репутация: 20 |
Я не много изменил основную программу,она стала выглядить так
Чтобы стало немного нагляднее.Принципи,большинство цифр получились вполне ожидаемыми,но возникли вопросы,почему,при разрядности мантисы 19 получается самое точное число ,а именно 8.603*10^-16,но дальше начинается уже какой то бред,так же непонятно,потому при 19,по идеи это должно было произойти при 16,либо я что то сильно недопонимаю.И я не понял почему при 20 я не получил на 1 значащую цифру более точный результат?В общем вопросов много.... |
volvo |
15.04.2011 12:11
Сообщение
#3
|
Гость |
Что-то тема заскучала... Давай сделаем вброс небольшой.
1) Цитата что я сделал, при помощи маткада я посчитал,при каком N будет достигаться относительная погрешность на грани машинного эпсилон 10-16,это N =24. Неверно. Надо проверять не на грани машинного эпсилон, а на грани эпсилон для твоего типа, мантисса которого содержит ограниченное число разрядов. Для m = 5 и m = 11 это будут разные значения, и нет смысла вычислять с точностью 10-16, если m = 5. Максимальная точность - только для максимальных длин мантиссы, и то не в типе float, а в long double. Соответственно, вычислять надо не N первых членов ряда, а пока очередной член не будет меньше Epsilon для типа.2) Цитата Дальше я посомтрел как оно себя будет вести при разрядах мантисы от 10 до 25,при фиксированных исходных данных. На всех значениях от 10 до 25 посмотреть не могу, а вот для M = 5, M = 8 и M = 11 - проверил. Извиняй, в Сях нет соответствующих средств, поэтому проверил там, где есть:with Ada.Text_IO; use Ada.Text_IO;Результат: Mantissa : 5 Могу проверить еще и для остальных (M = 15, 18, 21, ...), если надо. |
Krjuger |
15.04.2011 17:06
Сообщение
#4
|
Профи Группа: Пользователи Сообщений: 652 Пол: Мужской Реальное имя: Алексей Репутация: 20 |
Я наверно со совсем корректно написал то,что сделал.
Цитата Неверно. Надо проверять не на грани машинного эпсилон, а на грани эпсилон для твоего типа, мантисса которого содержит ограниченное число разрядов. Для m = 5 и m = 11 это будут разные значения, и нет смысла вычислять с точностью 10-16, если m = 5. Максимальная точность - только для максимальных длин мантиссы, и то не в типе float, а в long double. Соответственно, вычислять надо не N первых членов ряда, а пока очередной член не будет меньше Epsilon для типа. Да я это понимаю.Я их не сравнивал с машинной эпсилон. В общем,лень мое горе,напишу полностью,как есть информацию.Изначально у меня было 2 задачи 1 нужно было сделать в маткаде,а 2 на языке. Цитата Задача 1.2 Используя разложение заданной функции F(x) в ряд Тейлора в окрестности нуля, вычислить значения функции в двух точках x1и x2. Вычисление частичных сумм ряда производить до тех пор, пока отношение прибавляемого члена к частичной сумме не станет меньше машинного эпсилон.. ПОРЯДОК РЕШЕНИЯ ЗАДАЧИ: 1. Разложить заданную функцию F(x) в ряд Тейлора в окрестности нуля. 2. Выписать величину относительной погрешности, вычисляя ее как отношение прибавляемого члена к накопленной частичной сумме , взятое по модулю. 3. Определить количество членов ряда , при котором величина относительной погрешности станет меньше машинного эпсилон. Это я сделал сдал и бог бы с ним.В маткаде было выставлено считать до 16 цифр,результат я показал ранее. Цитата Задача 1.4. Составить программу на алгоритмическом языке, моделирующую вычисления на ЭВМ с ограниченной разрядностью m. Решить задачу 1.2 , используя эту программу. Составить график зависимости относительной погрешности от количества разрядов m= 4,5,…8. Вот собственно то,что я пытаюсь сотворить. Я немного отошел от задания,а именно сделал проверку при мантисе не 4,5,…8,а 10-25,чтобы посмотреть поведение.В моей голове уложилось такое мнение,что если мантиса имеет n чисел,то для этой мантисы машинное эпсилон будет равно 10-n,Так же я понимаю,что существует машинная эпсилон для тех стантартных типов данных,что есть я языке.В маткаде при 16 цифрах,я получал результат 8.602898672363349*10^-16,что вполне логично,это было границей точности,так как следующее число было уже 10-17,что выходит за рамки.Все это действо получалось при суммировании 24 членов ряда.Я думаю вполне логично,что при мантисе от 10 до 25 где нить должно будет появиться это число.Когда я выставляю мантису 16 и суммирую 24 раза я получаю вполне ожидаемый результат 8.602898672363349*10^-16 превращается в 9*10^-16,что вполне логично.Эта логика сохраняется до мантисы в 19.Происходить просто увеличение на 1 цифру точности числа,при 19 я получаю 8.603*10^-16,но при 20 происходит ,то чего я не ожидал.Вместо улучшения еще на 1 цифру я получаю совершенно другие результаты.Я пробовал менять double на long double,думая,что упираюсь в его точность,но меня ждал,сурприз,ни в одном тесте цифры не изменились. Тип float я в своей программе нигде и не использовал.Собственно,вопросы которыми я задаюсь следующие.Почему фигня начинается при мантисе 19,а не после 16,я спрашивал у преподавателя,он что то невнятное сказал,про то ,что когда сопроцессор считает,он использует расширенную точность,меня это как то невоодушевило,слишком расплывчато. В ваш код я очень старался вникнуть,но увы,с адой мое знакомство нулевое,так что я понял достаточно мало.Единственное я понял,что вы высчитывали факториал и слешующий элемент последовательности. Я не понял почему вы вызывали для мантисы 5 type MyFloat_05 is new Float digits 1; И в результате получали Last item : 1.6E-01,тобиш 0.16,вроде как мантиса 5 должна упереться в 10-5,либо я уже совсем ничего не понимаю.Кстати вы уж извините,но я руками посчитал несколько первых цленов ряда,и с вашими цифрами они никак не совпадают. Так что я прошу прокоментировать ваш код,ну или сделать небольшой вброс теории, которой вы руководствовались.Ну и если я где то что то смутно написал,то спросить,чтобы я прямо ответил. Да я забыл сказать,Для второй точки там число суммирований членов ряда при 16 получается около 70,так что я не стал реализовывать факториал рекурсивно,такая махина ни в один стандартный тип не влезет,использовать длинную арифметику тоже не стал,на мой взгляд не стоит овчинка выделки,да и как сделать это не знаю,не сталкивался,так что я поступил следующим образом,переходя в цикле на очередной член ряда я его в цикле делил на число от 2 до номера текущего члена ряда,и каждый раз при делении укорачивал подстраиваясь под мантису.Может это создаст еще некоторую погрешность,но мне легче обосновать преподавателю эту вынужденную погрешность,чем избавиться от нее. Сообщение отредактировано: Krjuger - 15.04.2011 17:11 |
volvo |
15.04.2011 17:58
Сообщение
#5
|
Гость |
Цитата Я не понял почему вы вызывали для мантисы 5 type MyFloat_05 is new Float digits 1; Я не для какой-то мантиссы делал специфическое значение digits, я просто создал три новых типа, каждый из которых ограничивает вычисления определенной точностью. Первый - одной десятичной цифрой после запятой, второй - двумя, третий, соответственно, тремя. Зачем? А затем, чтобы все эти 3 типа имели разное представление: разную длину мантиссы, в данном случае. При желании можно сделать еще и длину экспоненты разной, но меня это в данном случае меньше интересовало. Потом проверил, что для сконструированного типа возвращает атрибут 'Mantissa - это как раз и будет число бит в мантиссе (как ты на 5 битах собрался достичь точности 10-5 для меня - загадка). Атрибут 'Epsilon возвращает ту самую точность, до достижения которой надо продолжать вычисления (здесь мне ничего вручную делать не надо - в отличие от тебя, творящего непонятно что с числами - в случае Ады это забота компилятора. Если я сказал, что мне достаточно одной цифры после запятой, и 'Mantissa показала, что M=5, то все вычисления будут производиться именно так, как они и должны производиться при пятибитной мантиссе).Ну, а потом - все просто. Вычисляем очередной член ряда до тех пор, пока не доберемся до незначащих значений (меньше эпсилон). Можно чуть-чуть поправить, не домножать знаменатель на N, а делить числитель на него. От этого ничего не изменится, разве что будет работать при больших значениях N. Цитата Собственно,вопросы которыми я задаюсь следующие.Почему фигня начинается при мантисе 19,а не после 16 Собственно, вопрос: а почему фигня должна начинаться при длине мантиссы = 16? И с какой стати ты решил, что те результаты, которые ты получил - фигня? Я, например, вообще ничего не вижу на твоем скриншоте. Выведи хотя бы то же самое, что выводил я: длина мантиссы, последний член ряда, сумма ряда. Вот тогда и посмотрим, что у тебя творится...Цитата Кстати вы уж извините,но я руками посчитал несколько первых членов ряда,и с вашими цифрами они никак не совпадают. Вы у ж меня тоже извините, но я посчитал сумму ряда (оно же - значение x(ex - 1)) при заданном X. Что характерно - сумма (при использовании точных типов) совпадает идеально. Как может быть, что член ряда не совпадает, а их сумма - таки да? И... Что именно не совпадает?Первый: (-2.3)2 / 1! = 5.29 (у меня 5.3E+00) Второй: (-2.3)3 / 2! = -6.0835 (у меня -6.1E+00) Дальше продолжать? С учетом точности представления (не забыл? 5 бит мантиссы - это 1 десятичная цифра после запятой) как раз все совпадает... В общем, убеждаюсь в очередной раз: тебе лучше не отвечать, ибо я ж еще и виноват в том, что ты не умеешь читать и считать. Удачи тебе в дальнейших обвинениях других... Вот вычисления при длине мантиссы 15, 18, 21, 25, 28 и 31 бит (Показать/Скрыть)
|
Krjuger |
15.04.2011 19:14
Сообщение
#6
|
Профи Группа: Пользователи Сообщений: 652 Пол: Мужской Реальное имя: Алексей Репутация: 20 |
Почему,реакция сразу негативная,я же не говорил,что вы не правы,я лиш сказал,что мои расчеты и ваши отличаются, именно поэтому я попросил привести аргументы,которыми вы руководствовались,чтобы найти ошибку.
Насчет всего выше сказанного буду пытаться обмозговать. Скриншот исправлю,он относился к первой редакции,до изменений,дальше стано намного читабельней. Я нашел почему получались разные результаты,да,это была моя ошибка,ну а точнее неточность,я выводил сразу относительную погрешность,а не а-n-ый член рядаи даже не сумму.Так,по числам у меня воспадает с вашими. Насчет эпсилон,я покопался в рукописах своих,и ума не приложу,почему меня так переклинило на этой точности.Буду работать ,чуть позже выложу новый вариант. Сообщение отредактировано: Krjuger - 15.04.2011 19:51 |
Krjuger |
15.04.2011 21:00
Сообщение
#7
|
Профи Группа: Пользователи Сообщений: 652 Пол: Мужской Реальное имя: Алексей Репутация: 20 |
В общем,я нашел основные ошибки и исправил их.Вышло то,что и получалось у тебя на скринах,volvo.
Я выложу код,который считает an,чтобы можно было сравнить с твоими результатами.
Пока что написано достаточно коряво,много повторений практически идентичных кусков кода. Сообщение отредактировано: Krjuger - 15.04.2011 23:08 |
Krjuger |
17.04.2011 13:07
Сообщение
#8
|
Профи Группа: Пользователи Сообщений: 652 Пол: Мужской Реальное имя: Алексей Репутация: 20 |
Я немного поработал на округлением,а то до этого не совсем корректно выводились данные и в итоге пришел к следующему варианту.
Для точки x1 вроде правильно считает,но с выводом нечто неладное. Volvo,Вы раньше упоминали,что выводить надо с точностью до десятой,я не совсем понял при каких случаях.Например,nxt = -4.5E-02 ,что равно -0.045 при эпсилон 0.0625 при выводе правильно выводить -0.04 или все равно выводить -0.045?Просто как я не крутился,но ответ предстает в виде. Если я хочу вывести все таки -0.045,то тогда у меня у всех чисел начинают появляться по 1 цифре... Следующий вопрос,можно ли как то принудительно заставить выводить через экспоненту,потому что для второго корня числа выводятся не очень красиво. Ну и последний вопрос,можно ли все это как нибудь оптимизировать,потому,что я программе очень много повторяющегося кода,и слишком много на мой взгляд циклов,но как от них избавиться я не знаю. Надеюсь мне все таки ответят. |
Текстовая версия | 28.04.2024 12:41 |