Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java lambda中使用两个流计算协方差_Java_Lambda_Statistics_Java 8_Java Stream - Fatal编程技术网

在Java lambda中使用两个流计算协方差

在Java lambda中使用两个流计算协方差,java,lambda,statistics,java-8,java-stream,Java,Lambda,Statistics,Java 8,Java Stream,假设我有两个double数组。 我一直在试验Java8中的流。我想我已经理解了主要思想 但后来我意识到我不知道如何同时操纵两条流 例如,我想计算两个数组的协方差 public class foo { public static double mean(double[] xs) { return Arrays.stream(xs).average().getAsDouble(); } public static void main(String[] args)

假设我有两个double数组。 我一直在试验Java8中的流。我想我已经理解了主要思想 但后来我意识到我不知道如何同时操纵两条流

例如,我想计算两个数组的协方差

public class foo {

    public static double mean(double[] xs) {
        return Arrays.stream(xs).average().getAsDouble();
}

    public static void main(String[] args) {
        double[] xs = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        double[] ys = {1517.93, 1757.78, 1981.1, 2215.73, 2942.66, 3558.32, 4063.91, 4521.16, 5101.76, 5234.12};

        System.out.println("Mean of xs: " + mean(xs));
        double xs_sumDeviation = Arrays.stream(xs)
            .boxed()
            .mapToDouble(d -> d.doubleValue() - mean(xs))
            .sum();
       // Covariance
        double covXY = Arrays.stream(xs, ys)
            .mapToDouble(x,y -> {
                  double numerator = (x-mean(xs)* (y-mean(ys);
                  double denominator = Math.sqrt((x-mean(xs)* (x-mean(xs));
                  return numerator / denominator;
             })
            .sum();

    }
}
谢谢你的建议

尝试1

public static double covariance(double[] xs, double[] ys) {
    double xmean = mean(xs);
    double ymean = mean(ys);
    double numerator = IntStream.range(0, Math.min(xs.length, ys.length))
            .parallel()
            .mapToDouble(i -> (xs[i] - xmean) * (ys[i] - ymean))
            .sum();
    double denominator = Math.sqrt(IntStream.range(0, xs.length)
            .parallel()
            .mapToDouble(i -> (xs[i] - xmean) * (xs[i] - xmean))
            .sum());
    return numerator / denominator;

其他FP语言具有zip操作,它从两个元素流生成一个对流。这在Java中还没有提供

但是,对于数组,您可以很容易地生成数组索引流,并让您的函数关闭数组,通过index参数访问它们

我还要警告你,在这方面

.mapToDouble(d -> d.doubleValue() - mean(xs))

您正在使您的程序复杂性为2,因为平均值在每一步都会重新计算。您应该预先计算并在lambda中结束结果。

其他FP语言具有zip操作,它从两个元素流生成一个对流。这在Java中还没有提供

但是,对于数组,您可以很容易地生成数组索引流,并让您的函数关闭数组,通过index参数访问它们

我还要警告你,在这方面

.mapToDouble(d -> d.doubleValue() - mean(xs))

您正在使您的程序复杂性为2,因为平均值在每一步都会重新计算。您应该预先计算并在lambda中结束结果。

在其他编程语言中,有一种zip函数,它接受多个iterables,并返回一个迭代器,该迭代器聚合每个iterables中的元素。例如,请参见Python库中的函数

虽然可以在Java中创建类似的函数,但很难以支持高效并行执行的方式实现它。然而,Java中有一种常用的模式,这有点不同。在您的情况下,它可能如下所示:

public static double covariance(double[] xs, double[] ys) {
    double xmean = mean(xs);
    double ymean = mean(ys);
    return IntStream.range(0, Math.min(xs.length, ys.length))
        .parallel()
        .mapToDouble(i -> {
                double numerator = (xs[i] - xmean) * (ys[i] - ymean);
                double denominator = ...;
                return numerator / denominator;
            })
        .sum();
}

您不需要合并两个流,而是创建一个包含所有索引的IntStream,并通过索引访问不同集合的元素。只要集合支持随机访问操作,这就可以很好地工作。

在其他编程语言中,有一种zip函数,它接受多个iterables,并返回一个迭代器,该迭代器聚合每个iterables中的元素。例如,请参见Python库中的函数

虽然可以在Java中创建类似的函数,但很难以支持高效并行执行的方式实现它。然而,Java中有一种常用的模式,这有点不同。在您的情况下,它可能如下所示:

public static double covariance(double[] xs, double[] ys) {
    double xmean = mean(xs);
    double ymean = mean(ys);
    return IntStream.range(0, Math.min(xs.length, ys.length))
        .parallel()
        .mapToDouble(i -> {
                double numerator = (xs[i] - xmean) * (ys[i] - ymean);
                double denominator = ...;
                return numerator / denominator;
            })
        .sum();
}

您不需要合并两个流,而是创建一个包含所有索引的IntStream,并通过索引访问不同集合的元素。只要集合支持随机访问操作,这就可以很好地工作。

还有什么问题吗?对不起。问题是如何实现java lambda表达式来计算两个数组的协方差。问题是什么?对不起。问题是如何实现java lambda表达式来计算两个数组的协方差。谢谢。现在我学习使用lambda表达式的另一种方法。函数Math.sqrt应仅在求和后应用于分母。我想这就是你为什么写。。。但这是否意味着我必须计算另一条流中的分母?@CheJharia:我使用了。。。关注要点。其目的是保持原始语义。这将有助于了解协方差函数的非流实现,因为有不同种类的方差和协方差。谢谢。现在我学习使用lambda表达式的另一种方法。函数Math.sqrt应仅在求和后应用于分母。我想这就是你为什么写。。。但这是否意味着我必须计算另一条流中的分母?@CheJharia:我使用了。。。关注要点。其目的是保持原始语义。这将有助于看到协方差函数的非流实现,因为有不同种类的方差和协方差。