Java IntStream、Range和mapToDouble和reduce函数在C中的等价性#
有人能帮我做下面几行Java的工作吗?或者你能给出下面代码行的C#等价物吗
public static double[] logSumExp(List<Double> a, List<Double> b) {
double amax = Collections.max(a);
double sum = IntStream.range(0, a.size())
.mapToDouble(i -> Math.exp(a.get(i) - amax) * (i < b.size() ? b.get(i) : 1.0))
.reduce(0.0, Double::sum);
double sign = Math.signum(sum);
sum *= sign;
double abs = Math.log(sum) + amax;
double[] ret = {abs, sign};
return ret;
}
# 1 楼答案
在Java中使用流的代码通常可以很好地转换为LINQ。净
map
或mapToXXX
的工作原理类似于Select
,reduce
是Aggregate
,但这里Sum
更方便IntStream.range
是Enumerable.Range
。其他一切都应该有一个“明显的”等价物如果您使用的是C#7+,那么实际上应该返回一个元组:
# 2 楼答案
C#等价代码
# 3 楼答案
这个函数的作用的详细答案在这个LogSumExp Wikipedia Page中得到了很好的解释。它通常被简称为LSE或softmax
该链接还解释了为什么在应用指数并在末尾添加最大值之前,需要从每个值中减去最大值
关于Java/C#转换,Java Streams操作与LINQ操作非常相似。对于这种特定的情况,文字转换应该是简单的,因为几乎所有方法的名称都是相同的(注意命名约定)
不太明显的是:
Collections.max
是一个名为Max
的简单LINQ扩展方法,可直接应用于列表李>IntStream
只是Enumerable
,还有一个方法Range
李>mapToDouble
可以通过{Sum
李>希望这些信息对您有用