From c35dfe3739047c4252fd7723f8ed2825580fbe47 Mon Sep 17 00:00:00 2001 From: mabuni1998 Date: Mon, 19 Jun 2023 10:35:46 -0400 Subject: [PATCH] Added multiplication of LazyOperators --- src/operators_lazysum.jl | 38 +++++++++++++++++++++++++++++++ src/operators_lazytensor.jl | 9 ++++++++ test/test_operators_lazysum.jl | 12 +++++++++- test/test_operators_lazytensor.jl | 10 ++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/operators_lazysum.jl b/src/operators_lazysum.jl index c61d4eeb..ce0a3fc0 100644 --- a/src/operators_lazysum.jl +++ b/src/operators_lazysum.jl @@ -104,6 +104,44 @@ end -(a::O1, b::O2) where {O1<:LazyOperator,O2<:LazyOperator} = LazySum(a) - LazySum(b) +#*(a::LazySum{B1,B2}, b::AbstractOperator{B2,B3}) where {B1,B2,B3} = LazySum(a.basis_l, a.basis_r, a.factors, a.operators .* b) +#*(a::AbstractOperator{B1,B2}, b::LazySum{B2,B3}) where {B1,B2,B3} = LazySum(a.basis_l, b.basis_r, b.factors, a.operators .* b) + +#*(a::Operator{B1,B2}, b::LazySum{B2,B3}) where {B1,B2,B3} = LazySum(a.basis_l, b.basis_r, b.factors, a.operators .* b) +#*(a::LazySum{B1,B2}, b::Operator{B2,B3}) where {B1,B2,B3} = LazySum(a.basis_l, b.basis_r, a.factors, a.operators .* b) + + +function Base.:*(a::LazySum{B1,B2}, b::O2) where {B1,B2,O2<:LazyOperator} + c = Array{AbstractOperator}(undef,length(a.operators)) + for i in eachindex(a.operators) + c[i] = LazyProduct(a.operators[i]) * b + end + LazySum(a.basis_l, b.basis_r, a.factors, (c...,)) +end + +function Base.:*(a::O1, b::LazySum{B1,B2}) where {B1,B2,O1<:LazyOperator} + c = Array{AbstractOperator}(undef,length(b.operators)) + for i in eachindex(b.operators) + c[i] = a * LazyProduct(b.operators[i]) + end + LazySum(a.basis_l, b.basis_r, b.factors, (c...,)) +end + + +function Base.:*(a::O1, b::O2) where {O1<:LazySum,O2<:LazySum} + c = Array{AbstractOperator}(undef,length(a.operators)*length(b.operators)) + factors = similar(a.factors,length(a.operators)*length(b.operators)) + k = 1 + for i in eachindex(a.operators) + for j in eachindex(b.operators) + factors[k] = a.factors[i] * b.factors[j] + c[k] = a.operators[i] * b.operators[j] + k += 1 + end + end + LazySum(a.basis_l, b.basis_r, factors, (c...,)) +end + function *(a::LazySum, b::Number) factors = b*a.factors @samebases LazySum(a.basis_l, a.basis_r, factors, a.operators) diff --git a/src/operators_lazytensor.jl b/src/operators_lazytensor.jl index a6802f3b..ec55d1d3 100644 --- a/src/operators_lazytensor.jl +++ b/src/operators_lazytensor.jl @@ -161,6 +161,15 @@ function *(a::DenseOpType{B1,B2}, b::LazyTensor{B2,B3}) where {B1,B2,B3} result end +*(a::LazyTensor{B1,B2}, b::LazyProduct{B2,B3}) where {B1,B2,B3} = LazyProduct(a) * b +*(a::LazyProduct{B1,B2}, b::LazyTensor{B2,B3}) where {B1,B2,B3} = a * LazyProduct(b) + +#*(a::LazyTensor{B1,B2}, b::AbstractOperator{B2,B3}) where {B1,B2,B3} = LazyProduct((a, b), 1) +#*(a::AbstractOperator{B1,B2}, b::LazyTensor{B2,B3}) where {B1,B2,B3} = LazyProduct((a, b), 1) +#*(a::LazyTensor{B1,B2}, b::Operator{B2,B3}) where {B1,B2,B3} = LazyProduct((a, b), 1) +#*(a::Operator{B1,B2}, b::LazyTensor{B2,B3}) where {B1,B2,B3} = LazyProduct((a, b), 1) + + /(a::LazyTensor, b::Number) = LazyTensor(a, a.factor/b) diff --git a/test/test_operators_lazysum.jl b/test/test_operators_lazysum.jl index 887a2547..45cdb056 100644 --- a/test/test_operators_lazysum.jl +++ b/test/test_operators_lazysum.jl @@ -68,12 +68,15 @@ op1b = randoperator(b_l, b_r) op2a = randoperator(b_l, b_r) op2b = randoperator(b_l, b_r) op3a = randoperator(b_l, b_r) +op4a = randoperator(b_r, b_l) op1 = LazySum([0.1, 0.3], (op1a, sparse(op1b))) op1_ = 0.1*op1a + 0.3*op1b op2 = LazySum([0.7, 0.9], [sparse(op2a), op2b]) op2_ = 0.7*op2a + 0.9*op2b op3 = LazySum(op3a) op3_ = op3a +op4 = LazySum(op4a) +op4_ = op4a x1 = Ket(b_r, rand(ComplexF64, length(b_r))) x2 = Ket(b_r, rand(ComplexF64, length(b_r))) @@ -94,7 +97,7 @@ xbra1 = Bra(b_l, rand(ComplexF64, length(b_l))) @test 1e-14 > D(op1 + (-1*op2), op1_ - op2_) # Test multiplication -@test_throws ArgumentError op1*op2 +@test_throws DimensionMismatch op1*op2 @test LazySum([0.1, 0.1], (op1a, op2a)) == LazySum(op1a, op2a)*0.1 @test LazySum([0.1, 0.1], (op1a, op2a)) == 0.1*LazySum(op1a, op2a) @test 1e-11 > D(op1*(x1 + 0.3*x2), op1_*(x1 + 0.3*x2)) @@ -102,6 +105,13 @@ xbra1 = Bra(b_l, rand(ComplexF64, length(b_l))) @test 1e-11 > D((op1+op2)*(x1+0.3*x2), (op1_+op2_)*(x1+0.3*x2)) @test 1e-12 > D(dagger(x1)*dagger(0.3*op2), dagger(x1)*dagger(0.3*op2_)) + +@test 1e-12 > D(op1*op4,op1_*op4_) +@test 1e-12 > D(op4*op1,op4_*op1_) + +@test 1e-12 > D(LazyProduct(op1_)*op4,op1_*op4_) +@test 1e-12 > D(op4*LazyProduct(op1_),op4_*op1_) + ## Test multiplication with LazySum that has no elements @test iszero( LazySum(b_r, b_l) * op1a ) @test iszero( op1a * LazySum(b_r, b_l) ) diff --git a/test/test_operators_lazytensor.jl b/test/test_operators_lazytensor.jl index fc2f92f7..6ce8b5fe 100644 --- a/test/test_operators_lazytensor.jl +++ b/test/test_operators_lazytensor.jl @@ -105,6 +105,11 @@ op3_ = 0.3*I1 ⊗ I2 ⊗ subop3 op4 = 0.4*LazyTensor(b_l, b_r, 2, subop2) op4_ = 0.4*I1 ⊗ subop2 ⊗ I3 +subop4 = randoperator(b2b, b2a) +op5 = 0.3*LazyTensor(b_r, b_l, 2, subop4) +op5_ = 0.3*identityoperator(b1b,b1a) ⊗ subop4 ⊗ identityoperator(b3b,b3a) + + x1 = Ket(b_r, rand(ComplexF64, length(b_r))) x2 = Ket(b_r, rand(ComplexF64, length(b_r))) xbra1 = Bra(b_l, rand(ComplexF64, length(b_l))) @@ -158,6 +163,11 @@ op2_tensor_ = op1_ ⊗ subop1 @test 1e-12 > D(dagger(0.3*op2)*op1_, dagger(0.3*op2_)*op1_) @test 1e-12 > D(dagger(0.3*op2)*op1, dagger(0.3*op2_)*op1_) +@test 1e-12 > D(op5*LazySum(op1_,op2_), op5_*(op1_+op2_)) +@test 1e-12 > D(LazySum(op1_,op2_)*op5, (op1_+op2_)*op5_) +@test 1e-12 > D(op5*LazyProduct(op1_), op5_*op1_) +@test 1e-12 > D(LazyProduct(op1_)*op5, op1_*op5_) + # Test division @test 1e-14 > D(op1/7, op1_/7)