Функция поиска корня для верхних и нижних пересечений оси X - PullRequest
0 голосов
/ 28 марта 2019

Мне нужно найти нижнее и верхнее пересечения с осью X кривой, заданной

y=f(x)=10⋅exp(sin(x))−(x^2)/2

Чтобы найти длину дуги кривой, в Python

Я уже попробовал два метода, секущий метод, который я не могу заставить работать вообще. И метод Ньютона, который находит одно пересечение.

from math import exp 
from math import sin
from math import cos

def func( x ): 
    return 10*exp(sin(x))-(x**2)/2

def derivFunc( x ): 
    return 10*exp(sin(x))*cos(x)-x

def newtonRaphson( x ): 
    h = func(x) / derivFunc(x) 
    while abs(h) >= 0.0001: 
        h = func(x)/derivFunc(x) 

        x = x - h 

    print("The value of the root is : ", 
                             "%.4f"% x) 


x0 = -20 
newtonRaphson(x0) 

, что дает

The value of the root is :  -5.7546

Тогда второй метод

import math 
from math import exp 
from math import sin


def f(x):

    f = 10*exp(sin(x))-(x**2)/2
    return f; 

def secant(x1, x2, E):
    n = 0; xm = 0; x0 = 0; c = 0;
    if (f(x1) * f(x2) < 0):
        while True:
            x0 = ((x1 * f(x2) - x2 * f(x1)) /(f(x2) - f(x1)));
            c = f(x1) * f(x0);
x1 = x2;
x2 = x0;
n += 1;
if (c == 0): 
    xm = ((x1 * f(x2) - x2 * f(x1)) /(f(x2) - f(x1)));
if(abs(xm - x0) < E):
    print("Root of the given equation =",round(x0, 6));
    print("No. of iterations = ", n); 
    print("Can not find a root in ","the given inteval"); 
x1 = 0; x2 = 1;
E = 0.0001;
secant(x1, x2, E);             

Только результаты

NameError: name 'x2' is not defined

Тем не менее, когда бы я ни пытался определить символы, он не запускался

Я хотел бы иметь возможность получить верхнее и нижнее пересечения с осью X, чтобы я мог найти длину дуги. И есть ли способ заставить его построить график также

1 Ответ

1 голос
/ 29 марта 2019

О методе Ньютона-Рафсона:

Нормальное поведение

Работает в основном так, как задумано.Метод может сходиться только к одному корню, который зависит от начальной точки.Чтобы получить другой корень, вам нужна другая начальная точка.

Ваша функция выдает:

>>> newtonRaphson(-20)
-5.7545790362989
>>> newtonRaphson(5)
3.594007784799419

Что кажется правильным.

Ошибки

Метод Ньютона-Рафсона не гарантированно сходится, он может войти в цикл ifinite, в этом случае ваша программа зависнет на неопределенное время, или производная в точке может быть нулевой, и в этом случае вы не можетевычислить h.Вам нужно разобраться с этими случаями.

Стиль

Есть много вещей, которые могут быть доказаны:

  • Ошибка должна бытьисправлено
  • В настоящее время метод Ньютона-Рафсона работает только для одной функции.Вы должны передать функцию и производную в качестве аргументов, чтобы можно было применить метод к любой функции, которую вы хотите.
  • Желаемую точность и максимальные итерации можно также передавать в качестве аргументов
  • Это плохая практикапечать в функции.Вместо этого вы должны вернуть значение, чтобы вы могли решить, что делать с результатом.
  • Вы должны следовать рекомендациям PEP8 по стилю
  • включить строку документации, если вы планируете использовать ее повторно (что вполне возможноэто очень полезный инструмент!)

Мой взгляд на метод:

def newton_raphson(f, df, x, epsilon = 0.0001, maxiter = 1000): 
    """ Estimates the root of a function.

    Gives an estimate to the required precision of a root of the given function
    using the Newton-Raphson method.

    Raises an Exception if the Newton-Raphson method doesn't converge in the
    specified number of iterations.
    Raises a ZeroDivisionError if the derivative is zero at a calculated point

    :param f: The function 
    :param df: The function's derivative
    :param x: the starting point for the method
    :param epsilon: The desired precision
    :param maxiter: The maximum number of iterations

    :return: The root extimate
    :rtype: float
    """

    for _ in range(maxiter):
        h = f(x)/df(x) 
        if abs(h) < epsilon:
            return x
        x = x - h 

    raise Exception("Newton Raphson method didn't "
                    + "converge in {} iterations".format(maxiter))

Использование:

>>> print(newton_raphson(func, derivFunc, 20))
-5.7545790362989
>>> print(newton_raphson(func, derivFunc, 5, 0.1, 100))
3.5837828560043477
>>> print(newton_raphson(func, derivFunc, 5, 0.001, 100))
3.594007784799419
>>> print(newton_raphson(func, derivFunc, 5, 1e-9, 4))
Traceback (most recent call last):
(...)
Exception: Newton Raphson method didn't converge in 4 iterations

О секантеМетод:

Я не настолько знаком с этим, поэтому я просто упомяну вашу ошибку из-за плохой идентификации.Здесь это исправлено:

def secant(x1, x2, E):
    n = 0; xm = 0; x0 = 0; c = 0;
    if (f(x1) * f(x2) < 0):
        while True:
            x0 = ((x1 * f(x2) - x2 * f(x1)) /(f(x2) - f(x1)));
            c = f(x1) * f(x0);
    x1 = x2;
    x2 = x0;
    n += 1;
    if (c == 0): 
        xm = ((x1 * f(x2) - x2 * f(x1)) /(f(x2) - f(x1)));
    if(abs(xm - x0) < E):
        print("Root of the given equation =",round(x0, 6));
        print("No. of iterations = ", n); 
    print("Can not find a root in ","the given inteval"); 

Если вы планируете продолжать реализацию этого метода, замечания по поводу метода Ньютона-Рафсона по-прежнему сохраняются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...