Skip to content

Commit 82847f5

Browse files
committed
Fix vararg methods in spinors and add tests
1 parent 1ec31a8 commit 82847f5

File tree

2 files changed

+75
-2
lines changed

2 files changed

+75
-2
lines changed

src/spinors.jl

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,20 @@ end
8383
Compute the direct sum of two operators. The result is an operator on the
8484
corresponding [`SumBasis`](@ref).
8585
"""
86-
directsum(a::DataOperator, b::DataOperator) = Operator(directsum(a.basis_l, b.basis_l), directsum(a.basis_r, b.basis_r), hcat([a.data; zeros(size(b))], [zeros(size(a)); b.data]))
86+
function directsum(a::DataOperator, b::DataOperator)
87+
dType = promote_type(eltype(a),eltype(b))
88+
data = zeros(dType, size(a,1)+size(b,1), size(a,2)+size(b,2))
89+
data[1:size(a,1),1:size(a,2)] = a.data
90+
data[size(a,1)+1:end, size(a,2)+1:end] = b.data
91+
return Operator(directsum(a.basis_l, b.basis_l), directsum(a.basis_r, b.basis_r), data)
92+
end
93+
function directsum(a::SparseOpType, b::SparseOpType)
94+
dType = promote_type(eltype(a),eltype(b))
95+
data = spzeros(dType, size(a,1)+size(b,1), size(a,2)+size(b,2))
96+
data[1:size(a,1),1:size(a,2)] = a.data
97+
data[size(a,1)+1:end, size(a,2)+1:end] = b.data
98+
return Operator(directsum(a.basis_l, b.basis_l), directsum(a.basis_r, b.basis_r), data)
99+
end
87100
directsum(a::AbstractOperator...) = reduce(directsum, a)
88101

89102
"""
@@ -124,12 +137,24 @@ mutable struct LazyDirectSum{BL<:SumBasis, BR<:SumBasis, T<:Tuple{Vararg{Abstrac
124137
basis_r::BR
125138
operators::T
126139
end
140+
141+
# Methods
127142
LazyDirectSum(op1::AbstractOperator, op2::AbstractOperator) = LazyDirectSum(directsum(op1.basis_l,op2.basis_l),directsum(op1.basis_r,op2.basis_r),(op1,op2))
143+
LazyDirectSum(op1::LazyDirectSum, op2::AbstractOperator) = LazyDirectSum(directsum(op1.basis_l,op2.basis_l),directsum(op1.basis_r,op2.basis_r),(op1.operators...,op2))
144+
LazyDirectSum(op1::AbstractOperator, op2::LazyDirectSum) = LazyDirectSum(directsum(op1.basis_l,op2.basis_l),directsum(op1.basis_r,op2.basis_r),(op1,op2.operators...))
145+
LazyDirectSum(op1::LazyDirectSum, op2::LazyDirectSum) = LazyDirectSum(directsum(op1.basis_l,op2.basis_l),directsum(op1.basis_r,op2.basis_r),(op1.operators...,op2.operators...))
128146
LazyDirectSum(op::AbstractOperator...) = reduce(LazyDirectSum, op)
147+
148+
# Algebra
129149
dense(x::LazyDirectSum) = directsum(dense.(x.operators)...)
130150
*(op1::LazyDirectSum{B1,B2},op2::LazyDirectSum{B2,B3}) where {B1<:Basis,B2<:Basis,B3<:Basis}= LazyDirectSum(op1.basis_l,op2.basis_r,Tuple(op1.operators[i]*op2.operators[i] for i=1:length(op1.operators)))
131151
-(op::LazyDirectSum) = LazyDirectSum([-op.operators[1];op.operators[2:end]]...)
132152
+(op1::LazyDirectSum{B1,B2},op2::LazyDirectSum{B1,B2}) where {B1<:Basis,B2<:Basis} = LazyDirectSum((op1.operators .+ op2.operators)...)
153+
dagger(op::LazyDirectSum) = LazyDirectSum(op.basis_r, op.basis_l, dagger.(op.operators))
154+
155+
directsum(op1::AbstractOperator,op2::LazyDirectSum) = LazyDirectSum(op1,op2)
156+
directsum(op1::LazyDirectSum,op2::AbstractOperator) = LazyDirectSum(op1,op2)
157+
directsum(op1::LazyDirectSum,op2::LazyDirectSum) = LazyDirectSum(op1,op2)
133158

134159
# Use lazy sum for FFTOperator
135160
transform(b1::SumBasis,b2::SumBasis; kwargs...) = LazyDirectSum([transform(b1.bases[i],b2.bases[i];kwargs...) for i=1:length(b1.bases)]...)

test/test_spinors.jl

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,57 @@
11
using QuantumOpticsBase
22
using Test
3-
3+
using Random
44

55
@testset "spinors" begin
66

7+
Random.seed!(0)
8+
9+
D(op1::AbstractOperator, op2::AbstractOperator) = abs(tracedistance_nh(dense(op1), dense(op2)))
10+
11+
b1a = GenericBasis(2)
12+
b1b = GenericBasis(3)
13+
b2a = GenericBasis(1)
14+
b2b = GenericBasis(4)
15+
b3a = GenericBasis(1)
16+
b3b = GenericBasis(5)
17+
18+
b_l = b1ab2ab3a
19+
b_r = b1bb2bb3b
20+
21+
op1a = randoperator(b1a, b1b)
22+
op1b = randoperator(b1a, b1b)
23+
op2a = randoperator(b2a, b2b)
24+
op2b = randoperator(b2a, b2b)
25+
op3a = randoperator(b3a, b3b)
26+
op123 = op1a op2a op3a
27+
@test op123.basis_l == b_l
28+
@test op123.basis_r == b_r
29+
30+
# Associativity
31+
@test 1e-13 > D((op1a op2a) op3a, op1a (op2a op3a))
32+
@test 1e-13 > D(op1a op2a op3a, op1a (op2a op3a))
33+
34+
# Mixed-product property
35+
@test 1e-13 > D((op1a op2a) * dagger(op1b op2b), (op1a*dagger(op1b)) (op2a*dagger(op2b)))
36+
37+
# Transpose
38+
@test 1e-13 > D(dagger(op1a op2a), dagger(op1a) dagger(op2a))
39+
@test 1e-13 > D(dagger(op1a op2a), dagger(op1a) dagger(op2a))
40+
41+
# Sparse version
42+
@test isa(sparse(op1a)sparse(op2a)sparse(op3a), SparseOpType)
43+
44+
# Test lazy implementation
45+
L = LazyDirectSum(op1a,op2a)
46+
@test 1e-13 > D(op1aop2a, L)
47+
@test 1e-13 > D(2*(op1aop2a), L+L)
48+
@test isa(L op3a, LazyDirectSum)
49+
@test 1e-13 > D(op1a op2a op3a, L op3a)
50+
@test 1e-13 > D((op1aop2a)*dagger(op1aop2a), L*L')
51+
52+
53+
### Test example
54+
755
# Define x-space
856
Nunitcells=2
957
Lx=Nunitcells/2

0 commit comments

Comments
 (0)