Я работаю над методом вычисления пределов функции в Python, но некоторые функции выдают неверный вывод. Моя главная цель - вычислить производные, но для этого я должен вычислить предел функции.
Это для личного проекта, я бы не хотел, чтобы модуль решал лимит или искал алгоритм в Википедии. Я пытался использовать следующий метод:
- Я создаю список со значениями f (x), очень близкими к значению, которое стремится к x
- Код анализирует, какое значение больше всего повторяется в этом списке, и делается вывод, что это значение является пределом функции f (x), стремящейся к x.
Этот метод явно антиматематический, но я не мог придумать лучшего решения. Я пытался применить меры централизации, но я не думаю, что это работает для периодической непрерывной дроби, как 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
# ammount 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 были неправильными. Среди них:
- Ввод 1: Упражнение 1, элемент m)
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']
- Ввод 2: Упражнение 1, пункт p)
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']
- Ввод 3: Упражнение 1, элемент u)
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']
- Ввод 4: Упражнение 1, элемент z)
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']
- Ввод 5: Упражнение 3, пункт а)
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']
Следовательно, как лучше всего проверить, к какому значению подходят элементы списка?