Компьютерная алгебра для Clojure

Краткая версия: Меня интересует некоторый код Clojure, который позволит мне указать преобразования x (например, перестановки, вращения), при которых значение функции f (x) инвариантно, так что я могу эффективно генерировать последовательность x, которая удовлетворяют г =/(х). Есть ли какое-то развитие в компьютерной алгебре для Clojure? Для (тривиального) примера

(defn #^{:domain #{3 4 7} 
         :range #{0,1,2}
         :invariance-group :full} 
          f [x]  (- x x))

Я мог бы позвонить (preimage f # {0}), и он будет эффективно возвращать # {3 4 7}. Естественно, он также мог бы правильно кодировать кодомену. Любые предложения?

Более длинная версия: У меня есть определенная проблема, которая заставляет меня задуматься о разработке компьютерной алгебры для Clojure. Может ли кто-нибудь указать мне на такой проект? Моя конкретная проблема заключается в поиске всех комбинаций слов, которые удовлетворяют F (x) = r, где F - функция ранжирования, а r - целое положительное число. В моем конкретном случае f можно вычислить как сумму

F (x) = f (x [0]) + f (x [1]) +... f (x [N-1])

Кроме того, у меня есть набор непересекающихся множеств S = {s_i}, таких, что f (a) = f (b) для a, b в s, s в S. Итак, стратегия генерации всех x такая, что F x) = r следует полагаться на эту факторизацию F и инвариантность f при каждом s_i. В словах я вычисляю все перестановки сайтов, содержащих элементы S, которые суммируют по r и составляют их со всеми комбинациями элементов в каждом s_i. Это делается довольно небрежно в следующем:

(use 'clojure.contrib.combinatorics)
(use 'clojure.contrib.seq-utils)


(defn expand-counter [c]
 (flatten (for [m c] (let [x (m 0) y (m 1)] (repeat y x)))))

(defn partition-by-rank-sum [A N f r]
  (let [M (group-by f A)
    image-A (set (keys M))
    ;integer-partition computes restricted integer partitions,
    ;returning a multiset as key value pairs
    rank-partitions (integer-partition r (disj image-A 0))
    ]
    (apply concat (for [part rank-partitions]
        (let [k (- N (reduce + (vals part)))
          rank-map (if (pos? k) (assoc part 0 k) part) 
          all-buckets (lex-permutations (expand-counter rank-map))
          ]
          (apply concat (for [bucket all-buckets]
        (let [val-bucket (map M bucket)
              filled-buckets (apply cartesian-product val-bucket)]
          (map vec filled-buckets)))))))))

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

Ответы

Ответ 1

Там Clojuratica, интерфейс между Clojure и Mathematica:

http://clojuratica.weebly.com/

См. также почтовый список автором Clojuratica.

Пока не CAS, Incanter также имеет несколько очень приятных функций и может быть хорошей ссылкой/основой для создания собственных идей.

Относительно "Например, если ассоциативная операция была продуктом вместо суммы, мне пришлось бы переписать части".: если вы структурируете свой код соответственно, вы не смогли бы выполнить это, используя функции более высокого порядка и передав ассоциативная операция? Подумайте о снижении карты.

Ответ 2

Я не знаю ни одной системы компьютерной алгебры, написанной в Clojure. Однако, для моих довольно простых математических потребностей, я нашел, что часто полезно использовать Maxima, который написан в lisp. Можно взаимодействовать с Maxima с помощью s-выражений или представлений более высокого уровня, что может быть действительно удобным. Maxima также имеет некоторые рудиментарные функции комбинаторики, которые могут быть тем, что вы ищете.

Если вы чертовски используете Clojure, в краткосрочной перспективе возможно перебронирование ваших данных вперед и назад между Maxima и Clojure поможет вам достичь ваших целей.

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

Ответ 3

Система ниже не поддерживает комбинаторика, хотя для их добавления не было бы огромных усилий, добавлено множество хорошего кода, и это может быть хорошей платформой для ее трансплантации, поскольку основы довольно хороши. Я надеюсь, что короткий штепсель здесь не уместен, это единственный серьезный Clojure CAS, о котором я знаю, но эй, какая система...

=======

Для читателей этой темы может показаться, что система Gerry Sussman scmutils переносится на Clojure. Это очень продвинутый CAS, предлагающий такие вещи, как автоматическая дифференциация, литеральные функции и т.д., В основном в стиле Maple. Он используется в MIT для продвинутых программ по динамике и дифференциальной геометрии, а также для частичной электротехники. Это также система, используемая в Sussman & Wisdom "продолжение" (LOL) для SICP, SICM (структура и интерпретация классической механики). Хотя первоначально программа Scheme, это не прямой перевод, а переименование, чтобы использовать лучшие функции Clojure. Он был назван сикмутил, как в честь оригинала, так и книги Это превосходное усилие - работа Колина Смита, и вы можете найти его на https://github.com/littleredcomputer/sicmutils.

Я считаю, что это могло бы стать основой удивительной компьютерной алгебраической системы для Clojure, конкурентоспособной с любым другим доступным. Хотя это довольно огромный зверь, как вы можете себе представить, и тонны вещей по-прежнему нужно портировать, основы там очень много, система будет дифференцироваться и отлично справляться с литералами и буквальными функциями. Это незавершенное производство. Система также использует "общий" подход, предложенный Суссманом, при котором операции могут быть применены к функциям, создавая отличную абстракцию, которая упрощает обозначения без конца.

Здесь дегустатор:

> (def unity (+ (square sin) (square cos)))
> (unity 2.0)  ==>  1.0
> (unity 'x)   ==> 1 ;; yes we can deal with symbols
> (def zero (D unity))  ;; Let differentiate
> (zero 2.0)   ==> 0

SicmUtils вводит два новых типа векторов "вверх" и "вниз" (называемых "структурами" ), они работают в значительной степени, как и ожидали векторы, но имеют некоторые специальные математические (ковариантные, контравариантные) свойства, а также некоторое программирование свойства, поскольку они исполняемы!

> (def fnvec (up sin cos tan))  => fnvec
> (fnvec 1)   ==> (up 0.8414709848078965 0.5403023058681398 1.5574077246549023)
> ;; differentiated
> ((D fnvec) 1)  ==>  (up 0.5403023058681398 -0.8414709848078965 3.425518820814759) 
> ;; derivative with symbolic argument
> ((D fnvec) 'θ) ==> (up (cos θ) (* -1 (sin θ)) (/ 1 (expt (cos θ) 2)))  

Частичная дифференциация полностью поддерживается

> (defn ff [x y] (* (expt x 3)(expt y 5)))
> ((D ff) 'x 'y) ==> (down (* 3 (expt x 2) (expt y 5)) (* 5 (expt x 3) (expt y 4))) 
> ;; i.e. vector of results wrt to both variables

Система также поддерживает вывод TeX, полиномиальную факторизацию и множество других полезных свойств. Однако многое из того, что можно было легко реализовать, не было сделано исключительно из-за нехватки людских ресурсов. Графический выход и интерфейс "блокнот/рабочий лист" (с использованием Clojure Gorilla) также работают.

Я надеюсь, что это пошло на то, чтобы поднять ваш аппетит настолько, чтобы посетить сайт и дать ему вихрь. Вам даже не нужно Clojure, вы можете запустить его из предоставленного файла jar.