You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Clojure无法调用Smile 3.0.0中MathEx类的特定方法

问题:升级Smile至3.0.0后部分Java方法无法在Clojure中调用

将Smile包升级至3.0.0后,部分方法无法在Clojure中调用。Leiningen项目的project.clj中依赖配置为:

[com.github.haifengl/smile-core "3.0.0"]

在REPL中执行代码时出现如下情况:

(import smile.math.MathEx)

(MathEx/log2 5.)
=> 2.321928094887362
(MathEx/pow2 5.)
Syntax error (IllegalArgumentException) compiling . at (C:\Users\AAlmosni\AppData\Local\Temp\1\form-init13649993705313983821.clj:1:1).
No matching method pow2 found taking 1 args for class smile.math.MathEx
(MathEx/sigmoid 5.)
Syntax error (IllegalArgumentException) compiling . at (C:\Users\AAlmosni\AppData\Local\Temp\1\form-init13649993705313983821.clj:1:1).
No matching method sigmoid found taking 1 args for class smile.math.MathEx
(MathEx/isPower2 32)
=> true

这种部分方法可用、部分不可用的情况令人困惑。以下是MathEx.class的关键代码片段:

public static double log2(double x) {
    return Math.log(x) / LOG2;
}

public static double log(double x) {
    double y = -690.7755D;
    if (x > 1.0E-300D) {
        y = Math.log(x);
    }

    return y;
}

public static double log1pe(double x) {
    double y = x;
    if (x <= 15.0D) {
        y = Math.log1p(Math.exp(x));
    }

    return y;
}

public static boolean isInt(float x) {
    return x == (float)Math.floor((double)x) && !Float.isInfinite(x);
}

public static boolean isInt(double x) {
    return x == Math.floor(x) && !Double.isInfinite(x);
}

public static boolean equals(double a, double b) {
    if (a == b) {
        return true;
    } else {
        double absa = Math.abs(a);
        double absb = Math.abs(b);
        return Math.abs(a - b) <= Math.min(absa, absb) * 2.220446049250313E-16D;
    }
}

public static double sigmoid(double x) {
    x = Math.max(-36.0D, Math.min(x, 36.0D));
    return 1.0D / (1.0D + Math.exp(-x));
}

public static double pow2(double x) {
    return x * x;
}

public static boolean isPower2(int x) {
    return x > 0 && (x & x - 1) == 0;
}

原因分析与解决方法

原因

问题根源在于Clojure的Java方法解析机制,以及Smile 3.0.0中MathEx类的方法重载冲突:

  • Clojure调用Java静态方法时,会严格根据传入参数的类型匹配方法签名。如果存在同名但参数类型不同的重载方法,且Clojure无法明确推断出目标方法,就会抛出"找不到匹配方法"的错误。
  • 你提供的代码片段之外,pow2和sigmoid大概率存在其他重载版本(比如接受float类型参数的版本),而Clojure中5.是Double类型,导致重载匹配时出现歧义。
  • 而log2和isPower2能正常调用,是因为它们没有重载版本,或者重载版本的参数类型差异足够明显,Clojure可以准确匹配。

解决方法

  1. 显式指定参数类型:通过类型提示告诉Clojure要匹配的方法签名,示例如下:
; 方式一:强制转换参数类型
(MathEx/pow2 (double 5.))
(MathEx/sigmoid (double 5.))

; 方式二:使用类型注解
(MathEx/pow2 ^double 5.)
(MathEx/sigmoid ^double 5.)
  1. 查阅Smile官方文档,确认pow2和sigmoid的所有重载版本,确保调用时参数类型与目标方法完全匹配。

内容的提问来源于stack exchange,提问作者alex314159

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 12:01:52