Interpreting your request literally, I defined Foo and its constructor like this:
# Copyright Β© 2021: Neven Sajko
#
# Licensed under the MIT license.
using LinearAlgebra
struct Foo{
S <: Number,
Ta <: Union{<:AbstractMatrix, <:Cholesky},
Tb <: Union{<:AbstractMatrix, <:Cholesky},
}
a :: Ta
b :: Tb
# NOTE: the inner constructor methods are not meant to be used directly,
# use the outer constructor methods instead!
function Foo{S, Ta, Tb}(
a :: AbstractMatrix{S},
b :: AbstractMatrix{S},
) where {
S <: Number,
Ta <: AbstractMatrix{S},
Tb <: AbstractMatrix{S},
}
typeof(a) === Ta || error("type parameter 1 disagrees with the argument type")
typeof(b) === Tb || error("type parameter 2 disagrees with the argument type")
new{S, Ta, Tb}(a, b)
end
function Foo{S, Ta, Tb}(
a :: Cholesky{S, A1},
b :: Cholesky{S, A2},
) where {
S <: Number,
A1 <: AbstractMatrix{S},
A2 <: AbstractMatrix{S},
Ta <: Cholesky{S, A1},
Tb <: Cholesky{S, A2},
}
typeof(a) === Ta || error("type parameter 1 disagrees with the argument type")
typeof(b) === Tb || error("type parameter 2 disagrees with the argument type")
new{S, Ta, Tb}(a, b)
end
end
function Foo(
a :: AbstractMatrix{S},
b :: AbstractMatrix{S},
) where {
S <: Number,
}
Foo{S, typeof(a), typeof(b)}(a, b)
end
function Foo(
a :: Cholesky{S, A1},
b :: Cholesky{S, A2},
) where {
S <: Number,
A1 <: AbstractMatrix{S},
A2 <: AbstractMatrix{S},
}
Foo{S, Cholesky{S, A1}, Cholesky{S, A2}}(a, b)
end
Example REPL session:
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.5.4 (2021-03-11)
_/ |\__'_|_|_|\__'_| |
|__/ |
julia> include("zsoerenm.jl")
Foo
julia> A = [4. 12. -16.; 12. 37. -43.; -16. -43. 98.]
3Γ3 Array{Float64,2}:
4.0 12.0 -16.0
12.0 37.0 -43.0
-16.0 -43.0 98.0
julia> Foo(A, A)
Foo{Float64,Array{Float64,2},Array{Float64,2}}([4.0 12.0 -16.0; 12.0 37.0 -43.0; -16.0 -43.0 98.0], [4.0 12.0 -16.0; 12.0 37.0 -43.0; -16.0 -43.0 98.0])
julia> D = Diagonal(A)
3Γ3 Diagonal{Float64,Array{Float64,1}}:
4.0 β
β
β
37.0 β
β
β
98.0
julia> Foo(D, D)
Foo{Float64,Diagonal{Float64,Array{Float64,1}},Diagonal{Float64,Array{Float64,1}}}([4.0 0.0 0.0; 0.0 37.0 0.0; 0.0 0.0 98.0], [4.0 0.0 0.0; 0.0 37.0 0.0; 0.0 0.0 98.0])
julia> CA = cholesky(A)
Cholesky{Float64,Array{Float64,2}}
U factor:
3Γ3 UpperTriangular{Float64,Array{Float64,2}}:
2.0 6.0 -8.0
β
1.0 5.0
β
β
3.0
julia> CD = cholesky(D)
Cholesky{Float64,Diagonal{Float64,Array{Float64,1}}}
U factor:
3Γ3 Diagonal{Float64,Array{Float64,1}}:
2.0 β
β
β
6.08276 β
β
β
9.89949
julia> Foo(CA, CD)
Foo{Float64,Cholesky{Float64,Array{Float64,2}},Cholesky{Float64,Diagonal{Float64,Array{Float64,1}}}}(Cholesky{Float64,Array{Float64,2}}([2.0 6.0 -8.0; 12.0 1.0 5.0; -16.0 -43.0 3.0], 'U', 0), Cholesky{Float64,Diagonal{Float64,Array{Float64,1}}}([2.0 0.0 0.0; 0.0 6.082762530298219 0.0; 0.0 0.0 9.899494936611665], 'U', 0))
Keep in mind that:
-
You may have asked an overly specific question. That is, while I think that I answered your question, your question may have been the wrong question to ask.
-
Someone who isnβt as new to Julia as I am may be able to improve on my code.
-
Your question was actually also somewhat ambiguous regarding the Cholesky types, so my interpretation of the question may not align completely with what you thought you wanted.