clojure中的符号矩阵库,需要建议



虽然有很多用于线性代数的java库,但Clojure目前没有一个支持符号数学的惯用计算机代数系统。首先,我想我可以开始做一些简单的事情。

作为第一步,我认为正确的数据结构将是一个良好的开端。

步骤1:实现持久矩阵

我将使用deftype(或reify),目前,为了便于实现,我将使用一个存储哈希图(如果认为更好,请提出一个替代方案,但要权衡)。(根据您的性能要求,可以想象许多不同的实现,例如使用数组或委托给外部java库,以及实现某种瞬态接口。)

我的问题是,我应该考虑实现什么接口/协议?(一般来说,clojure使用的所有协议/接口的列表是什么?)此外,对于如何实现这些协议/接口,有什么建议吗

我要实现的事项列表:

-关联将是有用的,以不可变的方式修改矩阵的部分

-将矩阵视为一个函数作为元素的访问器,我认为可以通过自定义查询hashmap/语言,传递一个二元组来返回单个元素、单个值(按宽度索引*y+x)、hashmap来获取列、行或次要项。

注意,我目前的目标是设计好的抽象,以便在选择实现时实现灵活性

我或多或少地管理SymPy中的线性代数模块,SymPy是一个主要的Python符号包。我将从传统的计算机代数系统中给你我的观点。

对于三个重要的用例,我们有三个单独的实现

  1. 可变矩阵——尽管在Python中,SymPy默认情况下是不可变的。我们实际上已经打破了矩阵的这个规则。矩阵算法是一个标准示例,说明出于性能原因,您真正需要切换到可变性
  2. 不可变矩阵——但您希望可以选择切换回来。我们预期的工作流程如下

    1. 构建一个不可变矩阵
    2. 切换到可变性并执行一些算法
    3. 切换回不变性并将其呈现给用户
  3. 矩阵符号——通常你不需要处理矩阵中的显式条目,而是需要处理矩阵的概念。请参阅此scicomp.stackeexchange帖子。这是我目前的工作,我觉得它非常令人兴奋。

还有其他分裂,比如密集表示与稀疏性。符号线性代数是一个重要的领域。我期待着看到Clojure社区的集体解决方案。

虽然它是一个Java库,但我设计了从Clojure使用的vectorz。

它为高性能矢量和矩阵数学提供了大量的数据结构和算法。你可能会发现它很有用。我目前正在Clojure中使用它进行计算机图形学和机器学习。

矩阵和向量是可变的,但我发现这是一个必要的缺点:对于许多算法来说,使用不可变的向量和矩阵太慢了。

如果有足够多的人觉得这很有用和/或想参与进来,我会对构建一个惯用的clojure包装器(包括向量和矩阵的不可变版本)感兴趣。

本线程的读者可能感兴趣的是,Gerry Sussman的scmutils系统正在移植到Clojure。这是一个非常先进的CAS,提供自动区分、文字函数等功能,非常像Maple。它在麻省理工学院用于动力学和微分几何的高级课程,以及相当多的电气工程内容。它也是Sussman&智慧的"续集"(LOL)SICPSICM(经典力学的结构与解释)。虽然最初是Scheme程序,但这不是直接翻译,而是利用Clojure的最佳功能进行的一次彻底重写。它被命名为sicmutils,既是为了纪念原作,也是为了纪念这本书这是科林·史密斯的杰作,你可以在https://github.com/littleredcomputer/sicmutils。

我相信这可以成为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引入了两种新的向量类型"up"one_answers"down"(称为"structures"),它们的工作原理与您所期望的向量非常相似,但具有一些特殊的数学(协变、逆变)属性,以及一些编程属性,因为它们是可执行的!

> (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文件中运行它。

===========

PS。顺便说一句,要直接回答最初的问题,是的,sicmutils确实支持符号结构:您可以设置一个矩阵表示,其中条目是公式,例如旋转矩阵,然后对给定坐标进行计算(相乘)。这种方式非常灵活。

这可能无法回答您的问题,但我在使用Incanter时发现的一件事是,我需要能够使用环绕式访问元素。对于向量也是如此,有时可以方便地从末尾反向为访问元素提供负索引,或者从一开始就向访问元素提供超出范围的索引。自然地计算偏移会增加开销,但有时这是你愿意为付费的功能

MPL是一个用可移植R6RS方案编写的简单符号数学库。这里有一个简短的介绍。

由于Scheme是一个Lisp,因此MPL应该非常简单地移植到Clojure。

最新更新