将Java代码转换为快速的Clojure代码

2da*_*aaa 8 clojure

这个Java代码可以转换为快速或几乎同样快的Clojure代码吗?

我已经能够获得更简单的功能,比如添加两个数组,以合理的速度运行类型提示,但我无法让Clojure使用Java互操作或Incanter在合理的时间内完成以下功能矩阵并使用功能或命令式样式.

我错过了关于类型提示的东西,还是最好在Java中做这种事情?

static double[][] grad2_stencil= { {0,0,-1,0,0}, 
                             {0,0,16,0,0}, 
                             {-1,16,-60,16,-1}, 
                             {0,0,16,0,0}, 
                             {0,0,-1,0,0} };

public static double grad2(double[][] array, int x, int y){
    double temp=0;
    int L=array.length;
    for(int i=0; i<5; i++){
        for(int j=0; j<5; j++){
            temp+=array[((x+i-2)%L+L)%L][((y+j-2)%L+L)%L]*grad2_stencil[i][j];
        }
    }
    return temp/12.0;
}

public static double[][] grad2_field(double[][] arr){
    int L=arr.length;
    double[][] result=new double[L][L];

    for(int i=0; i<L; i++){
        for(int j=0; j<L; j++){
            result[i][j]=grad2(arr, i, j);
        }
    }

    return result;
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*art 8

在clojure 1.3(master分支)中尝试以下内容:

(def ^"[[D" grad2-stencil
  (into-array (Class/forName "[D")
    (map double-array 
      [[ 0   0  -1  0  0 ] 
       [ 0   0  16  0  0 ]
       [-1  16 -60 16 -1 ] 
       [ 0   0  16  0  0 ] 
       [ 0   0  -1  0  0 ]])))

(defn ^:static idx ^long [^long x ^long i ^long L]
  (-> x
    (+ i)
    (- 2)
    (mod L)
    (+ L)
    (mod L)))

(defn ^:static grad2 ^double [^doubles arr ^long x ^long y]
  (let [L (alength arr)
        temp (loop [i 0 j 0 temp 0.0]
               (if (< i 5) 
                 (let [a (idx x i L)
                       b (idx y j L)
                       temp (double (* (aget arr a b) 
                                      (aget grad2-stencil i j)))]
                   (if (< j 4)
                     (recur i (inc j) temp)
                     (recur (inc i) 0 temp)))
                 temp))]
    (/ temp 12.0)))

(defn ^:static grad2-field ^"[[D" [^"[[D" arr]
  (let [result (make-array Double/TYPE (alength arr) (alength arr))]
    (loop [i 0 j 0]
      (when (< i 5)
        (aset result (grad2 arr i j) i j)
        (if (< j 4)
          (recur i (inc j))
          (recur (inc i) 0))))
    result))
Run Code Online (Sandbox Code Playgroud)


Art*_*ldt 5

从目前在github上的clojure 1.3分支开始,您可以使用原语作为函数的参数并从函数返回.您也将不再需要键入提示编号基元.它应该能够更快地暗示这种类型的代码并且看起来更优雅.

在类型提示中,你可能会遇到(<= clojure 1.2)所有函数参数被装箱的事实.