Open oschulz opened 6 months ago
@jariji , it it sufficient for you to support positive n
? Supporting negative n
would require a hard dependency on InverseFunctions and it would result in type instability (except maybe in cases of compiler constant propagation).
@uniment , I think you had use cases with a negative n
in mind, though?
I would be happy to use frepeat
with positive n
.
Could you explain why negative n
would cause type instability? Using the snippet I posted in https://github.com/JuliaMath/InverseFunctions.jl/issues/43 I'm not seeing it:
julia> @report_opt (exp∘̂(2))(ℯ)
No errors detected
julia> @report_opt (exp∘̂(-2))(ℯ)
No errors detected
Using the snippet I posted in JuliaMath/InverseFunctions.jl#43 I'm not seeing it
I think in your example that is because both exp
and log
return the same output type for a given input type. But (with your implementation from JuliaMath/InverseFunctions.jl#43):
julia> @inferred (InverseFunctions.square∘̂(2))(3)
ERROR: return type Int64 does not match inferred return type Union{Float64, Int64}
Here, square
returns an integer type for an integer input, but sqrt
always returns a floating point type, so the "if n is negative use inverse" approach cannot be type stable. The return type simply cannot be inferred at compile time, except (maybe) if n
is constant and if the implementation of ∘̂
gets inlined by the compiler.
The same issue occurs with the implementation
@inline function ∘̂(f, n::Integer)
if n == 0
identity
elseif n > 0
frepeat(f, n)
else
frepeat(inverse(f), -n)
end
end
It can be type-stable when the compiler can propagate a constant n
and inline and elide the conditional code, but it's type-unstable in general. That happens more often in this case, because the decision on which path to take is made earlier (so higher chance of constant propagation), but it's still not type-stable in general.
That being said, I'm Ok with allowing for negative n
in ∘̂
if people have use cases and aren't too worried about the type stability issue (frepeat
, on the other hand, should definitely require a non-negative n
).
Is it fair to support the n=0
case as the identity function or does that go wrong somewhere?
Is it fair to support the n=0 case as the identity function or does that go wrong somewhere?
Yes, n = 0
would be the identity.
Add a convenience function
and
Implements the functionality described in JuliaLang/julia#39042 and JuliaMath/InverseFunctions.jl#43.