首页 > 解决方案 > 检查列表元素接近什么值的最佳方法是什么?

问题描述

我正在研究一种在 Python 中计算函数限制的方法,但某些函数给出的输出不正确。我的主要目标是计算导数,但为此,我必须计算函数的极限。

这是一个个人项目,我不想要一个模块来解决限制,或者在维基百科上搜索一个算法。我尝试使用以下方法:

这种方法显然是反数学的,但我想不出更好的解决方案。我尝试应用集中化措施,但我认为它不适用于周期性连分数,例如 2/7。

这是我的代码:

# this function resolves a numerical expression
# using eval function from Python

def Solve(Str):
    if '^' in Str:
        Str = Str.replace('^', '**')
    return eval(Str)


# this function solves a mathematical function by substituting x
# for a value passed by parameter and returning its result

def SolveF(f, x, var = 'x'):
    f = f.replace(' ', '')

    # inserts a multiplication sign between numbers
    # example: 5x --> 5*x

    f = list(f)
    i = 0
    while i < len(f)-1:
        L = f[i:i+2]
        if L[0] in '0123456789' and L[1] == var:
            f.insert(i+1, '*')
        i += 1
    f = ''.join(f)

    f = f.replace(var, '(' + var + ')')
    f = f.replace(var, str(x))

    return Solve(f)


# this function returns f(x) for a value very close
# to the value at which x tends. for example, if x
# tends to 5, it returns f(5.0000000000001). the tiny
# amount that is added to x is 10^(-13) (arbitrary value)

def Lim(f, x, c = 13):
    return SolveF(f, x + (10**(-c)))


# this function returns several f(x) in a list to values
# very close to the value at which x tends. for example,
# if x tends to 0, it will add the list f(0.001), f(0.000001),
# f(0.0000001), ..., f(0.0000000001). then returns the value
# that most repeats in that list, which is supposed to be the
# value whose function is approaching.

def LimM(f, x):
    i = 0
    L = []
    for i in range(5, 20):
        try:
            L.append("{:.10f}".format(Lim(f, x, i)))
        except ZeroDivisionError:
            i += 1
            continue

    print(L)
    List2 = [L.count(i) for i in set(L)]
    if List2 == [1]*len(List2):
        return 'inf'
    else:
        return list(set(L))[List2.index(max(List2))]

from fractions import Fraction
while True:
    F = input('Function: ')
    X = float(input('x --> '))
    Res = LimM(F, X)
    if Res != 'inf':
            print(Fraction(Res).limit_denominator())
    else:
        print(Res)

示例 1:函数(x^2 - 4)/(x - 2)正在逼近x = 2.

LimM 函数生成的列表等于['4.0000100000', '4.0000010001', '4.0000000977', '4.0000000000', '4.0000000000', '4.0000000000', '4.0000000000', '4.0000000000', '4.0000000000', '4.0000000000', '4.0000000000']

请注意,列表中重复次数最多的值是'4.0000000000',因此限制等于 4。

示例 2:函数((x + 1)/(x - 1)正在逼近x = 2.

LimM 函数生成的列表等于['2.9999800002', '2.9999980000', '2.9999998000', '2.9999999800', '2.9999999980', '2.9999999998', '3.0000000000', '3.0000000000', '3.0000000000', '3.0000000000', '3.0000000000', '3.0000000000', '3.0000000000', '3.0000000000', '3.0000000000']

请注意,列表中重复次数最多的值是'3.0000000000',因此限制等于 3。

我测试了 28 个不同的限制(你可以在这里查看问题),只有 6 个是不正确的。其中有:

Function: (1/(1-x)) - (3/(1-x^3))
x --> 1

    Right answer: -1
    Code output: 0

生成的列表:['-0.9999930434', '-1.0000138859', '-0.9992006216', '-0.7401486933', '0.0000000000', '0.0000000000', '0.0000000000', '0.0000000000', '0.0000000000', '0.0000000000', '0.0000000000']

Function: (3x^4 - 4x^3 + 1)/(x - 1)^2
x --> 1

    Right answer: 6
    Code output: 0

生成的列表:['6.0000848733', '6.0000893153', '5.9952043260', '8.8817843050', '0.0000000000', '0.0000000000', '0.0000000000', '0.0000000000', '0.0000000000', '0.0000000000', '0.0000000000']

Function: (x^2 + 7x - 44)/(x^2 - 6x + 8)
x --> 4

    Right answer: 15/2
    Code output: 4222/563

生成的列表:['7.4999675007', '7.4999967484', '7.4999995648', '7.4999992895', '7.4999982236', '7.4999911182', '7.4991119005', '7.4991119005', '7.5714285714', '6.6666666667']

Function: (1/(x^2 - 1)) - (2/(x^4 - 1))
x --> 1

    Right answer: 1/2
    Code output: 0

生成的列表:['0.4999950374', '0.4999879392', '0.4996002605', '0.8326672688', '0.0000000000', '0.0000000000', '0.0000000000', '0.0000000000', '0.0000000000', '0.0000000000', '0.0000000000']

Function: ((1 + 2x)^(0.5) - 1)/(3x)
x --> 0

    Right answer: 1/3
    Code output: 0

生成的列表:['0.3333316667', '0.3333331667', '0.3333333165', '0.3333333313', '0.3333332869', '0.3333333609', '0.3333333609', '0.3332889520', '0.3330669074', '0.3330669074', '0.2960594732', '0.0000000000', '0.0000000000', '0.0000000000', '0.0000000000']

因此,检查列表元素接近什么值的最佳方法是什么?

标签: pythonmathstatisticscalculus

解决方案


只取最后一个值。这是您将获得的最佳近似值。

更高级别的算法改进:甚至不用费心计算列表的其他元素。只需取一个差异很小的差商,并将其用作计算的导数。

这当然不会完全可靠,但这是您选择的方法的一个不可避免的问题。根本不可能通过查看您想要获取限制的附近有限数量的点来计算限制。


推荐阅读