Defining function that accepts both FP32 and FP64

Hi, I’m just starting out with Julia and ran into a weird issue. I defined a function that can take float values (fp32 or fp64, but strictly no int) as follows

function elim(A::Array{float},b::Array{float})
    Function which transforms matrix
    A into upper triangular matrix U
    n = size(b)[1]
    # Pick a pivot row
    for k in 1:n-1
        for i in k+1:n
            if A[i,k] != 0
                lambda = A[i,k]/A[k,k]
                A[i,k+1:n] -= lambda*A[k,k+1:n]
                b[i,:] -= lambda*b[k,:]
    return A, b

Now when I call this function and give inputs as Float32

A = [[6, -4, 1] [-4, 6, -4] [1, -4, 6]]
b = [[-14, 36, 6] [22, -18, 7]];
A = Float32.(A)
b = Float32.(b);

U, b_t = elim(A,b)
show(stdout, "text/plain", U)
show(stdout, "text/plain", b_t)

I get an error saying

MethodError: no method matching elim(::Array{Float32,2}, ::Array{Float32,2})

 [1] top-level scope at In[3]:1
 [2] include_string(::Function, ::Module, ::String, ::String) at ./loading.jl:1091

I get the same error when I input Float64. Is there any way that I can define a function that takes both Float32 and Float64? I don’t want to define two separate functions as it’ll just clutter everything for no reason.


It is best practice to make the type signature as loose as possible to have generic and reusable code.

elim(A:: Matrix{<: AbstractFloat},...) # for accepting all Floats

or even

elim(A:: Matrix,...) # for all element types

Note that Matrix is a 2-dim array, which is probably a restriction that you want (1d or 3d arrays will not work in your code/ do not make sense).

Or is there a specific reason why you want to exclude integer element types?


I am using AbstractFLoat now but as elim(A::Array{<:AbstractFloat},b::Array{<:AbstractFloat}). I hope this doesn’t make any difference.

I don’t want to use Integers because I get an error

InexactError: Int64(3.3333333333333335)

 [1] Int64 at ./float.jl:710 [inlined]
 [2] convert at ./number.jl:7 [inlined]
 [3] setindex! at ./array.jl:849 [inlined]
 [4] macro expansion at ./multidimensional.jl:802 [inlined]
 [5] macro expansion at ./cartesian.jl:64 [inlined]
 [6] macro expansion at ./multidimensional.jl:797 [inlined]
 [7] _unsafe_setindex!(::IndexLinear, ::Array{Int64,2}, ::Array{Float64,1}, ::Int64, ::UnitRange{Int64}) at ./multidimensional.jl:789
 [8] _setindex! at ./multidimensional.jl:785 [inlined]
 [9] setindex! at ./abstractarray.jl:1153 [inlined]
 [10] elim(::Array{Int64,2}, ::Array{Int64,2}) at ./In[1]:13
 [11] top-level scope at In[3]:1
 [12] include_string(::Function, ::Module, ::String, ::String) at ./loading.jl:1091

I think I’m getting this error because I’m reusing the input matrices to store my solution (solution is float and when input is int, it’s giving some error). I might be wrong here, but I would like to know the exact reason of this error.

Dividing two integers gives a float in Julia:

julia> 4 / 3

The InexactError is because you are trying to convert a float to an integer:

julia> Int(4/3)
ERROR: InexactError: Int64(1.3333333333333333)
 [1] Int64(::Float64) at ./float.jl:710
 [2] top-level scope at REPL[12]:1
 [3] run_repl(::REPL.AbstractREPL, ::Any) at /build/julia/src/julia-1.5.3/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:288

You need to perform a truncation or rounding before Julia will let you do that.


Note that if you want C-like (or Python2-like) truncating integer division you should use div(a,b) (or equivalently a ÷ b) rather than a / b.

1 Like