Функция python находит корень (или ноль) с минимальным расстоянием от реального корня эпсилон

Так что и упражнения для python я полностью застрял! у вас есть случайная функция в [a,b], вы уже знаете, что a отрицательно, а b положительно и имеет только ОДИН корень. Истинный корень: -0,94564927392359, и вам нужно сделать определение, которое найдет корень (или ноль), который будет ближе всего к истинному корню с минимальной разницей eps. eps — это 1e-8 или 1e-6. Обратите внимание, что мы не знаем истинный корень, ранее был пример, чтобы понять, какое число мы ищем. о. Также нам дано выше:

import math

def fnc(x):
    """ This the function in which root we are looking for """
    global a, b, eps
    if not hasattr(fnc, "counter"):
        fnc.counter = 0
        fnc.maxtimes = (int)(0.1+math.ceil(math.log((b-a)/eps, 2.0)+2))
    if fnc.counter<fnc.maxtimes:
        fnc.counter += 1
        return x*x*x-x-0.1 
    else:
        return 0.0 ##

МЫ должны начать с этого:

def root(f, a, b, eps):

(Извините за мой английский )


person Dora    schedule 17.05.2015    source источник
comment
Я не думаю, что это возможно без какого-либо дополнительного условия (например, [[Липшицева непрерывность]](en. wikipedia.org/wiki/Lipschitz_continuity).   -  person Ami Tavory    schedule 17.05.2015
comment
@AmiTavory Я считаю, что ОП опубликовал домашнее задание из курса базового численного анализа.   -  person Alik    schedule 17.05.2015


Ответы (2)


Просто биссектриса:

from __future__ import division
import math

def func(x):
    return x*x*x-x-0.1

def sign(n):
    try:
        return n/abs(n)
    except ZeroDivisionError:
        return 0

def root(f, a, b, eps=1e-6):
    f_a = f(a)
    if abs(f_a) < eps:
        return a
    f_b = f(b)
    if abs(f_b) < eps:
        return b

    half = (b+a)/2
    f_half = f(half)

    if sign(f_half) != sign(f_a):
        return root(f, a, half, eps)
    else:
        return root(f, half, b, eps)

print root(func, -1.5, -0.5, 1e-8)  # -0.945649273694
person Łukasz Rogalski    schedule 17.05.2015

Посмотрите, подходит ли вам следующая эвристика итеративного разделения интервалов на 2 равных, а затем выбор допустимой половины.

def root(fnc, a, b, eps = 1e-8, maxtimes = None):
    if maxtimes == None: maxtimes = (int)(0.1+math.ceil(math.log((b-a)/eps, 2.0)+2))
    for counter in xrange(maxtimes+1) : # a was assumed negative and b positive
        if fnc(a) > -eps : return a, -fnc(a)
        if fnc(b) < eps : return b, fnc(b)
        new_bound = (a + b)/2.0
        print a, b, new_bound
        if fnc(new_bound) < 0 : a = new_bound
        else : b = new_bound
    return new_bound, min(-fnc(a),fnc(b))

а потом

fnc = lambda x : x**3-x-0.1
result = root(fnc, 0, 2, 1e-6)
print "root = ", result[0], "error = ", result[1]
person donbunkito    schedule 17.05.2015