1
votes

I have a function that takes in either Float64 types or CValue types (which is a custom type defined by me)

the function is of the form:

function _Ke(T,ρ,kf,r1,r2,r3)
    Ke[r1] = _Ke_r1(T,ρ)*(1.0E-06)
    kb[r1] = _kb_r1(kf[r1],Ke[r1],ρ)
    Ke[r2] = _Ke_r2(T)*(1.0E-06)
    kb[r2] = _kb_r2(kf[r2],Ke[r2],ρ)
    Ke[r3] = _Ke_r3(T)*(1.0E-06)
    kb[r3] = _kb_r3(kf[r3],Ke[r3],ρ)
    return Ke, Kb
end

Where kf is initialized by ones(Float64, Nr) where Nr=3 in this instance.

I'm trying to set up the function so that it can output Ke and kb as a Float64 or CValue depending on the inputs to the function, but declaring:

Ke = Vector{CValue}(undef,Nr)
kf = Vector{CValue}(undef,Nr)

before calling this function seems to affect the function when I wish to only use values of Float64 not CValue. Removing them yields the error: ERROR: LoadError: UndefVarError: Ke not defined

How do I amend my function so that it can seamlessly take in Float64 or CValue without explicitly referring to either in the function?

2
Can you clarify: can Ke and Kf contain both Float64 and CValue at the same time, or is it one or the other? And what do the output types depend on, do they depend on input values or input types?DNF
so im using two sets of each variable: bkb, bkf and bKe are of type Float64 kb,kf and Ke are of type CValue They will be one or the otherqwebfub3i4u
The error is thrown because you attempt to change the contents of Ke and Kf but they do not appear in the arguments. If these are globals, then you should avoid that and instead put them in as the first argument and be explicit that you are going to change them (for which the Julia convention is to use a bang (!) at the end of the function name).Benoit Pasquier
What are bkb, bkf, bKe? They do not appear in your code example.DNF

2 Answers

1
votes

Be pedantic with vocabulary. You would want to set up a method for your function.

julia dispatches on methods on functions depending on the supplied types.

In plain English, this means a function is something with a name that can be called. Each function needs at least one method. A method is a function with specified type(s).

To use a function in two scenarios with one type each, you really want to do is write down your function twice. Once with each type.

For clarification of this, it might be elegent to write the major type you dispatch on at the beginning or the end of your argument list. I just put it at the end.

function _Ke(T,ρ,r1,r2,r3,kf::CValue)
    return kF*foo
end
function _Ke(T,ρ,r1,r2,r3,kf::Float64)
    return kF*foo
end
1
votes

I will assume that your goal is to have the type of input parameter dictating the output type. And I also assume that CValue is a kind of Float; however, if it is not the case, you can remove or amend the 'where' clause to fit your needs.

You could do that in the following way:

function foo(a::T) where {T<: AbstractFloat}
    return Vector{T}(undef, 5)
end

# here is how your type could be defined:
struct CValue <: AbstractFloat
    c::Int64
    v::Int64
end

#and you could call your function in these ways:
foo(3.)
foo(CValue(2,4))

Calls to foo will return a vector of 5 elements of uninitialized Float64 and Cvalues, respectively.