Как решить многомерное неравенство с помощью python и sympy?

Я новичок в использовании python и Sympy... И у меня возникла проблема с решением многомерных неравенств с использованием sympy.

Допустим, у меня есть много функций в файле, который выглядит так:

    cst**(sqrt(x)/2)/cst
    exp(sqrt(cst*x**(1/4)))
    log(log(sqrt(cst + exp(x))))
    (y**(1/4) + y)**cst
    sqrt(y/log(x))/cst
    sqrt(cst**log(cst) + x)
    (y**2)**(x/4)
    sqrt(y*sqrt(cst**y))
    log(sqrt(2)*sqrt(cst)*x)

Мне нужно вывести их, установить значение константы и проверить, если для каждой функции f

    df/dx > 0
    df/dy < 0 

С х в ​​[0, +оо) и у в [0, 1].

Для получения я использую:

    dx = diff(f, x)
    dy = diff(f, y)

Затем, когда я пытаюсь:

    cst = 2 #(for example) 
    solve(dx > 0) 

Я получил эту ошибку:

    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/local/lib/python2.7/dist-packages/sympy/solvers/solvers.py", line 634, in solve
symbols=symbols)
    File "/usr/local/lib/python2.7/dist-packages/sympy/solvers/inequalities.py", line 374, in reduce_inequalities
    raise NotImplementedError("only univariate inequalities are supported")
    NotImplementedError: only univariate inequalities are supported

Но если я попробую это:

    x=Symbol('x', real=True, postive=True, nonzero=True)
    y=Symbol('y', real=True, postive=True, nonzero=True)
    solve(x**2+y > 0)

Я получил :

    True

Это хороший и рабочий ответ. Можно ли как-то решить многомерное неравенство и всегда получить работоспособный ответ?

Например, я хотел бы получить: решить (x ** 2-y> 0) или (x> -sqrt (y), x> sqrt (y))


person sloan    schedule 11.06.2013    source источник
comment
Добро пожаловать! Не забывайте, что этикет здесь заключается в том, чтобы объяснить, что вы пробовали и почему это не сработало, задавая вопросы.   -  person Krastanov    schedule 11.06.2013
comment
Айе, я не забуду в следующий раз! Я попробовал тот же код, что и вы... И получил тот же ответ: NotImplementedError.   -  person sloan    schedule 11.06.2013


Ответы (2)


При попытке решить эту проблему с помощью SymPy вы получаете довольно четкое сообщение об ошибке: NotImplementedError: only univariate inequalities are supported. Имейте в виду, что это означает, что команда SymPy будет очень рада, если вы предложите алгоритм, решающий эту проблему.

Теперь, когда стало ясно, что sympy.solve недостаточно мощен, можно попробовать другой подход. Недавно (в версии 0.7.2) в sympy была добавлена ​​процедура неявного построения графика, которая может отображать, где выражение оценивается как True. К сожалению, это только числовое решение, а не символическое, которое вы можете получить от solve, но этого может быть достаточно:

введите здесь описание изображения

На изображении видно, что есть только одна строка, где выражение меняет знак, поэтому решение для expr==0 может дать вам то, что вы хотите. И это действительно так:

введите здесь описание изображения

person Krastanov    schedule 11.06.2013
comment
Спасибо за ответ, но это не годится для того, что мне нужно. Я должен сгенерировать все возможные функции f(x,y), например, с 10 символами, а затем оценить все производные, чтобы проверить, если: df/dx > 0 и df/dy ‹ 0. Есть много возможностей, чтобы иметь возможность проверить все сам... Есть идеи по этому поводу? - person sloan; 11.06.2013
comment
Я действительно не понимаю, как то, что вы спрашиваете в комментарии, каким-либо образом связано с тем, что вы задали в вопросе выше? Не стесняйтесь задавать новый вопрос или, если вы настаиваете, изменить исходный вопрос, чтобы было ясно, чего вы хотите. Проголосуйте, если найдете ответ полезным. - person Krastanov; 11.06.2013
comment
Отличный и исчерпывающий ответ. Объяснение помогло мне с расчетом распределения ядра по теории игр. - person hobs; 11.12.2013

В mystic есть многомерный решатель неравенства, который построен поверх sympy. Он использует оптимизацию и (математическое) сопоставление наборов, чтобы обеспечить эту функцию. Это не идеально, но работает во многих случаях.

>>> equations = '''
... 2*A + 3*B >= C
... A*B > D
... C < 4*A    
... D == 0
... '''
>>> 
>>> import mystic.symbolic as ms
>>> var = list('ABCD')
>>> eqns = ms.simplify(equations, variables=var)
>>> print eqns
D == 0
B > 0
A > C/4
A >= -3*B/2 + C/2
A > D/B
>>> 
>>> # generate a constraints function, which maps one space to another
>>> constrain = ms.generate_constraint(ms.generate_solvers(eqns, var))
>>> solution = constrain([1,2,3,4])
>>> print solution
[1, 2, 3, 0] 
>>> # here's the solution...
>>> dict(zip(var,solution))
{'A': 1, 'C': 3, 'B': 2, 'D': 0}
>>>
>>> A=1; C=3; B=2; D=0
>>> 2*A + 3*B >= C
True
>>> A*B > D
True
>>> C < 4*A
True
>>> D == 0
True
>>> 

Давайте сделаем это снова, с предложенным тестом:

>>> equations = """x**2 - y >= 0
... x + y = 0
... """
>>> eqns = ms.simplify(equations, variables=var)
>>> constrain = ms.generate_constraint(ms.generate_solvers(eqns, var))
>>> solution = constrain([1,3])
>>> solution
[-3, 3]
>>> dict(zip(var, solution))
{'y': 3, 'x': -3}
>>> y=3; x=-3
>>> x**2 - y >= 0
True
>>> x+y == 0
True
>>>

mystic использует комбинацию sympy и численной оптимизации для упрощения неравенств; и при представлении исходного решения предположения может (в большинстве случаев, но не всегда) генерировать действительное решение уравнений. mystic на самом деле не решает неравенства как таковые, но (обычно) генерирует правильное решение неравенств.

person Mike McKerns    schedule 30.09.2015