Есть два способа подойти к этой задаче: численно и символически.
Чтобы решить ее численно, вы должны сначала закодировать ее как "исполняемую" функцию - вставить значение, получить значение. Например,
def my_function(x):
return 2*x + 6
Вполне возможно разобрать строку, чтобы автоматически создать такую функцию; скажем, вы анализируете 2x + 6
в список, [6, 2]
(где индекс списка соответствует степени x - так что 6 * x ^ 0 + 2 * x ^ 1). Затем:
def makePoly(arr):
def fn(x):
return sum(c*x**p for p,c in enumerate(arr))
return fn
my_func = makePoly([6, 2])
my_func(3) # returns 12
Затем вам понадобится другая функция, которая неоднократно подставляет значение x в вашу функцию, смотрит на разницу между результатом и тем, что она хочет найти, и настраивает значение x, чтобы (надеюсь) минимизировать разницу.
def dx(fn, x, delta=0.001):
return (fn(x+delta) - fn(x))/delta
def solve(fn, value, x=0.5, maxtries=1000, maxerr=0.00001):
for tries in xrange(maxtries):
err = fn(x) - value
if abs(err) < maxerr:
return x
slope = dx(fn, x)
x -= err/slope
raise ValueError('no solution found')
Здесь есть много потенциальных проблем - найти хорошее начальное значение x, предполагая, что функция действительно имеет решение (т.е. нет действительных ответов на x ^ 2 + 2 = 0), выходя за пределы вычислительной точности, и т.д. Но в данном случае подходит функция минимизации ошибок и мы получаем хороший результат:
solve(my_func, 16) # returns (x =) 5.000000000000496
Обратите внимание, что это решение не является абсолютно правильным. Если вам нужно, чтобы он был идеальным, или если вы хотите попробовать решить семейства уравнений аналитически, вам придется обратиться к более сложному зверю: символьному решателю.
Символьный решатель, такой как Mathematica или Maple, представляет собой экспертную систему с множеством встроенных правил («знаний») об алгебре, исчислении и т. д.; он «знает», что производная sin равна cos, что производная kx^p равна kpx^(p-1) и так далее. Когда вы даете ему уравнение, оно пытается найти путь, набор правил-приложений, от того места, где оно находится (уравнение), до того места, где вы хотите быть (самая простая возможная форма уравнения, которая, надеюсь, является решением). .
Ваше примерное уравнение довольно простое; символическое решение может выглядеть так:
=> LHS([6, 2]) RHS([16])
# rule: pull all coefficients into LHS
LHS, RHS = [lh-rh for lh,rh in izip_longest(LHS, RHS, 0)], [0]
=> LHS([-10,2]) RHS([0])
# rule: solve first-degree poly
if RHS==[0] and len(LHS)==2:
LHS, RHS = [0,1], [-LHS[0]/LHS[1]]
=> LHS([0,1]) RHS([5])
и вот ваше решение: x = 5.
Я надеюсь, что это дает аромат идеи; детали реализации (нахождение хорошего, полного набора правил и принятие решения о том, когда следует применять каждое правило) могут легко потребовать многих человеко-лет усилий.
person
Hugh Bothwell
schedule
08.05.2012
solve y = mx + c for x
? - person Li-aung Yip   schedule 08.05.2012maxima
илиMathematica
, но я не думаю, что это является целью. - person Li-aung Yip   schedule 08.05.2012