2016-03-22 2 views
2

Java Apache Maths 3をClojureにラップしようとしていますが、私は理解できない問題に直面しています。ClojureとJava interop:voidを返す関数

http://commons.apache.org/proper/commons-math/javadocs/api-3.3/index.html

オブジェクトに値を追加しますが、voidを返すaddValue方法:ここで

はjavadocのです。私はこのオブジェクトの内部にいくつかの内部データがあると思います。

Javaでは、私はどうなる:

regression.addValue(1,2); 

は、私はそれをラップするためにClojureの中で関数を定義した:

;;----------Simple regression object builder---------- 

(defn simple-regression [] 
    (SimpleRegression.)) 

;;----------Add points---------- 

(defn add-point 
    ([reg [x y]] 
    (.addData reg (double x) (double y))) 
    ([reg x y] 
    (.addData reg (double x) (double y)))) 

(defn add-points 
    ([data reg] 
    (let [x (data :x) 
     y (data :y) 
     d (zipmap x y)] 
    (map (fn [[k v]] (add-point reg k v)) d))) 
    ([x y reg] 
    (let [d (zipmap x y)] 
    (map (fn [[k v]] (add-point reg k v)) d)))) 

の機能が正常に動作し、私はREPLで別々にそれを使用する場合。私は(.getNのREG)しようとすると確認され(それは値が追加されていないことを意味するように戻り、[NaNではNaNを])

(defn lin-reg 
    ([data & {:keys [type] :or {type "simple"}}] 
    (let [reg (simple-regression)] 
    (do (add-points data reg) 
     (cond (= type "simple") 
       [(.getSlope reg) (.getIntercept reg)] 
       (= type "extended") 
       {:params [(.getSlope reg) (.getIntercept reg)] :r (.getR reg) :r2 (.getRSquare reg) :significance (.getSignificance reg)} 
       (= type "full") 
       {:params [(.getSlope reg) (.getIntercept reg)] :r (.getR reg) :r2 (.getRSquare reg) :significance (.getSignificance reg) 
       :conf-intervals [(.getSlopeConfidenceInterval reg) (.getInterceptConfidenceInterval reg)] :params-sse [(.getSlopeStdErr reg) (.getInterceptStdErr reg)] 
       :sse (.getSumSquaredErrors reg) :ssto (.getTotalSumSquares reg) :ssm (.getRegressionSumSquares reg) :cross-products-sum (.getSumOfCrossProducts reg)} 
       :else 
       (println "regression type can only be : simple, extended or full")))))) 

コードは動作しません、:

私は、完全なラッパーを定義し私は別にそれをしようとした場合= 0 、私はすべての作品は、最初の

(def reg (simple-regression)) 
(add-points {:x [1 2 3] :y [0.1 0.2 0.3]} reg) 
[(.getSlope reg) (.getIntercept reg)] 

問題ありませんを意味します。

しかし、機能の中では、私は多くのバージョンを試しました

_ (add-points data reg) 

私は、機能の中にポイントが追加されていないという印象を持っています。 doを貼り付けても同じです。

オブジェクトが関数内で変更できないような、より一般的なJavaのメカニズムがありますか?あなたがdoでそれらを使用し、(doallまたはdorunを使用して)実際の値を返すか、それらを強制するように依頼していないので、すべての要素が実現され、すべての副作用が発生したときのおかげ

答えて

2

mapzipmapはとても怠け者です(例:呼び出す.addDataは、ある状態を変更する副作用です)、あなたの関数がmapに渡されたとしても、まったく呼び出されません。 REPLでこれらの関数を使用すると、結果の印刷はmapの結果をレンダリングしようとし、遅延セクションを実現します。

mapの実際の結果は必要ありませんが、副作用を適用したい場合は、代わりにdoseqを使用します。

+0

ありがとう、私はClojureについて多くの知識が不足しているようです。大きな計算ではないのでdoallで問題を解決しましたが、後でdoseqを使うことを検討します! –

+2

あなたは "怠け者のバグ"に噛まれていますが、あなたが見ていないときにはかかります;-) –