2

我只需要i在算法中使用。对于这样的任务,我觉得导入clojure.math是矫枉过正的。

为什么?

我不需要复杂的结果,实际上不需要带有虚部的实部。在我的实现中,我一次只使用一个值,并且从不将两者结合起来,除了乘法。输出最终没有参考i,虚部只需要查看计算中符号的变化。

简而言之,如果有一种方法可以定义i为:

(def i (....) ) 

这样(* i i)等于-1

4

3 回答 3

3

如果你想(* i i)评估,-1我们需要准备一个宏。

(ns user)
(defmacro *
  [& args]
  (let [i-count (count (filter #(= % 'i) args))
        error #(throw (Exception. "Illegal number of imaginary units."))
        i-factor (case (mod i-count 4)
                   0 1
                   2 -1
                   (error))]
    `(clojure.core/* ~@(conj (filter #(not= % 'i) args) i-factor))))

宏扩展为普通乘法,它不应该干扰实数的乘法。

user=> (macroexpand '(* i i))
(clojure.core/* -1)
user=> (macroexpand '(* i i 5 i 6 i))
(clojure.core/* 1 5 6)
user=> (macroexpand '(* 1.3 3.7))
(clojure.core/* 1 1.3 3.7)
user=> (macroexpand '(* i (+ 2 3) i))
(clojure.core/* -1 (+ 2 3))

Is a macro necessary? Without a macro is present in (* i i) would get evaluated. Since they weren't defined it would cause a compile-time error. As suggested in the question, we could define i as a value which * knows how to handle. Despite that being possible, it would still be evaluated at runtime. A clear advantage of a macro is the fact that it's evaluated during compilation and replaced with an ordinary call to clojure.core/* as shown in examples above. Simply put, it's fast.

于 2012-11-27T11:13:15.920 回答
1

像这样的东西很快就被黑了*?

(defn hacked-* [& args]
  (let [[i-amount product] 
        ((juxt (comp count filter) 
               (comp #(apply * %) remove)) 
         #{:i} args)]
    (if (and (> i-amount 0) (even? i-amount)) 
      (- product)
      product)))


(hacked-* 1 2 3) => 6
(hacked-* 1 2 3 :i :i) => -6
(hacked-* 1 2 3 :i :i :i) => 6

您可以在词法上将 * 重新绑定到被破解的版本以评估复杂的表达式:

(let [* hacked-*]
 (* 1 :i 2 :i 3 :i (* :i :i))) => -6
于 2012-11-26T17:22:43.257 回答
0

这是我的技巧,假设参数都是虚构的:

(defn im* [& i] ((fn [q n] (([* str * str] q) ([1 'i -1 '-i] q) n)) (mod (count i) 4) (reduce * i)))

...可怕!但是如果没有例如破解Numbers.java以调度到 java.lang.Number 的新子类型,您所要求的实际上是不可能的。实际上,使用 Java 或 Clojure 复数库会更有意义。

于 2012-11-27T01:23:15.877 回答