#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?