2016-07-07 90 views
0

我编写了一个类,使用Apache数学(不管),我有一个奇怪的故障(或者也许有我的Java代码中的问题?)。Clojure:java interop,为什么这段代码不起作用?

这里是代码

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的包装:

(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]}) 

基本上它是内部有两种形式的数据分布:包含HashMap和阵列。

在Clojure中,我想:

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

两个回报NullPointerException异常,NativeMethodAccessorImpl..blabla 相同的.cumulativeProbabilityMethod (在另一方面,所以它可能是HashMap中的一个问题。样品工作正常)

我想通了,也许在构造函数中MCP和MP(即是包含HashMap)没有正确的构造函数计算的,但是当我尝试:

(.get (.getMCP dist) 4) 

它返回我正确的结果。实际上,MCP hashmap是我预期的结果。

那么为什么我的代码不起作用?我的两条线在功能上是一样的。 如果我犯了一个错字,我没有看到它。 也许是因为不变性的原因?

谢谢!

回答

1

好吧,我想出了问题,我忘了Java不像Clojure那样灵活的使用数字原语。

此代码:

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

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

在Clojure中的代码,双重的转换是自动的。 在Java中,我传递了一个整数,HasMap预计长整数

相关问题