Clojure 的计算机代数

发布于 2024-09-28 04:35:47 字数 1651 浏览 1 评论 0原文

简短版本: 我对一些 Clojure 代码感兴趣,它允许我指定 x 的变换(例如排列、旋转),在这些变换下函数 f(x) 的值是不变的,这样我就可以有效地生成满足 r 的 x 序列= 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},这样对于 s 中的 a、b、S 中的 s,f(a)=f(b)。因此,生成所有 x 使得 F(x) = r 的策略应该依赖于这种因式分解F 的和每个 s_i 下 f 的不变性。换句话说,我计算包含 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)))))))))

这完成了工作,但错过了底层的图片。例如,如果关联运算是乘积而不是和,我将不得不重写部分内容。

Short version:
I am interested in some Clojure code which will allow me to specify the transformations of x (e.g. permutations, rotations) under which the value of a function f(x) is invariant, so that I can efficiently generate a sequence of x's that satisfy r = f(x). Is there some development in computer algebra for Clojure?
For (a trivial) example

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

I could call (preimage f #{0}) and it would efficiently return #{3 4 7}. Naturally, it would also be able to annotate the codomain correctly. Any suggestions?

Longer version:
I have a specific problem that makes me interested in finding out about development of computer algebra for Clojure. Can anyone point me to such a project? My specific problem involves finding all the combinations of words that satisfy F(x) = r, where F is a ranking function and r a positive integer. In my particular case f can be computed as a sum

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

Furthermore I have a set of disjoint sets S = {s_i}, such that f(a)=f(b) for a,b in s, s in S. So a strategy to generate all x such that F(x) = r should rely on this factorization of F and the invariance of f under each s_i. In words, I compute all permutations of sites containing elements of S that sum to r and compose them with all combinations of the elements in each s_i. This is done quite sloppily in the following:

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

This gets the job done but misses the underlying picture. For example, if the associative operation were a product instead of a sum I would have to rewrite portions.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

假装不在乎 2024-10-05 04:35:48

我不知道有任何用 Clojure 编写的计算机代数系统。然而,对于我相当简单的数学需求,我发现使用 Maxima 通常很有用,它是用 lisp 编写的。可以使用 s 表达式或更高级别的表示与 Maxima 进行交互,这非常方便。 Maxima 还具有一些基本的组合函数,这可能正是您正在寻找的。

如果您执意要使用 Clojure,短期内也许在 Maxima 和 Clojure 之间来回传输数据会帮助您实现目标。

从长远来看,我有兴趣看看你能想出什么!

I am unaware of any computer algebra systems written in Clojure. However, for my rather simple mathematical needs I have found it often useful to use Maxima, which is written in lisp. It is possible to interact with Maxima using s-expressions or a higher-level representations, which can be really convenient. Maxima also has some rudimentary combinatorics functions which may be what you are looking for.

If you are hellbent on using Clojure, in the short term perhaps throwing your data back and forth between Maxima and Clojure would help you achieve your goals.

In the longer term, I would be interested in seeing what you come up with!

等风来 2024-10-05 04:35:47

下面的系统尚不支持组合,尽管添加它们并不需要付出巨大的努力,已经存在大量好的代码,并且这可能是一个很好的移植平台,因为基础知识非常完善。我希望在这里简短的插入不是不合适的,这是我所知道的唯一严肃的 Clojure CAS,但是嘿,这是一个什么样的系统...

=======

Gerry Sussman 的这篇文章的读者可能会感兴趣scmutils 系统正在移植到 Clojure。
这是一个非常先进的 CAS,提供自动微分、文字函数等功能,很像 Maple 的风格。
它在麻省理工学院用于动力学和微分几何的高级程序,以及相当多的电气工程内容。它也是 Sussman&Wisdom 的 SICPSICM(经典力学的结构与解释)的“续集”(LOL)中使用的系统。
虽然最初是一个Scheme程序,但这并不是直接翻译,而是为了利用Clojure的最佳功能而进行的彻底重写。它被命名为sicmutils,既是为了纪念原著,也是为了纪念这本书
这项出色的工作是 Colin Smith 的作品,您可以在 https://github.com/littleredcomputer/sicmutils< /a> .

我相信这可以构成令人惊叹的 Clojure 计算机代数系统的基础,与其他可用的系统竞争。虽然它是一个相当庞大的野兽,正如你可以想象的那样,并且还有大量的东西需要移植,但基础知识几乎已经存在,系统将区分并很好地处理文字和文字函数。这是一项正在进行的工作。该系统还使用 Sussman 提倡的“通用”方法,通过该方法可以将操作应用于函数,从而创建一个伟大的抽象,从而无限地简化符号。

这是一个品尝者:

> (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 的 Gorilla)也正在开发中。

我希望这足以激起您的兴趣,让您访问该网站并尝试一下。您甚至不需要 Clojure,您可以通过提供的 jar 文件运行它。

The system below does not yet support combinatorics, though it would not be a huge effort to add them, loads of good code already exists, and this could be a good platform to graft it onto, since the basics are pretty sound. I hope a short plug is not inappropriate here, this is the only serious Clojure CAS I know of, but hey, what a system...

=======

It may be of interest to readers of this thread that Gerry Sussman's scmutils system is being ported to Clojure.
This is a very advanced CAS, offering things like automatic differentiation, literal functions, etc, much in the style of Maple.
It is used at MIT for advanced programs on dynamics and differential geometry, and a fair bit of electrical engineering stuff. It is also the system used in Sussman&Wisdom's "sequel" (LOL) to SICP, SICM (Structure and Interpretation of Classical Mechanics).
Although originally a Scheme program, this is not a direct translation, but a ground-up rewrite to take advantage of the best features of Clojure. It's been named sicmutils, both in honour of the original and of the book
This superb effort is the work of Colin Smith and you can find it at https://github.com/littleredcomputer/sicmutils .

I believe that this could form the basis of an amazing Computer Algebra System for Clojure, competitive with anything else available. Although it is quite a huge beast, as you can imagine, and tons of stuff remains to be ported, the basics are pretty much there, the system will differentiate, and handle literals and literal functions pretty well. It is a work in progress. The system also uses the "generic" approach advocated by Sussman, whereby operations can be applied to functions, creating a great abstraction that simplifies notation no end.

Here's a taster:

> (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 introduces two new vector types “up” and “down” (called “structures”), they work pretty much as you would expect vectors to, but have some special mathematical (covariant, contravariant) properties, and also some programming properties, in that they are executable!

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

Partial differentiation is fully supported

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

The system also supports TeX output, polynomial factorization, and a host of other goodies. Lots of stuff, however, that could be easily implemented has not been done purely out of lack of human resources. Graphic output and a "notepad/worksheet" interface (using Clojure's Gorilla) are also being worked on.

I hope this has gone some way towards whetting your appetite enough to visit the site and give it a whirl. You don't even need Clojure, you could run it off the provided jar file.

久光 2024-10-05 04:35:47

Clojuratica 是 Clojure 和 Mathematica 之间的接口:

http://clojuratica.weebly.com/

另请参阅此 < Clojuratica 作者的 href="http://groups.google.com/group/clojure/browse_thread/thread/4b25d4b547df113e/f7f48f5cf5594c94?show_docid=f7f48f5cf5594c94" rel="nofollow">邮件列表帖子。

虽然不是 CAS,Incanter 也有几个非常好的功能,可能是构建您自己的想法的一个很好的参考/基础。

关于“例如,如果关联运算是乘积而不是总和,我就必须重写部分内容。”:如果您相应地构建代码,难道不能通过使用高阶来实现这一点吗?函数并传入关联运算?想想映射缩减。

There's Clojuratica, an interface between Clojure and Mathematica:

http://clojuratica.weebly.com/

See also this mailing list post by Clojuratica's author.

While not a CAS, Incanter also has several very nice features and might be a good reference/foundation to build your own ideas on.

Regarding "For example, if the associative operation were a product instead of a sum I would have to rewrite portions.": if you structure your code accordingly, couldn't you accomplish this by using higher-order functions and passing in the associative operation? Think map-reduce.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文