【发布时间】:2013-10-29 21:54:23
【问题描述】:
我想使用 Clojure 哈希图来定义广义向量。在这张图中,hashmap {:x 3 :y 2 :z (- 3)} 表示符号表达式 3x + 2y - 3z。
我想要一个函数 gen+,它充当哈希图上的加法运算,并且满足以下约束:
- 将 gen+ 应用于两个具有重叠键的哈希图会返回一个哈希图,其中这些键值求和。例如,
(gen+ {:x 1} {:x 2})
;= {:x 3}
- 将 gen+ 应用于两个具有不同键的哈希映射会返回一个组合了这些键值的哈希映射。例如,
(gen+ {:x 1} {:y 2})
;= {:x 1 :y 2}
- 空的 hashmap {} 是 gen+ 函数的附加标识。例如,
(gen+ {:x 1} {})
:= {:x 1}
- 根据上述限制,任何条目为零的哈希图也是一个附加标识。例如,{:z 0}。由于这种冗余,gen+ 函数应始终返回不带任何 0 值的哈希图。例如,
(gen+ {:x 1 :y 0} {:z 0})
;= {:x 1}
- Clojure 将缺少的键解释为具有值 nil,而不是 0,就像
({:x 3} :y) ;= nil一样。因此,gen+ 应该以与 0 相同的方式处理 nil 值。例如,
(gen+ {:x 1 :y 0} {:x nil :y nil})
{:x 1}
- 我的问题: 我们如何编写满足上述约束的函数 gen+?一旦到位,是否可以使用 gen+ 函数重载 + 运算符,从而使用哈希图实现基本加法?
应该很明显为什么这种形式将哈希图视为广义向量。 Clojure 将像 [x0 x1 x2] 这样的向量解释为与哈希图 {:0 x0 :1 x1 :2 x2} 几乎相同,但有一点我不太理解的差异。因此,如果我们将 gen+ 应用于两个向量,那么它实际上应该与应用于它们的 + 相同。这使我们能够轻松地使用 sparse 向量,以及添加不同大小的向量。例如,
(gen+ [0 0 0 4] [0 0 0 0 0 0 0 0 0 9])
;= {:4 4 :9 9}
以下是我对哈希图和向量的不理解。如果我将哈希图称为函数,我需要应用一个关键参数,例如:2。另一方面,如果我将向量作为函数调用,我需要应用像 2 这样的索引参数。例如,
({:2 2} :2)
;= 2
([0 1 2] 2]
;= 2
即使您无法使用 gen+ 函数,您能否解释一下为什么哈希图和向量在作为函数调用时表现不同?
【问题讨论】:
-
就像 M Smith 一样,我不建议重载 +, but here's some dark magic 反正。
-
如果这是一个学校项目,请支持你的学校接受clojure。
-
@muhuk:我是一名专业数学家,主要从事泛函分析(无限维线性代数)。当感兴趣的空间/类型是线性空间、点/项是向量、地图/函数是线性运算符时,这些工具适用。能够将哈希图用作向量意味着我们可以部署现代数学技术,而不必重新发明轮子。这种观点在 MapReduce 架构中特别有用,其中感兴趣的基本对象是键/值对,就像哈希图一样。
-
但我也认为学校应该对各种编程语言开放,尤其是功能性语言:)
标签: vector clojure hashmap linear-algebra addition