Skip to content
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

weird InexactError() #3728

Closed
autozimu opened this issue Jul 16, 2013 · 13 comments
Closed

weird InexactError() #3728

autozimu opened this issue Jul 16, 2013 · 13 comments
Labels
bug Indicates an unexpected problem or unintended behavior

Comments

@autozimu
Copy link
Contributor

screen shot 2013-07-15 at 22 58 18

OS: Mac OS X 10.8.4
Julia Version: Commit 05e64a1 2013-07-13 04:09:58

Am I doing something wrong, or is this a bug?

@aviks
Copy link
Member

aviks commented Jul 16, 2013

Looking at the code in array.jl,

This seems to occur due to

julia> typeof(real(zero(Complex)))
Int64

Defining

A=Array(Complex{Float64},1)

fixes the immediate issue, but I have no opinion on whether this issue should be considered a bug or not.

@ViralBShah
Copy link
Member

zero(Complex) should certainly not be Complex{Int64}. At the very least, it should perhaps be Complex{Float64} to be consistent with the real case.

@autozimu If you use a concrete type like Complex128 instead of an abstract type like Complex, your example will work fine. We should ensure that it works either ways. Do note that it is more efficient to use a concrete type.

@StefanKarpinski
Copy link
Sponsor Member

I'm not sure that zero(::Type{Complex}) should be defined at all – there's no canonical value for that. Perhaps if we made it so that Complex{Bool} could replace the ImaginaryUnit type, then we could use Complex(false,false) for this.

@JeffBezanson
Copy link
Sponsor Member

Oh no not this again. Using Complex{Bool} as the imaginary unit is cute, but we would have false * Inf == 0. While that's convenient in some cases, it seems too magical to have a special zero that behaves differently from other zeros, I'd almost like to think of a way to justify that behavior but I haven't thought of anything yet.

@StefanKarpinski
Copy link
Sponsor Member

We could have Zero and One constants that are MathConst{0} and MathConst{1} or something like that and then make const im = Complex(Zero,One). I think this could be made to work correctly.

@JeffBezanson
Copy link
Sponsor Member

That would lead to the undesirable situation of a complex number whose components are of different types.

@JeffBezanson
Copy link
Sponsor Member

I also don't see how that solves the multiplying by Inf problem. Then MathConst{0} would be the special value, instead of false.

@JeffBezanson
Copy link
Sponsor Member

One option is to change complex multiplication so that Inf * complex(0,0) is NaN, but if one component is nonzero and the other is zero then the zero is left alone. After all complex(0,1) does not equal zero, so multiplying by Inf might not have to give NaN.

@stevengj
Copy link
Member

I vote that we solve the issue at hand first. Why not simply define:

for f in (:real, :imag)
    @eval begin
        function ($f){T}(A::AbstractArray{Complex{T}})
            F = similar(A, T)
            for i=1:length(A)
                F[i] = ($f)(A[i])
            end
            return F
         end
    end
end
real{T<:Real}(A::AbstractArray{T}) = copy(A)
imag{T<:Real)(A::AbstractArray{T}) = zeros(T, size(A)...)

@ViralBShah
Copy link
Member

Interestingly, trying your code (there is a typo in the last imag definition),

julia> A = Array(Complex,1)
1-element Complex{T<:Real} Array:
 #undef

julia> A[1] = 0.5 + 0.5im
0.5 + 0.5im

julia> real(A)
ERROR: no method real(Array{Complex{T<:Real},1},)

@JeffBezanson
Copy link
Sponsor Member

Yes; putting Complex{T} in the signature requires that the argument specify T, but the type Complex by itself does not.

@stevengj
Copy link
Member

Whoops, I was thinking of Complex as equivalent to Complex{Real}. Just add:

         function ($f)(A::AbstractArray{Complex})
            F = similar(A, Real)
            for i=1:length(A)
                F[i] = ($f)(A[i])
            end
            return F
         end

@stevengj
Copy link
Member

Of course, one also has to audit whether any other functions fall down for Complex arguments.

StefanKarpinski added a commit that referenced this issue Jan 22, 2014
This change requires giving multiplition by Bools special behavior.
Approximately, `true * x = x` and `false * x = zero(x)`, but a bit
complicated for the sake of promotion, the only non-trivial example
of which is `Bool * MathConst`, which is promoted to Float64.

Idea originally due to @GunnarFarneback:

    https://groups.google.com/forum/#!topic/julia-dev/VkGrqnrAdaY
    #2980
    #3728
StefanKarpinski added a commit that referenced this issue Jan 22, 2014
This change requires giving multiplition by Bools special behavior.
Approximately, `true * x = x` and `false * x = zero(x)`, but a bit
complicated for the sake of promotion, the only non-trivial example
of which is `Bool * MathConst`, which is promoted to Float64.

Idea originally due to @GunnarFarneback:

    https://groups.google.com/forum/#!topic/julia-dev/VkGrqnrAdaY
    #2980
    #3728
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Indicates an unexpected problem or unintended behavior
Projects
None yet
Development

No branches or pull requests

6 participants