I want to write a Julia program which performs matrix operations such as matrix multiplication, diagonalization, etc. The matrices are user given and read from a file. All matrix operations are formally identical for real or complex matrices, so this is actually a perfect example for a multiple dispatch design Julia. I only have to write one single code, which can handle both cases, all real or all complex.
For instance, I could write all function arguments like
function MatrixOperations(M1::Matrix{<:Number})::Matrix{<:Number}
# my code
end
However, if the matrices are all real or all complex is decided only during runtime (via user input).
What is best practice to treat this scenario?
In principle the following would do the job:
# user given type info in string TypeInfo
if TypeInfo == "real"
M = Matrix{Float64}(undef, size)
else
M = Matrix{ComplexF64}(undef, size)
end
read!("matrixfile.bin", M)
However, my gut feeling tells me that
Are there more elegant ways to handle that in Julia? What would be best practice here?
Based on your requirements, as I understand them:
Given these points, I don't see any way outside of using a branch (if/else, ternary operator, or try/catch), and then creating a matrix based on that.
The best solution is the one you suggested in your OP:
# user given type info in string TypeInfo
if TypeInfo == "real"
M = Matrix{Float64}(undef, size)
else
M = Matrix{ComplexF64}(undef, size)
end
read!("matrixfile.bin", M)
It is simple and clear, and will also be efficient. There is a cost to dynamic dispatch, but it will probably be in the microseconds range, so as long as it happens a single time, it is negligible. The problem with dynamic dispatch is mainly when it occurs millions of times inside a hot loop.