Rozwinięcie funkcji w szereg Taylora

0

Witam, proszę o pomoc w znalezieniu rozwiązania poniższego zadania:
Napisz program tablicujący (rozwinięcie w szereg Taylora) funkcje f(x) w zadanym przedziale z zadaną liczbą podprzedziałów. Program powinien wyświetlać wartość funkcji z biblioteki matematycznej i oszacowanej w rozwinięciu
screenshot-20201114153735.png

mój kod wraz z przykładowym wynikiem
screenshot-20201114154006.png
będę wdzięczny za pomoc i wskazówki

2

No to tak, wybiorę sobie może jeden przypadek, a Ty spróbujesz zrobić drugi. Wybieram

f(x) = (1 + x) ^ (1/3)

Drugi przypadek jest analogiczny, doprowadzisz go sobie do porządku sam.

#include <assert.h>

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_ITER 4000

double
szereg(double x, int iterations)
{
	double coeff = 1.0;
	double result = 1.0;
	int ii;

	/*
	 * For |x| <= 1.0:
	 *                  +inf
	 *                  __
	 *  sqrt3(1 + x) ~= \    n ( 1/3 )
	 *                  /_  x  (  n  )
	 *                  n=0
	 */

	for (ii = 1; fabs(coeff) > 1e-48 && ii < iterations; ii++) {
		coeff *= (1.0 / 3.0 - (double)(ii - 1)) / (double)ii * x;
		result += coeff;
	}
	return (result);
}

int
main()
{
	int lp;
	double a, b, step, x;

	scanf("%lf %lf %d", &a, &b, &lp);

	step = (b - a) / (double)lp;

	for (x = a; x <= b; x += step) {
		const double v1 = szereg(x, MAX_ITER);
		const double v2 = pow(1.0 + x, 1.0 / 3.0);

		printf("%lf %.07lf %.07lf %.032lf\n", x, v1, v2, fabs(v1 - v2));
	}
}

Dla wartości x bliskich -1 cała zabawa się wywala, bo w sumie samo przybliżenie Taylorem tej funkcji jest trochę słabe w tej okolicy. Spróbuj ogarnąć sam przypadek dla f(x) = (1 - x)^(1/3).

2

Problemem jest matematyka!
Każdy szereg, ma coś takiego jak promień zbieżności, czyli odległość od środka, w które suma szeregu jest skończona i w której szeregu Taylora potrafi odtworzyć funkcję analityczną.
Szkolny przykład suma ciągu szeregu geometrycznego jest skończona, tak długo jak wartość bezwzględna q jest mniejsza niż 1.
Tak akurat się składa, że ten szereg jest asymptotycznie podobny do szeregu geometrycznego, więc jego promień zbieżności wynosi 1.

Dlatego właśnie musisz liczyć wartości w zakresie (-1, 1).
Dla samej wartości 1 szereg jest rozbieżny!

Teraz im bardziej zbliżasz się do granicy zbieżności szeregu, tym więcej elementów szeregu trzeba zsumować, by uzyskać prawidłowy wynik.

Demo za pomocą testów i szereg liczony sprytniej (nie stała liczba elementów, ale sumuj tak długo jak zmienia się wynik):
https://godbolt.org/z/39fvs7

double taylor(double x) {
    double a = x / 3.0;
    double r = 1.0 + a;
    constexpr auto epsilon = std::numeric_limits<double>::epsilon();

    for (int i = 2; std::abs(r) * epsilon < std::abs(a); ++i) {
        a *= -(3 * i - 4) * x / (3 * i);
        r += a;
    }

    return r;
}
0

@kapojot: Dziękuję za pomoc udało mi się napisać program.

0

@MarekR22: Również dziękuję za pomoc program działa a problem z dziedziną muszę skonsultować z profesorem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1