2016-07-07 24 views
0

私はApache Maths(何でも)を使ってクラスをコーディングしましたが、私は奇妙なグリッチを持っています(あるいはJavaコードに問題がありますか?)。ハッシュマップと配列:Clojure:java interop、なぜこのコードは機能しませんか?

(defn create-distribution 
    "Creates a distribution from empirical data" 
    [data] 
    (let [values (long-array (data :values)) 
     probabilities (double-array (data :probabilities))] 
    (CustomDistribution. values probabilities))) 

(create-distribution {:values [1 2 3 4] :probabilities [0.3 0.2 0.2 0.3]}) 

基本的には、内部の2つの形式でデータを持つ分布である:

ここでコード

package distributions; 

import java.util.HashMap; 
import java.util.Map; 
import java.util.Random; 
import org.apache.commons.math3.distribution.AbstractIntegerDistribution; 
import org.apache.commons.math3.util.FastMath; 

public class CustomDistribution extends AbstractIntegerDistribution { 

    long[] v; 
    double[] p; 
    double[] cp; 
    Map<Long, Double> mp = new HashMap<Long, Double>(); 
    Map<Long, Double> mcp = new HashMap<Long, Double>(); 

    public CustomDistribution (long[] values, double[] probabilities) { 
     v = values; 
     p = probabilities; 

     int len = values.length; 

     for (int i = 0; i < len; i++) { 
      mp.put(v[i], p[i]); 
     } 

     cp = new double[len]; 
     cp[0] = p[0]; 
     for (int i = 1; i < len; i++) { 
      cp[i] = cp[i-1] + p[i]; 
     } 

     for (int i = 0; i < len; i++) { 
      mcp.put(v[i], cp[i]); 
     } 
    } 

     public Map<Long, Double> getMCP() {return mcp;} 

    @Override 
    public double cumulativeProbability(int v) { 
     return mcp.get(v); 
    } 

    // Not implemented, can be done in Clojure code 
    @Override 
    public double getNumericalMean() { 
     return 0; 
    } 

    // Not implemented, can be done in Clojure code 
    @Override 
    public double getNumericalVariance() { 
     return 0; 
    } 

    @Override 
    public int getSupportLowerBound() { 
     return 0; 
    } 

    @Override 
    public int getSupportUpperBound() { 
     return 0; 
    } 

    @Override 
    public boolean isSupportConnected() { 
     return false; 
    } 

    @Override 
    public double probability(int v) { 
     return mp.get(v); 
    } 

    // Uses a naive search implementation, should be ok due to data size 
    public int sample() { 

     double r = FastMath.random(); 
     int len = p.length; 
     Boolean flag = false; 
     int i = 0; 
     int result = -1; 

     while (i < len && flag == false) { 
      if (cp[i] < r) { 
       i = i + 1; 
      } 
      else { 
       result = (int) v[i]; 
       flag = true; 
      } 
     } 
     return result; 
    } 
    } 

Clojureのラッパーです。 Clojureので

は、私が試した:

(.probability dist 4) 
(.probability dist (int 4)) 

それはハッシュマップの問題であってもよいので、正常に動作し.sample両方返すNullPointerExceptionが、一方.cumulativeProbabilityMethod (、同じNativeMethodAccessorImpl..blabla 、 )

私は多分にコンストラクタMCPとMPが(ハッシュマップであること)が正しくコンストラクタで計算されていなかったことを考え出し

が、私が試した:

(.get (.getMCP dist) 4) 

私は正しい結果を返します。 MCPハッシュマップは実際に私が期待した結果です。

私のコードはなぜ機能しませんか?私の2つの行は「機能的に」同じです。 私がタイプミスをした場合、私はそれを見ません。 不変性のためかもしれませんか?

ありがとうございます!

答えて

1

私が問題を理解したので、JavaがClojureの数値プリミティブと同じくらい柔軟ではないことを忘れていました。

このコードは動作します:Clojureのコードで

@Override 
public double cumulativeProbability(int v) { 
    return mcp.get((long) v); 
} 

@Override 
public double probability(int v) { 
    return mp.get((long) v); 
} 

、二重の変換は自動的に行われます。 Javaでは、HasMapがLongと予想されるIntegerを渡しました

関連する問題