2010-10-18 18 views
13

Versión corta: Estoy interesado en algún código Clojure que me permita especificar las transformaciones de x (por ejemplo, permutaciones, rotaciones) bajo las cuales el valor de una función f (x) es invariante, de modo que Puedo generar eficientemente una secuencia de x que satisfaga r = f (x). ¿Hay algún desarrollo en álgebra computacional para Clojure? Para (a trivial) ejemploAlgebra computacional para Clojure

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

que podría llamar (imagen inversa f # {0}) y sería volver eficientemente # {3 4 7}. Naturalmente, también podría anotar correctamente el codominio. ¿Alguna sugerencia?

Versión más larga: Tengo un problema específico que me interesa saber sobre el desarrollo del álgebra computacional para Clojure. ¿Alguien puede indicarme un proyecto así? Mi problema específico implica encontrar todas las combinaciones de palabras que satisfagan F (x) = r, donde F es una función de clasificación yr es un entero positivo. En mi caso particular f puede calcularse como una suma

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

Además, tengo un conjunto de conjuntos disjuntos S = {s_i}, tal que f (a) = f (b) para a, b en s, s en S. Entonces, una estrategia para generar todo x tal que F (x) = r debería basarse en esta factorización de F y la invarianza de f debajo de cada s_i. En palabras, calculo todas las permutaciones de sitios que contienen elementos de S que suman r y los componen con todas las combinaciones de los elementos en cada s_i. Esto se hace bastante descuidado en lo siguiente:

(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))))))))) 

Esto hace el trabajo pero no ve la imagen subyacente. Por ejemplo, si la operación asociativa fuera un producto en lugar de una suma, tendría que volver a escribir porciones.

+0

Consulte [Expresso] (https://github.com/clojure-numerics/expresso) desde 2013. – Zaz

Respuesta

1

No estoy al tanto de ningún sistema de álgebra computacional escrito en Clojure. Sin embargo, para mis necesidades matemáticas bastante simples, he encontrado que a menudo es útil usar Maxima, que está escrito en lisp. Es posible interactuar con Maxima usando s-expressions o representaciones de alto nivel, lo que puede ser realmente conveniente. Maxima también tiene algunas funciones combinatorias rudimentarias que pueden ser lo que estás buscando.

Si está empeñado en usar Clojure, a corto plazo quizás arrojar sus datos entre Maxima y Clojure lo ayude a lograr sus objetivos.

A largo plazo, ¡me interesaría saber qué se te ocurre!

2

Hay Clojuratica, una interfaz entre Clojure y Mathematica:

http://clojuratica.weebly.com/

Ver también este mailing list post por el autor de Clojuratica.

Aunque no es un CAS, Incanter también tiene varias características muy agradables y podría ser una buena referencia/base para construir sus propias ideas.

Con respecto a "Por ejemplo, si la operación asociativa fuera un producto en lugar de una suma, tendría que reescribir las partes".: si estructura su código en consecuencia, ¿no podría lograrlo utilizando funciones de orden superior y pasando la operación asociativa? Piensa en map-reduce.

1

El sistema siguiente aún no es compatible con la combinatoria, aunque no sería un gran esfuerzo agregarlos, ya existe un buen código y esta podría ser una buena plataforma para incluirlo, ya que los fundamentos son bastante sólidos. . Espero un tapón corto no es apropiado aquí, esta es la única seria Clojure CAS no conozco, pero bueno, lo que es un sistema de ...

=======

Puede ser de interés para los lectores de este hilo que Gerry Sussman scmutils sistema está siendo portado a Clojure. Este es un CAS muy avanzado, que ofrece cosas como la diferenciación automática, funciones literales, etc., al estilo de Maple. Se usa en MIT para programas avanzados de dinámica y geometría diferencial, y un poco de ingeniería eléctrica. También es el sistema utilizado en "secuela" Sussman & de sabiduría (LOL) a SICP, SICM (Estructura e interpretación de la mecánica clásica). Aunque originalmente era un programa Scheme, esta no es una traducción directa, sino una reescritura original para aprovechar las mejores características de Clojure. Ha sido nombrado sicmutils, ambos en honor del original y del libro Este excelente esfuerzo es obra de Colin Smith y puedes encontrarlo en https://github.com/littleredcomputer/sicmutils.

Creo que esto podría formar la base de un increíble sistema de álgebra computarizada para Clojure, competitivo con cualquier otra cosa disponible. A pesar de que es una bestia bastante grande, como se puede imaginar, y aún quedan toneladas de cosas por portar, los conceptos básicos están bastante presentes, el sistema diferenciará y manejará literales y funciones literales bastante bien. Es un trabajo en progreso. El sistema también utiliza el enfoque "genérico" defendido por Sussman, según el cual las operaciones se pueden aplicar a las funciones, creando una gran abstracción que simplifica la notación sin fin.

He aquí una pequeña muestra:

> (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 introduce dos nuevos tipos de vectores “arriba” y “abajo” (llamadas “estructuras”), que funcionan más o menos como era de esperar vectores a, pero tienen algunos especiales propiedades matemáticas (covariantes, contravariantes), y también algunas propiedades de programación, ¡ya que son ejecutables!

> (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))) 

diferenciación parcial es totalmente compatible

> (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 

El sistema también soporta salida TeX, factorización polinomio, y una serie de otras golosinas. Sin embargo, muchas cosas que podrían implementarse fácilmente no se han realizado puramente por falta de recursos humanos. También se está trabajando en la salida gráfica y en la interfaz de "bloc de notas/hoja de trabajo" (utilizando Gorila de Clojure).

Espero que esto haya sido suficiente para despertar su apetito lo suficiente como para visitar el sitio y darle un giro. Ni siquiera necesita Clojure, puede ejecutarlo desde el archivo jar provisto.

Cuestiones relacionadas