Defining inner constructor with parametric types in Julia
Shuvomoy Das Gupta
January 12, 2021
Suppose we define the following parametric type in Julia.
abstract type CombinatorialProblem end
struct BinIntOptSF{V <: AbstractVector{<: Real}, M <: AbstractMatrix{<: Real}} <: CombinatorialProblem # means the concrete type BinIntOptSF is a subtype of the abstract type CombinatorialProblem
c::V
A::M
b::V
end
This is a parametric type. We can create an instance of this type as follows.
m = 4
n = 5
c = randn(n)
A = randn(m,n)
b = randn(m)
sf_bin_int_opt = BinIntOptSF(c, A, b)
Now suppose, we want to enforce the following check in an instance of the type: A
must have number of rows less than or equal to number of columns, number of rows of A
is equal number of entries in b
, and number of columns of A
is equal to the number of entries in c
.
In this case we can enforce the check by writing the following inner constructor for the parametric type.
struct BinIntOptSF2{V <: AbstractVector{<: Real}, M <: AbstractMatrix{<: Real}} <: CombinatorialProblem
c::V
A::M
b::V
# Inner constructor
# -----------------
function BinIntOptSF2{V,M}(c::V, A::M, b::V) where {V <: AbstractVector{<: Real}, M <: AbstractMatrix{<: Real}}
if size(A,1) != size(b,1)
error("A and b have incompatible direction")
end
if size(A,1) > size(A,2)
error("A must have number of row less than or equal to number of columns")
end
if size(A,2) != size(c,1)
error("A and c have incompatible dimension")
end
new{V, M}(c,A,b)
end
# Writing the inner constructor above is going to replace the default constructor that is automatically defined by Julia. This may cause slight inconvenience, as we have to instantiate by running: bin_opt_instance = BinIntOptSF2{.,.}(...). Fortunately we can avoid this by adding the following line.
# Ensuring the one shot instantiation
# -----------------------------------
BinIntOptSF2(c::V, A::M, b::V) where {V <: AbstractVector{<: Real}, M <: AbstractMatrix{<: Real}} = BinIntOptSF2{V,M}(c,A,b)
# We need to add this line so that we can instantiate by the convenient: bin_opt_instance = BinIntOptSF2(.). If we do not add this line, but call BinIntOptSF2(.), then we will get an error "No method matching...".
end
Let us instantiate the type above.
sf_bin_int_opt_2 = BinIntOptSF2(c, A, b)
© Shuvomoy Das Gupta. Last modified: October 11, 2024. Website built with Franklin.jl and the Julia programming language.