Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Error differentiating through complex power due to isinteger

未关闭
#637 6 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
3/5
预计耗时
1-2 天
新手友好度
38/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
停滞
技术栈
julia
领域
devtools

调研方向

首先使用 ForwardDiff.Dual 值复现所提供的 MWE,并阅读 Julia 的 complex.jl 中 _cpow 的实现,尤其是 isinteger 检查以及随后转换为 Int 的过程。确定应如何处理 Dual 的偏导数,并验证复数幂的求导能够在不出现所报告的 InexactError 的情况下完成。

由索引模型根据 Issue 内容生成。

描述

I have a weird case where a complex power is giving me an inexact error because the _cpow helper function determines my object to be an integer.

Truncated error message:

julia> ForwardDiff.gradient(test_func, ptest)
ERROR: InexactError: Int(Int64, Dual{ForwardDiff.Tag{typeof(test_func), Float64}}(1.0,-0.0,-0.8333333333333333,-0.0,-0.0,-0.17599538919114094))
Stacktrace:
  [1] Int64
    @ ~/.julia/packages/ForwardDiff/QdStj/src/dual.jl:364 [inlined]
  [2] convert(#unused#::Type{Int64}, x::ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_func), Float64}, Float64, 5})                                  
    @ Base ./number.jl:7
  [3] _cpow(z::Complex{ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_func), Float64}, Float64, 5}}, p::ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_func), Float64}, Float64, 5})
    @ Base ./complex.jl:782
  [4] ^
    @ ./complex.jl:851 [inlined]
  [5] ^
    @ ./complex.jl:866 [inlined]

So given that

julia> typeof(test_func)
typeof(test_func) (singleton type of function test_func, subtype of Function)

It seems that we can get the following MWE:

julia> isinteger(Dual{ForwardDiff.Tag{Function, Float64}}(1.0,-0.0,-0.8333333333333333,-0.0,-0.0,-0.17599538919114094))
true

This is the associated culprit line in complex.jl that tries to do this conversion to Int (only the relevant part is shown):

# _cpow helper function to avoid method ambiguity with ^(::Complex,::Real)
function _cpow(z::Union{T,Complex{T}}, p::Union{T,Complex{T}}) where T
    z = float(z)
    p = float(p)
    Tf = float(T)
    if isreal(p)
        pᵣ = real(p)
        if isinteger(pᵣ) && abs(pᵣ) < typemax(Int32) 
            # |p| < typemax(Int32) serves two purposes: it prevents overflow
            # when converting p to Int, and it also turns out to be roughly
            # the crossover point for exp(p*log(z)) or similar to be faster.
            if iszero(pᵣ) # fix signs of imaginary part for z^0
                zer = flipsign(copysign(zero(Tf),pᵣ), imag(z))
                return Complex(one(Tf), zer)
            end
            ip = convert(Int, pᵣ) # <--- HERE!

Admittedly, I am not sure if the partials should be considered for determining if it's an integer or not.

主要语言
Julia
星标
1k
派生
162
PR 合并指标
30 天内没有已合并 PR

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

JuliaDiff/ForwardDiff.jl 的其他 Issue

查看 JuliaDiff/ForwardDiff.jl 的全部 Issue

相似的 Issue

更多 Julia Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。