diff --git a/src/channels/compositions.jl b/src/channels/compositions.jl index e2816a7..8e7325a 100644 --- a/src/channels/compositions.jl +++ b/src/channels/compositions.jl @@ -86,6 +86,17 @@ function compose(::Type{T}, Φ1::T1, Φ2::T2) where {T<:AbstractQuantumOperation convert(T, so) end +function compose(Φ1::UnitaryChannel{M1}, Φ2::UnitaryChannel{M2}) where {M1<:AbstractMatrix{<:Number}, M2<:AbstractMatrix{<:Number}} + M = promote_type(M1, M2) + compose(UnitaryChannel{M}, Φ1, Φ2) +end + +function compose(::Type{UnitaryChannel{M}}, Φ1::UnitaryChannel{M1}, Φ2::UnitaryChannel{M2}) where {M<:AbstractMatrix{<:Number}, M1<:AbstractMatrix{<:Number}, M2<:AbstractMatrix{<:Number}} + Φ1.odim == Φ2.idim ? () : throw(ArgumentError("Unitaries are incompatible")) + um = Φ1.matrix * Φ2.matrix + UnitaryChannel{M}(convert(M, um), Φ1.idim, Φ2.odim) +end + function compose(Φ1::T, Φ2::T) where {T<:AbstractQuantumOperation{<:Number}} compose(T, Φ1, Φ2) end diff --git a/test/channels.jl b/test/channels.jl index ec717b8..cdf6c86 100644 --- a/test/channels.jl +++ b/test/channels.jl @@ -136,6 +136,13 @@ end c = UnitaryChannel(Diagonal(ComplexF64[1 -1.0im])) @test c isa UnitaryChannel{<:Diagonal} + + u1 = UnitaryChannel([cos(1) sin(1); -sin(1) cos(1)]) + u2 = UnitaryChannel([cos(2) sin(2); -sin(2) cos(2)]) + @test compose(u1, u2).matrix ≈ u2.matrix * u1.matrix + @test compose(UnitaryChannel{Array{Float64,2}}, u1, u2).matrix ≈ u2.matrix * u1.matrix + + @test kron(u1, u2).matrix ≈ kron(u1.matrix, u2.matrix) end @testset "POVMMeasurement" begin