简化版: 我想找一些Clojure代码,让我可以指定对x的变换(如排列、旋转),以使函数f(x)的值在变换下保持不变,这样我就可以高效地生成一系列满足r = f(x)的x序列。在Clojure中是否有计算机代数方面的进展? 以下是(一个微不足道的)示例。
(defn #^{:domain #{3 4 7}
:range #{0,1,2}
:invariance-group :full}
f [x] (- x x))
我可以调用(preimage f #{0})方法,它会高效地返回#{3 4 7}。自然地,它也能正确地注释目标集合。有什么建议吗?
更长的版本: 我的一个具体问题让我对寻找适用于Clojure的计算机代数开发产生了兴趣。有人能指向这样的项目吗? 我的具体问题涉及查找所有满足F(x) = r的单词组合,其中F是排名函数,r是正整数。在我的特定情况下,f可以计算为以下求和:
F(x) = f(x[0]) + f(x[1]) + ... f(x[N-1])
此外,我还有一组不交集合S = {s_i},使得对于a,b在s中,f(a) = f(b),s在S中。因此,生成所有满足F(x) = r的x的策略应该依赖于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)))))))))
这可以完成任务,但忽略了基本情况。例如,如果关联操作是乘法而不是加法,则必须重新编写某些部分。