Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define an array of any float type in Julia?

Tags:

types

julia

I tried Array{AbstractFloat,1}, but this does not work as Array{Float64,1} <: Array{AbstractFloat,1} is false, even though Float64 <: AbstractFloat is true.

like image 815
Dima Lituiev Avatar asked Nov 30 '25 08:11

Dima Lituiev


1 Answers

If you want an vector which can contain any kind of floating-point value, then the correct type is Vector{AbstractFloat}, which can be constructed like this:

julia> v = AbstractFloat[]
AbstractFloat[]

julia> push!(v, 1.5)
1-element Vector{AbstractFloat}:
 1.5

julia> push!(v, big(2.0)^1000)
2-element Vector{AbstractFloat}:
 1.5
 1.071508607186267320948425049060001810561404811705533607443750388370351051124936e+301

julia> map(typeof, v)
2-element Vector{DataType}:
 Float64
 BigFloat

julia> push!(v, "oy, I'm not a float!")
ERROR: MethodError: Cannot `convert` an object of type String to an object

You are correct that Vector{Float64} is not a subtype of Vector{AbstractFloat}. This is because subtyping of parametric types in Julia is invariant (not covariant or even contravariant). Even more generally, no concrete type is a subtype of any other concrete type and Vector{Float64} and Vector{AbstractFloat} are both concrete types since they are the types of actual objects:

julia> typeof(v)
Vector{AbstractFloat} = Array{AbstractFloat,1}

julia> typeof([1.5])
Vector{Float64} = Array{Float64,1}

If you want an abstract type which includes both of these concrete types as well as any other vector of floating-point values, that can be expressed as Vector{<:AbstractFloat}:

julia> Vector{AbstractFloat} <: Vector{<:AbstractFloat}
true

julia> Vector{Float64} <: Vector{<:AbstractFloat}
true

julia> Vector{Union{Float64, BigFloat}} <: Vector{<:AbstractFloat}
true

julia> Vector{String} <: Vector{<:AbstractFloat}
false

However, this type is abstract and you cannot create an instance of it. You can, however, use it for dispatch and write a method that will apply to any vector of floating-point values:

f(v::Vector{<:AbstractFloat}) = "a vector of floats"
f(v::Vector) = "a vector but not of floats"
f(x::Any) = "not a vector at all"

Here's this function in action:

julia> f(v)
"a vector of floats"

julia> f([1.5])
"a vector of floats"

julia> f(Union{Float64,BigFloat}[1.5, big(2.0)])
"a vector of floats"

julia> f([1, 2, 3])
"a vector but not of floats"

julia> f("nope")
"not a vector at all"

In short, the element type of a vector has to be an actual type, such as Float64 or AbstractFloat. You can expess the set of types of all floating-point vectors as Vector{<:AbstractFloat} but this cannot be the type of any vector because <:AbstractFloat is not a type, it's an upper bound on types. You can, however, use Vector{<:AbstractFloat} to define methods which operate on any vector of floats, regardless of specific element type (as long as the element type is some kind of float).

like image 54
StefanKarpinski Avatar answered Dec 02 '25 03:12

StefanKarpinski



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!