2016-07-07 8 views
0

Apache Math (무엇이든)를 사용하여 클래스를 코딩했는데 이상한 결함이 있습니다 (또는 Java 코드에 문제가있을 수 있습니다). HashMaps을 배열하고 :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]}) 

기본적으로 내부에 두 가지 형태의 데이터 분배가 :

여기서 코드

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)) 

이되는 HashMap의 문제가 될 수 있도록 잘 작동 .sample 모두 반환 NullPointerException이, 다른 한편으로는 .cumulativeProbabilityMethod (대한 동일 NativeMethodAccessorImpl..blabla ,)

나는 어쩌면에 생성자 MCP와 MP가 (HashMaps을하고 있는지)가 제대로 생성자에서 계산되지 않았 음을 알아 냈

그러나 나는 시도 :

(.get (.getMCP dist) 4) 

올바른 결과를 반환합니다. 사실 MCP hashmap이 예상 한 결과입니다.

그럼 왜 내 코드가 작동하지 않습니까? 내 두 줄은 "기능적으로"동일합니다. 제가 오타를 만든 경우, 저는 그것을 보지 못합니다. 어쩌면 그것은 불변의 것이기 때문일 수 있습니까?

감사합니다.

답변

1

그래, 문제를 알아 냈어. 자바가 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를 전달했습니다.