4

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

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

第 1 步:实现持久矩阵

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

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

我要实施的事情清单:

-Assoc'ing 会很有用,可以以不可变的方式修改矩阵的各个部分

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

请注意,我目前的目标是设计良好的抽象,以便能够灵活地选择实现。

4

5 回答 5

2

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

我们为三个重要的用例提供了三个单独的实现

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

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

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

于 2012-11-17T13:41:53.233 回答
1

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

它为高性能向量和矩阵数学提供了许多数据结构和算法。你可能会发现它很有用。我目前将它用于 Clojure 中的计算机图形和机器学习。

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

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

于 2012-11-17T10:06:54.703 回答
1

Gerry Sussman 的scmutils系统被移植到 Clojure可能会让本主题的读者感兴趣。这是一个非常先进的 CAS,提供诸如自动微分、文字函数等功能,非常类似于Maple。它在麻省理工学院用于动力学和微分几何的高级程序,以及相当多的电气工程材料。它也是 Sussman&Wisdom 的SICPSICM(经典力学的结构和解释)的“续集”(LOL)中使用的系统。虽然最初是一个 Scheme 程序,但这不是直接翻译,而是为了利用 Clojure 的最佳特性而进行的彻底重写。它被命名为sicmutils, 既是为了纪念原著,也是为了纪念这本书。这项出色的工作是 Colin Smith 的作品,您可以在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 引入了两种新的向量类型“向上”和“向下”(称为“结构”),它们的工作方式与您期望的向量非常相似,但具有一些特殊的数学(协变、逆变)属性,以及一些编程属性,在它们是可执行的!

> (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确实支持符号结构:您可以设置一个矩阵表示,其中条目是公式,例如旋转矩阵,然后针对给定坐标评估(乘以)它。它以这种方式非常灵活。

于 2017-01-14T03:10:40.867 回答
0

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

于 2012-11-19T05:35:12.517 回答
0

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

由于 Scheme 是一个 Lisp,MPL 应该很容易移植到 Clojure。

于 2012-12-09T04:56:41.947 回答