Рекурсивная аппроксимация серии Sin Тейлора

#java #recursion #trigonometry #taylor-series

#java #рекурсия #тригонометрия #ряд Тейлора

Вопрос:

Мне нужно некоторое представление о моем рекурсивном методе вычисления ряда sin Тейлора, который не работает должным образом. Метод вызывает два других рекурсивных метода, которые являются рекурсивным методом pow и рекурсивным факториальным методом. Я сравнил свои результаты с итеративным методом sin, который дал мне правильное решение. Чего не хватает в моем рекурсивном методе sin?

Аппроксимация sin(x) = x — x ^ 3/3! x ^ 5/5! -x^7/7! …

 public class SinApprox
    {
        public static void main (String [] args)
        {
            Out.println(sinx(1, 1, 2, 1, 1, 0, 1));
            Out.print(sinIT(2));
        }

    static double sinIT(double x)
    {
        double sin = 0;
        double a = x;
        double b = 1;
        double term = a/b;
        double vz = 1;
        double i = 1;

    while(term > 0.000001)
    {
        i = i  2;
        sin = sin   (term*vz);
        a= rekursivPow(x,i);
        b = rekursivN(i);
        term = a/b;
        vz = -1 * vz;
    }
    return sin;
}

static double rekursivN(double n)
{
    if(n==1)
    {
        return 1;
    }
    return n * rekursivN(n-1);
}

static double rekursivPow(double x , double y)
{
    if(y  == 1)
    {
        return x ;
    }
    return x * rekursivPow(x , y  - 1);
}

static double sinx(double i ,double n, double x, double y, double vz, double sum, double pow)
{


    double term = pow / n;

    if(term > 0.000001)
    {
        sum = sum   (term * vz);
        vz = -1 * vz;
        i = i  2;
        n = rekursivN(i);
        y = y  2;
        pow = rekursivPow(x ,y);

        return sinx(i, n, x , y , vz, sum, pow);
    }
    return sum;


   }
}
  

Комментарии:

1. Вы реализуете это с помощью рекурсии для выполнения домашнего задания? Потому что, если бы вам пришлось на самом деле реализовать это «по-настоящему», нет буквально нулевой причины делать это с рекурсивными вызовами.

2. Да, это домашнее задание, и мне нужно использовать для моего рекурсивного метода sin рекурсивные методы pow и factorial.

Ответ №1:

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

 sin(x)= x - x^3/3!   x^5/5! -x^7/7!  ...
  

Но вместо этого спросите «как я могу заставить все эти термины с x выглядеть одинаково»:

 sin(x)= x^1/1! - x^3/3!   x^5/5!   ...
  

Хорошее начало, но если мы выполняем рекурсию, то на самом деле нам нужно нечто, что только вычисляет один из этих терминов, а затем вызывает себя с обновленными аргументами для вычисления следующего термина. В идеале, мы хотим что-то вроде:

 doThing(args) {
  return simpleComputation()   doThings(updatedargs);
}
  

А затем рекурсия делает все остальное. Итак, давайте сначала убедимся, что нам приходится иметь дело только с вместо сочетания и - :

 sin(x)= (-1)^0 * x^1/1!   (-1)^1 * x^3/3!   (-1)^2 * x^5/5!   ...
  

И теперь у вас есть то, что вы действительно можете выразить как рекурсивное отношение, потому что:

 sin(x,n) {
  return (-1)^n * x^(2n 1) / (2n 1)!   sin(x, n 1);
}
  

С помощью функции «shortcut»:

 sin(x) {
  return sin(x,0); 
}
  

И на этом подсказки заканчиваются, вы должны быть в состоянии реализовать остальное самостоятельно. Пока вы не забудете остановить рекурсию, потому что ряд Тейлора бесконечен, а компьютерные программы и ресурсы — нет.

Комментарии:

1. Но разве это (-1) ^ 0 * x ^ 1/1! не должно быть положительным? -1^ 0 равно -1.

2. Это наверняка не так. -1 ^ 0 определенно 1 (с несколькими объяснениями, все из которых легко найти в Интернете)

3. Моя ошибка, извините

4. Спасибо, это сработало =) Но у меня есть еще один вопрос. Мой метод recursivePow работает только с положительными цифрами. Есть ли у вас какие-либо подсказки, как я могу достичь этого с помощью действительных чисел, например: -0.12 ^ 2?