-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sincos is broken for nonstandard types #22095
Comments
What's an example of non-standard The fallback method is defined for |
julia> using IntervalArithmetic
julia> a = (1..1) + (2..2)*im
[1, 1] + [2, 2]*im
julia> typeof(a)
Complex{IntervalArithmetic.Interval{Float64}}
julia> sin(a)
ERROR: TypeError: sin: in typeassert, expected AbstractFloat, got IntervalArithmetic.Interval{Float64}
Stacktrace:
[1] sincos at ./math.jl:428 [inlined]
[2] sin(::Complex{IntervalArithmetic.Interval{Float64}}) at ./complex.jl:701 |
k. so it's throwing an error due to Line 313 in 3e3f966
float doesn't return an AbstractFloat . The assertion is to avoid infinite recursion so it shouldn't be removed. The alternative way I've thought about but decide not to do before seeing a float that triggers the assertion is
function sincos_fast(v::Real)
vf = float(v)
if isa(vf, AbstractFloat)
sincos_fast(vf)
else
sin_fast(vf), cos_fast(vf)
end
end Another way is to restrict the input type to sincos_fast(v::Integer) = sincos_fast(float(v)) And rely on |
Ah, I see, thanks. And you can't just have two different fallbacks, one for |
There are two fallbacks Lines 312 to 314 in 3e3f966
isa(vf, AbstractFloat) method is basically implementing an fallback for Real .
|
There are other functions that don't work with |
Also julia> using IntervalArithmetic
julia> z = (1.1..1.2) + (2.1..2.2)im
[1.09999, 1.20001] + [2.09999, 2.20001]*im
julia> log(z)
ERROR: StackOverflowError:
Stacktrace:
[1] log(::Complex{IntervalArithmetic.Interval{Float64}}) at ./complex.jl:470 (repeats 80000 times) |
...and also julia> sinpi((1..2) + (3..4)im)
ERROR: StackOverflowError:
Stacktrace:
[1] sinpi(::IntervalArithmetic.Interval{Float64}) at ./special/trig.jl:220 (repeats 80000 times)
julia> cospi((1..2) + (3..4)im)
ERROR: StackOverflowError:
Stacktrace:
[1] cospi(::IntervalArithmetic.Interval{Float64}) at ./special/trig.jl:221 (repeats 80000 times)
julia> sinc((1..2) + (3..4)im)
ERROR: StackOverflowError:
Stacktrace:
[1] sinc(::Complex{IntervalArithmetic.Interval{Float64}}) at ./special/trig.jl:298 (repeats 80000 times)
julia> cosc((1..2) + (3..4)im)
ERROR: StackOverflowError:
Stacktrace:
[1] cosc(::Complex{IntervalArithmetic.Interval{Float64}}) at ./special/trig.jl:310 (repeats 80000 times) |
Thanks for the list. |
@yuyichao What is special about |
where? |
In |
There are lots of cases where One option would be to simply let it throw a Another option would be to use something like function forcefloat(v)
f = float(v)
typeof(f) === typeof(v) && error("float(::",typeof(v),") produces a result of the same type")
return f
end (The compiler optimizes out the type check in cases where inference succeeds.) |
This case is irrelevant since it's not
I don't think that fixes any problem? You will get a infinite recursion.
It's basically what the current code is doing. |
I figure there's an obvious reason, but why? |
I did not know any exception so I have no way to back it up in case anyone asks (and I'm 100% sure someone would). Especially since the infinite recursion in other functions clearly shows that it is not currently done in any other part in Base. |
Yes, I believe there are several places in Base where it's implicitly assumed that |
My question was more along the lines of "why is It is definitely a bug that all these complex functions that have relatively easy fallback definitions in terms of their real counterparts (ignoring subtleties of branch cuts etc) do not work for such "non-standard" complex types. |
@yuyichao, "infinite recursion" is not infinite because it eventually throws a StackOverflowError. So, it's basically a choice between throwing one exception or another, no? The point of my |
How about
|
No. It's because the fallback is defined for
..... Errr, well, StackOverflowError IS infinite recursion, in that real infinite recursion (without overflowing the stack) will not happen currently. If you don't like how it is described I can use "useless/unhelpful error". Note that this is also a case where if we disable certain codegen llvm options can actually infinitely recurse without raising any error.
There could be cases where this is the case. Certainly not for
I personally prefer not using |
Due to
julia/base/math.jl
Line 428 in 3e3f966
This breaks
sin
,cos
,exp
etc. forComplex{T}
with non-standardT
(i.e. notFloat64
,Float32
), that previously worked fine (but apparently weren't tested).Presumably it's sufficient to restrict the argument type of the above
sincos
definition and add a generic fallback? Should that beor is there a better solution?
The text was updated successfully, but these errors were encountered: