Можно ли инвертировать произвольную лямбду в Python? - PullRequest
1 голос
/ 29 марта 2012

В последнее время я играл с Python и математикой, и столкнулся с чем-то, что мне еще предстоит выяснить.А именно, возможно ли при произвольной лямбде вернуть обратное значение этой лямбды для математических операций?То есть, invertLambda такой, что invertLambda (lambda x: (x + 2)) (2) = 0. Тот факт, что лямбда-выражения ограничены выражениями, вселяет надежду, но пока я не смог заставить его работатьЯ понимаю, что любой результат может иметь проблемы с функциями, которые теряют информацию, но я готов ограничить пользователей и себя функциями без потерь, если мне придется.

Ответы [ 2 ]

6 голосов
/ 29 марта 2012

Конечно, нет: если лямбда не является инъективной функцией , вы не можете ее инвертировать.Пример: вы не можете инвертировать лямбда-отображение x в x*x, поскольку знак оригинала x потерян.

Если оставить в стороне инъективность, существуют функции, которые в вычислительном отношении очень сложны для инвертирования.Рассмотрим, например, восстановление исходного значения из хеша md5.(Для лямбда-вычисления хеша md5, инвертированная функция должна сломать md5 в криптологическом смысле!)


Редактировать:
действительно, мы можем теоретически сделать лямбда-преобразование обратимым, если мы ограничим выражения, которые можно использовать там,Например, если лямбда является линейной функцией от 1 аргумента, мы можем легко ее инвертировать.Если это полином степени> 4, у нас есть проблема с алгебраически точным решением.

Конечно, мы могли бы воздержаться от точного решения и просто инвертировать функцию численно .Это возможно при использовании любого метода численного решения уравнения lambda(x) = value (простейшим будет бинарный поиск).

1 голос
/ 31 октября 2016

Я немного опоздал, но я только что опубликовал пакет python, который делает это точно. Вы можете заимствовать некоторые идеи из этого: https://pypi.python.org/pypi/pynverse

По сути, следует этой стратегии:

  1. Выясните, увеличивается или уменьшается функция. Для этого необходимы две опорные точки ref1 и ref2:
    • В случае конечного интервала, точки опорных точек составляют 1/4 и 3/4 через интервал.
    • В бесконечном интервале любые два значения действительно работают.
    • Если f (ref1)
  2. Определить изображение функции в интервале.
    • Если указаны значения, то они используются.
    • В закрытом интервале просто вычислите f (a) и f (b), где a и b - концы интервала.
    • В открытом интервале попытайтесь вычислить f (a) и f (b), если это работает, они используются, в противном случае оно будет считаться (-Inf, Inf).
  3. Построена ограниченная функция со следующими условиями:
    • return -Inf, если x ниже интервала, а f увеличивается.
    • return + Inf, если x меньше интервала, а f уменьшается.
    • return + Inf, если x превышает интервал, а f увеличивается.
    • return -Inf, если x превышает интервал, а f уменьшается.
    • вернуть f (x) в противном случае
  4. Если требуемое число y0 для инверсии находится за пределами изображения, вызвать исключение.
  5. Найдите корни для bounded_f (x) -y0, минимизируя (bounded_f (x) -y0) ** 2, используя метод Brent, убедившись, что алгоритм минимизации начинается в точке внутри исходного интервала с помощью установка ref1, ref2 в скобках. Как только он выходит за допустимые интервалы, bounded_f возвращает бесконечность, заставляя алгоритм вернуться к поиску внутри интервала.
  6. Проверьте, чтобы решения были точными и соответствовали f (x0) = y0 с некоторой требуемой точностью, в противном случае выдается предупреждение.

Конечно, как указал Влад, функция должна быть обратимой, чтобы существовало обратное, а также непрерывной в области, чтобы это работало.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...