Компьютерная алгебра для Clojure - PullRequest
15 голосов
/ 19 октября 2010

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

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

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

Более длинная версия: у меня есть конкретная проблема, которая заставляет меня интересоваться развитием компьютерной алгебры для Clojure.Кто-нибудь может указать мне на такой проект?Моя конкретная проблема заключается в поиске всех комбинаций слов, которые удовлетворяют F (x) = r, где F - функция ранжирования и ra - положительное целое число.В моем конкретном случае 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)))))))))

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

Ответы [ 3 ]

5 голосов
/ 14 января 2017

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

=======

Читателям этой ветки может быть интересно, что система scmutils Джерри Суссмана переносится на Clojure. Это очень продвинутый CAS, предлагающий такие вещи, как автоматическое дифференцирование, литеральные функции и т. Д., В стиле Maple . Он используется в MIT для продвинутых программ по динамике и дифференциальной геометрии, а также для электротехники. Это также система, используемая в «продолжении» Sussman & Wisdom (LOL) для SICP , SICM (Структура и интерпретация классической механики). Хотя изначально это была программа Scheme, это не прямой перевод, а предварительное переписывание, чтобы воспользоваться всеми преимуществами Clojure. Он был назван sicmutils , как в честь оригинала, так и книги. Это превосходное усилие - работа Колина Смита, и вы можете найти его в 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's 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's Gorilla) также работают над этим.

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

2 голосов
/ 19 октября 2010

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

http://clojuratica.weebly.com/

См. Также сообщение в списке рассылки автора Clojuratica.

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

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

1 голос
/ 19 октября 2010

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

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

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

...