简体   繁体   English

Clojure:java互操作,为什么此代码不起作用?

[英]Clojure : java interop, why does this code do not work?

I coded a class using Apache Maths (whatever) and I have a weird glitch (or maybe there is a problem in my Java code ?). 我使用Apache Maths编写了一个类(无论如何),但出现了一个奇怪的小故障(或者我的Java代码是否有问题?)。

here is the 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 : 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]})

Basically it is a distribution with data inside in two forms : HashMaps and Arrays. 基本上,它是一种内部包含两种形式的数据的分布:HashMaps和Arrays。

In Clojure, I tried : 在Clojure中,我尝试了:

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

Both returns NullPointerException, NativeMethodAccessorImpl..blabla Same for the .cumulativeProbabilityMethod (on the other hand, .sample works fine so it may be a problem of HashMap) 两者都返回NullPointerException,NativeMethodAccessorImpl..blabla与.cumulativeProbabilityMethod相同(另一方面,.sample正常运行,因此可能是HashMap的问题)

I figured out that maybe in the constructor mcp and mp (that are HashMaps) were not properly calculated in the constructor but when I tried : 我发现也许在构造函数mcp和mp(即HashMaps)在构造函数中未正确计算,但是在尝试时:

(.get (.getMCP dist) 4) 

it returns me the correct result. 它给我返回正确的结果。 MCP hashmap is in fact the result I expected. MCP哈希图实际上是我期望的结果。

So why does my code does not work ? 那么为什么我的代码不起作用? My two lines are "functionally" the same. 我的两行在功能上是相同的。 If I did a typo, I do not see it. 如果输入错误,我看不到。 Maybe it's because of the immutability thing ? 也许是因为不可改变的事情?

Thanks ! 谢谢 !

Ok so I figured out the problem, I forgot that Java was not as flexible as Clojure with numeric primitives. 好的,所以我找出了问题所在,但我忘记了Java不像使用数字基元的Clojure那样灵活。

This code works : 此代码有效:

@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, the translation of a double is automatic. 在Clojure代码中,双精度翻译是自动的。 In Java I passed an Integer where the HasMap expected a Long 在Java中,我传递了一个整数,其中HasMap期望一个Long

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM