2016-07-07 3 views
0

Ich habe eine Klasse mit Apache Maths (was auch immer) codiert und ich habe einen seltsamen Fehler (oder vielleicht gibt es ein Problem in meinem Java-Code?).Clojure: Java-Interop, warum funktioniert dieser Code nicht?

hier ist der Code

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-Wrapper:

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

Im Grunde ist es eine Verteilung mit Daten innerhalb in zwei Formen: HashMaps und Arrays.

In Clojure, habe ich versucht:

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

Beide kehrt Nullpointer, NativeMethodAccessorImpl..blabla Das Gleiche gilt für die .cumulativeProbabilityMethod (auf der anderen Seite, .sample funktioniert gut, so dass es ein Problem der HashMap sein kann)

ich, dass vielleicht mcp und mp in der Konstruktor herausgefunden (die HashMaps sind) nicht richtig in den Konstruktor berechnet wurden, aber als ich versuchte:

(.get (.getMCP dist) 4) 

gibt mir das korrekte Ergebnis zurück. MCP hashmap ist in der Tat das Ergebnis, das ich erwartet habe.

Warum funktioniert mein Code nicht? Meine zwei Zeilen sind "funktional" gleich. Wenn ich einen Tippfehler gemacht habe, sehe ich es nicht. Vielleicht ist es wegen der Unveränderlichkeit Sache?

Danke!

Antwort

1

Ok, also habe ich das Problem herausgefunden, ich habe vergessen, dass Java nicht so flexibel wie Clojure mit numerischen Primitiven war.

Dieser Code funktioniert:

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

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

In Clojure Code, die Übersetzung eines Doppel automatisch. In Java habe ich einen Integer übergeben, wo die Hasmap einen Long

erwartet
Verwandte Themen