有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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;
  }

共 (3) 个答案

  1. # 1 楼答案

    在Java中使用流的代码通常可以很好地转换为LINQ。净

    mapmapToXXX的工作原理类似于SelectreduceAggregate,但这里Sum更方便IntStream.rangeEnumerable.Range。其他一切都应该有一个“明显的”等价物

    public static double[] LogSumExp(IList<double> a, IList<double> b) {
        double amax = a.Max();
        double sum = Enumerable.Range(0, a.Count)
                        .Select(i => Math.Exp(a[i] - amax) * (i < b.Count ? b[i] : 1.0))
                        .Sum();
        double sign = Math.Sign(sum);
        sum *= sign;
        double abs = Math.Log(sum) + amax;
        double[] ret = {abs, sign};
        return ret;
    }
    

    如果您使用的是C#7+,那么实际上应该返回一个元组:

    public static (double abs, double sign) LogSumExp(IList<double> a, IList<double> b) {
        ...
        return (abs, sign);
    }
    
  2. # 2 楼答案

    C#等价代码

        public static double[] logSumExp(List<Double> a, List<Double> b)
        {
            double amax = a.Max();
            double sum = Enumerable.Range(0, a.Count()).Sum(i => Math.Exp(a[i] - amax) * (i < b.Count() ? b[i] : 1.0));
            double sign = Math.Sign(sum);
            sum *= sign;
            double abs = Math.Log(sum) + amax;
            double[] ret = {abs, sign};
            return ret;
        }
    
  3. # 3 楼答案

    这个函数的作用的详细答案在这个LogSumExp Wikipedia Page中得到了很好的解释。它通常被简称为LSE或softmax

    该链接还解释了为什么在应用指数并在末尾添加最大值之前,需要从每个值中减去最大值

    关于Java/C#转换,Java Streams操作与LINQ操作非常相似。对于这种特定的情况,文字转换应该是简单的,因为几乎所有方法的名称都是相同的(注意命名约定)

    不太明显的是:

    • Collections.max是一个名为Max的简单LINQ扩展方法,可直接应用于列表
    • IntStream只是Enumerable,还有一个方法Range
    • mapToDouble可以通过{}在LINQ中实现
    • ^在这种情况下,{}可以替换为Sum

    希望这些信息对您有用