Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Исследовать алгоритм вычисления функции

Радмир Шихов Ученик (120), закрыт 6 месяцев назад
Лучший ответ
Николай Веселуха Высший разум (362839) 8 месяцев назад
Ареатангенс. Разложение в ряд на C++
 #include   
#include

using namespace std;

double argument(const char* msg) {
static constexpr auto lim = 1.0;
auto value = lim;
while (lim <= fabs(value)) {
cout << msg;
cin >> value;
cin.ignore(0x1000, '\n');
}
return value;
}

double power(const double x, unsigned n) {
auto product = 1.0;
for (auto i = 0U; i < n; ++i) product *= x;
return product;
}

double arthx(const double x) {
static constexpr auto eps = 1e-16;
auto previous = 0.0;
auto member = x;
auto sum = member;
auto n = 1U;
while (eps < fabs(member - previous)) {
n += 2;
previous = member;
member = power(x, n) / n;
sum += member;
}
return sum;
}

double control(const double x) {
return log((1.0 + x) / (1.0 - x)) / 2.0;
}

int main() {
const auto x = argument("x: ");
const auto ctrl = control(x);
cout.setf(ios::fixed);
cout.precision(15);
cout << "result: " << arthx(x) << '\n';
cout << "control: " << control(x) << '\n';
}
Остальные ответы
Василиск Мастер (1736) 8 месяцев назад
Ряды Тейлора и Маклорена тебе в помощь. Там ниче сложного, просто взять несколько производных
Вячеслав Мыслитель (6486) 8 месяцев назад
Данный ряд Маклорена хорошо сходится при |x|<1, только при |x|≈1 надо брать большое число слагаемых. И чем ближе |x| к единице, тем большее количество слагаемых требуется учитывать, время при этом расходуется тоже всё больше и больше, а точность вычислений значительно снижается.
Вычисление суммы ряда можно организовать по разному. Например так, как в предыдущем ответе, то есть глупо и нерационально. Воспользовавшись модулем <chrono>, модифицируем основную функцию из предыдущего ответа следующим образом:
 int main() {  for (;;) { 
const auto x = argument("x: ");
const auto ctrl = control(x);
auto start = chrono::system_clock::now();
cout.setf(ios::fixed);
cout.precision(15);
cout << "result: " << arthx(x) << '\n';
cout << "control: " << control(x) << '\n';
auto end = chrono::system_clock::now();
chrono::duration elapsed_seconds = end - start;
cout << elapsed_seconds.count() << " seconds" << endl; }
}
Запускаем код и начинаем вычислять:При |х|=0,9999 сумма ряда у меня на смартфоне вычисляется почти минуту, а при |х|=0,99999 - порядка часа, что, конечно же, совершенно неприемлемо, но такова плата за глупость! В остальном же код вполне работоспособный.
Теперь рационализуем вычисления. У первого члена ряда в числителе х, а в знаменателе 1, у каждого последующего члена ряда числитель больше в х² раз, а знаменатель на 2 больше чем у предыдущего. Вот этим и воспользуемся:
 #include  
#include
#include
using namespace std;
int main()
{
double e, p, s, q, x, xx, y, Y;
while (true)
{
cout << "x » "; cin >> x;
cout.precision(16);
auto start = chrono::system_clock::now();
xx = x * x; e = p = q = y = 1.;
while (e > 1e-17)
{ q += 2.; p *= xx; e = p / q; y += e; }
y *= x;
auto end = chrono::system_clock::now();
chrono::duration elapsed_seconds = end - start;
Y = 0.5 * log((1. + x) / (1. - x));
cout << y << '\n' << Y << "\nAbsolute error: "
<< y - Y << "\nRelative error: " << y / Y - 1. <<
"\nNumber of terms taken in the series: " <<
(unsigned long long)((q - 1.) * 0.5) << endl;
cout.precision(8);
cout << elapsed_seconds.count() << " seconds" << endl;
}
}
ВячеславМыслитель (6486) 8 месяцев назад
Все вычисления выполнялись на том же устройстве, что и в предыдущем случае и сразу видно, что так сумма ряда вычисляется гораздо быстрее, потому что алгоритм более толковый, благодаря более рациональной схеме расчёта.
А кроме количества слагаемых, взятых для вычисления суммы ряда, получаемой точности в сравнении с эталонной функцией и времени работы программы тут и анализировать больше нечего...
Похожие вопросы