Задача:
Задана функция и ее разложение в ряд. Численно убедиться в справедливости равенства, для чего для заданного значения аргумента [latex]x[/latex] вычислить левую его часть и разложение, стоящее в правой части, с заданной погрешностью [latex]\varepsilon[/latex]. Испытать разложение на сходимость при разных значениях аргумента, оценить скорость сходимости, для чего вывести число итераций [latex]n[/latex].
[latex]\frac{e^x+e^{-x}}{2}=1+\frac{x^2}{2!}+\frac{x^4}{4!}+ … +\frac{x^{2n}}{2n!}+…[/latex]Тесты:
[latex]x[/latex] | [latex]\varepsilon[/latex] | [latex]a[/latex] | [latex]b[/latex] | [latex]n[/latex] | Комментарий |
1 | 0.0001 | 1.54308 | 1.54306 | 3 | Пройден |
1.5 | 0.001 | 2.35241 | 2.35176 | 3 | Пройден |
3 | 0.02 | 10.0677 | 10.0502 | 0 | a=b,Пройден |
10 | 0.3 | 11013.2 | 11012.9 | 12 | Пройден |
Код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <iostream> #include <math.h> int main() { double x, a, e, b=1, z=1; int n=0; cin >> x; cin >> e; a = (exp(x) + exp(-x)) / 2; do{ z*=(x*x)/((2*n + 1)*(2*n + 2)); b+=z; n++; }while(fabs(a-b) > e); cout << a << endl; cout << b << endl; cout << n << endl; return 0; } |
В задаче дана функция и ее разложение. В главной функции задаем аргумент и погрешность. Находим значение функции(левая часть). Дальше нам нужно найти значение разложения(правая часть). Для этого создаем цикл который будет работать пока, разница левой и правой части не станет меньше погрешности. Для этого к правой части прибавляем [latex]\frac{x^{2n}}{2n!}[/latex] до тех пор, пока разница между функцией и разложением не будет меньше погрешности.
Код Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import java.util.*; import java.lang.*; import java.io.*; class Depo { public static void main (String[] args) throws java.lang.Exception { double x, a, e, b=1, z=1; int n=0; Scanner in = new Scanner(System.in); x= in.nextDouble(); e= in.nextDouble(); a=(Math.exp(x)+ Math.exp(-x))/2; do{ z*=(x*x)/((2*n + 1)*(2*n + 2)); b+=z; n++; }while(Math.abs(a-b) > e); System.out.println(a); System.out.println(b); System.out.println(n); } } |
— Вы не дописали до конца формулу в условии — «+…»
— Отступы!
— Все действия с b = a это какой-то странный трюк. Погрешность должна быть положительной. Если это не так ничего считать не нужно.
— А где это всё в отчёте «Испытать разложение на сходимость при разных значениях аргумента, оценить скорость сходимости»?
— То, что Вы считаете называется «косинус гиперболический» — cosh. Напишите об этом в метках отчёта пожалуйста.
Можно не переделывать, но замечание очень важное. Т.е. на оценку это повлияет.
При вычислении суммы ряда Вы для каждого члена ряда полностью вычисляете числитель и отдельно знаменатель. Потом делите. Это приводит к тому что Вы оперируете с огромными числами, а вычисляете (судя по тестам) числа совсем небольшие. Это приводит и к значительным погрешностям и к полной невозможности вычислить члены ряда начиная с некоторого не очень большого значения.
Как поступают в таких случаях? Выражают очередной член ряда через предыдущий. Так, как я объяснял на занятиях. Это позволяет получить относительно удобную рекуррентную формулу.
Код исправлен. Разложение теперь вычисляется по рекуррентной формуле.
Извините, но Вы чепуху какую-то написали.
В начале цикла в 27-28 строке Вы считаете всё по-старому. Потом в 29-39 делаете какие-то рекурсивные манипуляции, которые никак не используются и не влияют на результат. Жаль, что Вы не пришли на лекцию, когда я об этом рассказывал.
Давайте, чтобы я мог зачесть, удалите ненужный кусок кода
k = (x * x) / ((n+1)*(n+2));
z *= k;
и сдвиньте весь цикл влево на своё место.
– Отступы! Здесь можно посмотреть как это делается в цикле do… while
Хорошо.
— Теперь остались тесты. Точность (е) должна быть много меньше чем те величины, которые сравниваются. Если величины порядка 1, то точность должна быть много меньше. Скажем 0.01, или 0.0001, или 1е-12. Вам нужно убедиться, например, что для х=6 левая часть отличается от правой меньше чем 1е-12 после 16-го шага.
— Вы не даёте ссылку на Ваш код в ideone. Это не удобно. Мне пришлось скопировать туда текст программы. Получил массу синтаксических ошибок.
Исправлено
Работает как часы.
Зачтено