2012-03-28 2 views
1

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

+3

Они ограничены выражениями, но выражения могут иметь в них произвольные функции! –

+2

Вы попадаете в мутные области довольного байтового кода, чтобы заставить его работать, в лучшем случае. –

+1

Вы посмотрели на [SymPy] (http://code.google.com/p/sympy/)? Я бы поспорил, что это может быть лучше подходит для проблемы, это похоже на то, что вы пытаетесь решить. – SingleNegationElimination

ответ

6

Конечно, нет: если лямбда не является injective function, вы не можете ее инвертировать. Пример: вы не можете инвертировать отображение лямбда x в x*x, так как знак оригинала x утерян.

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


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

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

+0

Отредактировано в ответ. Спасибо. –

+0

md5 является инъективным? .. –

+0

@ Keller: Ну, мы также хотим запретить вызовы функций в рассматриваемых лямбдах? В противном случае лямбда могла бы просто вызвать mh5-хэш-расчет. – Vlad

1

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

Это существенно ниже этой стратегии:

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

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