From d29d930650ddbb918906b72c639db16464acd2be Mon Sep 17 00:00:00 2001 From: sagnikpal2004 Date: Mon, 23 Dec 2024 16:38:27 +0530 Subject: [PATCH 01/14] add RGate --- ext/QuantumOpticsExt/QuantumOpticsExt.jl | 10 +++++++++- src/QSymbolicsBase/predefined.jl | 12 ++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/ext/QuantumOpticsExt/QuantumOpticsExt.jl b/ext/QuantumOpticsExt/QuantumOpticsExt.jl index fff1fd5..9ee3e7c 100644 --- a/ext/QuantumOpticsExt/QuantumOpticsExt.jl +++ b/ext/QuantumOpticsExt/QuantumOpticsExt.jl @@ -4,7 +4,7 @@ using QuantumInterface, QuantumOpticsBase using QuantumInterface: samebases using QuantumSymbolics using QuantumSymbolics: - HGate, XGate, YGate, ZGate, CPHASEGate, CNOTGate, PauliP, PauliM, + HGate, XGate, YGate, ZGate, RGate, CPHASEGate, CNOTGate, PauliP, PauliM, XCXGate, XCYGate, XCZGate, YCXGate, YCYGate, YCZGate, ZCXGate, ZCYGate, ZCZGate, XBasisState, YBasisState, ZBasisState, NumberOp, CreateOp, DestroyOp, @@ -31,6 +31,13 @@ const _z = sigmaz(_b2) const _x = sigmax(_b2) const _y = sigmay(_b2) const _hadamard = (sigmaz(_b2)+sigmax(_b2))/√2 +const _r(g::RGate) = if g.dir == :x + cos(g.θ/2)*_id - im*sin(g.θ/2)*_x +elseif g.dir == :y + cos(g.θ/2)*_id - im*sin(g.θ/2)*_y +elseif g.dir == :z + cos(g.θ/2)*_id - im*sin(g.θ/2)*_z +end const _cnot = _l00⊗_id + _l11⊗_x const _cphase = _l00⊗_id + _l11⊗_z const _phase = _l00 + im*_l11 @@ -47,6 +54,7 @@ express_nolookup(::HGate, ::QuantumOpticsRepr) = _hadamard express_nolookup(::XGate, ::QuantumOpticsRepr) = _x express_nolookup(::YGate, ::QuantumOpticsRepr) = _y express_nolookup(::ZGate, ::QuantumOpticsRepr) = _z +express_nolookup(g::RGate, ::QuantumOpticsRepr) = _r(g) express_nolookup(::CPHASEGate, ::QuantumOpticsRepr) = _cphase express_nolookup(::CNOTGate, ::QuantumOpticsRepr) = _cnot diff --git a/src/QSymbolicsBase/predefined.jl b/src/QSymbolicsBase/predefined.jl index 789f045..3ebe97e 100644 --- a/src/QSymbolicsBase/predefined.jl +++ b/src/QSymbolicsBase/predefined.jl @@ -106,6 +106,14 @@ symbollabel(::HGate) = "H" ishermitian(::HGate) = true isunitary(::HGate) = true +@withmetadata struct RGate <: AbstractSingleQubitGate + dir::Symbol + θ::Float64 +end +symbollabel(g::RGate) = "R$(g.dir)($(g.θ))" +ishermitian(::RGate) = true +isunitary(::RGate) = true + @withmetadata struct CNOTGate <: AbstractTwoQubitGate end symbollabel(::CNOTGate) = "CNOT" ishermitian(::CNOTGate) = true @@ -143,6 +151,10 @@ const Pm = const σ₋ = PauliM() const Pp = const σ₊ = PauliP() """Hadamard gate""" const H = HGate() +"""Rotation gates""" +const Rx(θ::Float64) = RGate(:x, θ) +const Ry(θ::Float64) = RGate(:y, θ) +const Rz(θ::Float64) = RGate(:z, θ) """CNOT gate""" const CNOT = CNOTGate() """CPHASE gate""" From 62c2ff2c01698f51d68b8447b4ca0f6225ff86c9 Mon Sep 17 00:00:00 2001 From: sagnikpal2004 Date: Tue, 24 Dec 2024 11:07:31 +0530 Subject: [PATCH 02/14] export --- src/QSymbolicsBase/QSymbolicsBase.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/QSymbolicsBase/QSymbolicsBase.jl b/src/QSymbolicsBase/QSymbolicsBase.jl index 955a40d..46bc977 100644 --- a/src/QSymbolicsBase/QSymbolicsBase.jl +++ b/src/QSymbolicsBase/QSymbolicsBase.jl @@ -27,7 +27,7 @@ export SymQObj,QObj, tensor,⊗, dagger,projector,commutator,anticommutator,conj,transpose,inv,exp,vec,tr,ptrace, I,X,Y,Z,σˣ,σʸ,σᶻ,Pm,Pp,σ₋,σ₊, - H,CNOT,CPHASE,XCX,XCY,XCZ,YCX,YCY,YCZ,ZCX,ZCY,ZCZ, + H,Rx,Ry,Rz,CNOT,CPHASE,XCX,XCY,XCZ,YCX,YCY,YCZ,ZCX,ZCY,ZCZ, X1,X2,Y1,Y2,Z1,Z2,X₁,X₂,Y₁,Y₂,Z₁,Z₂,L0,L1,Lp,Lm,Lpi,Lmi,L₀,L₁,L₊,L₋,L₊ᵢ,L₋ᵢ, vac,F₀,F0,F₁,F1,inf_fock_basis, N,n̂,Create,âꜛ,Destroy,â,basis,SpinBasis,FockBasis, @@ -40,7 +40,7 @@ export SymQObj,QObj, SConjugate,STranspose,SProjector,SDagger,SInvOperator,SExpOperator,SVec,STrace,SPartialTrace, MixedState,IdentityOp, SApplyKet,SApplyBra,SMulOperator,SSuperOpApply,SCommutator,SAnticommutator,SBraKet,SOuterKetBra, - HGate,XGate,YGate,ZGate,CPHASEGate,CNOTGate, + HGate,XGate,YGate,ZGate,RGate,CPHASEGate,CNOTGate, XBasisState,YBasisState,ZBasisState,FockState,CoherentState,SqueezedState, NumberOp,CreateOp,DestroyOp,PhaseShiftOp,DisplaceOp,SqueezeOp, XCXGate,XCYGate,XCZGate,YCXGate,YCYGate,YCZGate,ZCXGate,ZCYGate,ZCZGate, From 45d8269c6e35c0747224ed6a508b961d69674045 Mon Sep 17 00:00:00 2001 From: sagnikpal2004 Date: Tue, 24 Dec 2024 14:46:19 +0530 Subject: [PATCH 03/14] update docstring --- src/QSymbolicsBase/predefined.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/QSymbolicsBase/predefined.jl b/src/QSymbolicsBase/predefined.jl index 3ebe97e..3c594a1 100644 --- a/src/QSymbolicsBase/predefined.jl +++ b/src/QSymbolicsBase/predefined.jl @@ -151,9 +151,11 @@ const Pm = const σ₋ = PauliM() const Pp = const σ₊ = PauliP() """Hadamard gate""" const H = HGate() -"""Rotation gates""" +"""Rotation X gate""" const Rx(θ::Float64) = RGate(:x, θ) +"""Rotation Y gate""" const Ry(θ::Float64) = RGate(:y, θ) +"""Rotation Z gate""" const Rz(θ::Float64) = RGate(:z, θ) """CNOT gate""" const CNOT = CNOTGate() From acfcc5a9cd5415bbbb9427a4b239c7ca5a0ae77c Mon Sep 17 00:00:00 2001 From: sagnikpal2004 Date: Wed, 23 Apr 2025 12:12:53 -0400 Subject: [PATCH 04/14] terminterface defs --- src/QSymbolicsBase/predefined.jl | 41 ++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/src/QSymbolicsBase/predefined.jl b/src/QSymbolicsBase/predefined.jl index 3c594a1..8853e84 100644 --- a/src/QSymbolicsBase/predefined.jl +++ b/src/QSymbolicsBase/predefined.jl @@ -106,13 +106,36 @@ symbollabel(::HGate) = "H" ishermitian(::HGate) = true isunitary(::HGate) = true -@withmetadata struct RGate <: AbstractSingleQubitGate - dir::Symbol - θ::Float64 +abstract type AbstractRotGate <: AbstractSingleQubitGate end +ishermitian(::AbstractRotGate) = false +isunitary(::AbstractRotGate) = true +isexpr(::AbstractRotGate) = true +iscall(::AbstractRotGate) = true +arguments(x::AbstractRotGate) = [x.θ] + +@withmetadata struct RotX <: AbstractRotGate + θ end -symbollabel(g::RGate) = "R$(g.dir)($(g.θ))" -ishermitian(::RGate) = true -isunitary(::RGate) = true +operation(::RotX) = RotX +head(::RotX) = :RotX +children(x::RotX) = [:RotX, x.θ] +symbollabel(x::RotX) = "Rx($(x.θ))" + +@withmetadata struct RotY <: AbstractRotGate + θ +end +operation(::RotY) = RotY +head(::RotY) = :RotY +children(x::RotY) = [:RotY, x.θ] +symbollabel(x::RotY) = "Ry($(x.θ))" + +@withmetadata struct RotZ <: AbstractRotGate + θ +end +operation(::RotZ) = RotZ +head(::RotZ) = :RotZ +children(x::RotZ) = [:RotZ, x.θ] +symbollabel(x::RotZ) = "Rz($(x.θ))" @withmetadata struct CNOTGate <: AbstractTwoQubitGate end symbollabel(::CNOTGate) = "CNOT" @@ -151,12 +174,6 @@ const Pm = const σ₋ = PauliM() const Pp = const σ₊ = PauliP() """Hadamard gate""" const H = HGate() -"""Rotation X gate""" -const Rx(θ::Float64) = RGate(:x, θ) -"""Rotation Y gate""" -const Ry(θ::Float64) = RGate(:y, θ) -"""Rotation Z gate""" -const Rz(θ::Float64) = RGate(:z, θ) """CNOT gate""" const CNOT = CNOTGate() """CPHASE gate""" From b4389741ca8953a7d4d99a73f616b75bb0f93819 Mon Sep 17 00:00:00 2001 From: sagnikpal2004 Date: Thu, 24 Apr 2025 00:05:49 -0400 Subject: [PATCH 05/14] rotation rules --- src/QSymbolicsBase/QSymbolicsBase.jl | 4 ++-- src/QSymbolicsBase/rules.jl | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/QSymbolicsBase/QSymbolicsBase.jl b/src/QSymbolicsBase/QSymbolicsBase.jl index 46bc977..5d981e1 100644 --- a/src/QSymbolicsBase/QSymbolicsBase.jl +++ b/src/QSymbolicsBase/QSymbolicsBase.jl @@ -27,7 +27,7 @@ export SymQObj,QObj, tensor,⊗, dagger,projector,commutator,anticommutator,conj,transpose,inv,exp,vec,tr,ptrace, I,X,Y,Z,σˣ,σʸ,σᶻ,Pm,Pp,σ₋,σ₊, - H,Rx,Ry,Rz,CNOT,CPHASE,XCX,XCY,XCZ,YCX,YCY,YCZ,ZCX,ZCY,ZCZ, + H,RotX,RotY,RotZ,CNOT,CPHASE,XCX,XCY,XCZ,YCX,YCY,YCZ,ZCX,ZCY,ZCZ, X1,X2,Y1,Y2,Z1,Z2,X₁,X₂,Y₁,Y₂,Z₁,Z₂,L0,L1,Lp,Lm,Lpi,Lmi,L₀,L₁,L₊,L₋,L₊ᵢ,L₋ᵢ, vac,F₀,F0,F₁,F1,inf_fock_basis, N,n̂,Create,âꜛ,Destroy,â,basis,SpinBasis,FockBasis, @@ -44,7 +44,7 @@ export SymQObj,QObj, XBasisState,YBasisState,ZBasisState,FockState,CoherentState,SqueezedState, NumberOp,CreateOp,DestroyOp,PhaseShiftOp,DisplaceOp,SqueezeOp, XCXGate,XCYGate,XCZGate,YCXGate,YCYGate,YCZGate,ZCXGate,ZCYGate,ZCZGate, - qsimplify,qsimplify_pauli,qsimplify_commutator,qsimplify_anticommutator,qsimplify_fock, + qsimplify,qsimplify_pauli,qsimplify_commutator,qsimplify_anticommutator,qsimplify_fock,qsimplify_rot, qexpand, isunitary, KrausRepr,kraus diff --git a/src/QSymbolicsBase/rules.jl b/src/QSymbolicsBase/rules.jl index a0a9402..fa44641 100644 --- a/src/QSymbolicsBase/rules.jl +++ b/src/QSymbolicsBase/rules.jl @@ -109,7 +109,19 @@ RULES_FOCK = [ @rule(~o::_isa(SqueezeOp) * ~k::_isequal(vac) => SqueezedState((~o).z, (~o).basis)) ] -RULES_SIMPLIFY = [RULES_PAULI; RULES_COMMUTATOR; RULES_ANTICOMMUTATOR; RULES_FOCK] +RULES_ROT = [ + @rule(RotX(0) => I), + @rule(RotY(0) => I), + @rule(RotZ(0) => I), + @rule(RotX(~θ1) * RotX(~θ2) => RotX(~θ1 + ~θ2)), + @rule(RotY(~θ1) * RotY(~θ2) => RotY(~θ1 + ~θ2)), + @rule(RotZ(~θ1) * RotZ(~θ2) => RotZ(~θ1 + ~θ2)), + @rule(exp(-im * ~θ / 2 * X) => RotX(~θ)), + @rule(exp(-im * ~θ / 2 * Y) => RotY(~θ)), + @rule(exp(-im * ~θ / 2 * Z) => RotZ(~θ)), +] + +RULES_SIMPLIFY = [RULES_PAULI; RULES_COMMUTATOR; RULES_ANTICOMMUTATOR; RULES_FOCK; RULES_ROT] ## # Simplification rewriters @@ -119,6 +131,7 @@ qsimplify_pauli = Chain(RULES_PAULI) qsimplify_commutator = Chain(RULES_COMMUTATOR) qsimplify_anticommutator = Chain(RULES_ANTICOMMUTATOR) qsimplify_fock = Chain(RULES_FOCK) +qsimplify_rot = Chain(RULES_ROT) """ qsimplify(s; rewriter=nothing) From 13196310ea5b216eeef898d0abbdade6d1ad69b4 Mon Sep 17 00:00:00 2001 From: sagnikpal2004 Date: Fri, 25 Apr 2025 20:45:06 -0400 Subject: [PATCH 06/14] updated rules --- src/QSymbolicsBase/rules.jl | 21 ++++++++++++--------- test/test_rotation.jl | 27 +++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 test/test_rotation.jl diff --git a/src/QSymbolicsBase/rules.jl b/src/QSymbolicsBase/rules.jl index fa44641..448d5bf 100644 --- a/src/QSymbolicsBase/rules.jl +++ b/src/QSymbolicsBase/rules.jl @@ -110,15 +110,18 @@ RULES_FOCK = [ ] RULES_ROT = [ - @rule(RotX(0) => I), - @rule(RotY(0) => I), - @rule(RotZ(0) => I), - @rule(RotX(~θ1) * RotX(~θ2) => RotX(~θ1 + ~θ2)), - @rule(RotY(~θ1) * RotY(~θ2) => RotY(~θ1 + ~θ2)), - @rule(RotZ(~θ1) * RotZ(~θ2) => RotZ(~θ1 + ~θ2)), - @rule(exp(-im * ~θ / 2 * X) => RotX(~θ)), - @rule(exp(-im * ~θ / 2 * Y) => RotY(~θ)), - @rule(exp(-im * ~θ / 2 * Z) => RotZ(~θ)), + @rule(~r::_isa(RotX) => I where (~r).θ == 0), + @rule(~r::_isa(RotY) => I where (~r).θ == 0), + @rule(~r::_isa(RotZ) => I where (~r).θ == 0), + @rule(~r1::_isa(RotX) * ~r2::_isa(RotX) => try RotX((~r1).θ + (~r2).θ) catch end), + @rule(~r1::_isa(RotY) * ~r2::_isa(RotY) => try RotY((~r1).θ + (~r2).θ) catch end), + @rule(~r1::_isa(RotZ) * ~r2::_isa(RotZ) => try RotZ((~r1).θ + (~r2).θ) catch end), + @rule(~r::_isa(RotX) => try RotX(mod((~r).θ, 2π)) catch end), + @rule(~r::_isa(RotY) => try RotY(mod((~r).θ, 2π)) catch end), + @rule(~r::_isa(RotZ) => try RotZ(mod((~r).θ, 2π)) catch end), + @rule(exp(~α * ~x::_isa(XGate)) => try real(~α) == 0 ? RotX(-2imag(~α)) : nothing catch end), + @rule(exp(~α * ~x::_isa(YGate)) => try real(~α) == 0 ? RotY(-2imag(~α)) : nothing catch end), + @rule(exp(~α * ~x::_isa(ZGate)) => try real(~α) == 0 ? RotZ(-2imag(~α)) : nothing catch end) ] RULES_SIMPLIFY = [RULES_PAULI; RULES_COMMUTATOR; RULES_ANTICOMMUTATOR; RULES_FOCK; RULES_ROT] diff --git a/test/test_rotation.jl b/test/test_rotation.jl new file mode 100644 index 0000000..4d1b663 --- /dev/null +++ b/test/test_rotation.jl @@ -0,0 +1,27 @@ +@testitem "Test Rotation" begin + @testset "Identity tests" begin + @test isequal(qsimplify(RotX(0), rewriter=qsimplify_rot), I) + end + + @testset "Fusion tests" begin + @test isequal(qsimplify(RotX(π/2) * RotX(π/2), rewriter=qsimplify_rot), RotX(1π)) + @test isequal(qsimplify(RotY(π/2) * RotY(π/2), rewriter=qsimplify_rot), RotY(1π)) + @test isequal(qsimplify(RotZ(π/2) * RotZ(π/2), rewriter=qsimplify_rot), RotZ(1π)) + + @test isequal(qsimplify(RotX(π/2) * RotX(-π/2), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(RotY(π/2) * RotY(-π/2), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(RotZ(π/2) * RotZ(-π/2), rewriter=qsimplify_rot), I) + + @test isequal(qsimplify(2 * RotX(π) * RotX(π), rewriter=qsimplify_rot), 2RotX(2π)) + @test isequal(qsimplify(2 * RotY(π) * RotY(π), rewriter=qsimplify_rot), 2RotY(2π)) + @test isequal(qsimplify(2 * RotZ(π) * RotZ(π), rewriter=qsimplify_rot), 2RotZ(2π)) + end + + @testset "Exponential tests" begin + @test isequal(qsimplify(exp(-im * π/2 * X), rewriter=qsimplify_rot), RotX(π)) + @test isequal(qsimplify(exp(-im * π/2 * Y), rewriter=qsimplify_rot), RotY(π)) + @test isequal(qsimplify(exp(-im * π/2 * Z), rewriter=qsimplify_rot), RotZ(π)) + end + + @testset "modulo tests" +end \ No newline at end of file From 44b7378dfb960bb4276d52f3353e17f7830cbb36 Mon Sep 17 00:00:00 2001 From: sagnikpal2004 Date: Fri, 25 Apr 2025 21:50:28 -0400 Subject: [PATCH 07/14] rotation tests --- src/QSymbolicsBase/QSymbolicsBase.jl | 2 +- test/test_rotation.jl | 34 +++++++++++++++++++++------- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/QSymbolicsBase/QSymbolicsBase.jl b/src/QSymbolicsBase/QSymbolicsBase.jl index 5d981e1..39f88e4 100644 --- a/src/QSymbolicsBase/QSymbolicsBase.jl +++ b/src/QSymbolicsBase/QSymbolicsBase.jl @@ -40,7 +40,7 @@ export SymQObj,QObj, SConjugate,STranspose,SProjector,SDagger,SInvOperator,SExpOperator,SVec,STrace,SPartialTrace, MixedState,IdentityOp, SApplyKet,SApplyBra,SMulOperator,SSuperOpApply,SCommutator,SAnticommutator,SBraKet,SOuterKetBra, - HGate,XGate,YGate,ZGate,RGate,CPHASEGate,CNOTGate, + HGate,XGate,YGate,ZGate,CPHASEGate,CNOTGate, XBasisState,YBasisState,ZBasisState,FockState,CoherentState,SqueezedState, NumberOp,CreateOp,DestroyOp,PhaseShiftOp,DisplaceOp,SqueezeOp, XCXGate,XCYGate,XCZGate,YCXGate,YCYGate,YCZGate,ZCXGate,ZCYGate,ZCZGate, diff --git a/test/test_rotation.jl b/test/test_rotation.jl index 4d1b663..0cc9d67 100644 --- a/test/test_rotation.jl +++ b/test/test_rotation.jl @@ -1,6 +1,8 @@ @testitem "Test Rotation" begin @testset "Identity tests" begin @test isequal(qsimplify(RotX(0), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(RotY(0), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(RotZ(0), rewriter=qsimplify_rot), I) end @testset "Fusion tests" begin @@ -12,16 +14,32 @@ @test isequal(qsimplify(RotY(π/2) * RotY(-π/2), rewriter=qsimplify_rot), I) @test isequal(qsimplify(RotZ(π/2) * RotZ(-π/2), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(2 * RotX(π) * RotX(π), rewriter=qsimplify_rot), 2RotX(2π)) - @test isequal(qsimplify(2 * RotY(π) * RotY(π), rewriter=qsimplify_rot), 2RotY(2π)) - @test isequal(qsimplify(2 * RotZ(π) * RotZ(π), rewriter=qsimplify_rot), 2RotZ(2π)) + @test isequal(qsimplify(2 * RotX(π/2) * RotX(π/2), rewriter=qsimplify_rot), 2RotX(1π)) + @test isequal(qsimplify(2 * RotY(π/2) * RotY(π/2), rewriter=qsimplify_rot), 2RotY(1π)) + @test isequal(qsimplify(2 * RotZ(π/2) * RotZ(π/2), rewriter=qsimplify_rot), 2RotZ(1π)) end - @testset "Exponential tests" begin - @test isequal(qsimplify(exp(-im * π/2 * X), rewriter=qsimplify_rot), RotX(π)) - @test isequal(qsimplify(exp(-im * π/2 * Y), rewriter=qsimplify_rot), RotY(π)) - @test isequal(qsimplify(exp(-im * π/2 * Z), rewriter=qsimplify_rot), RotZ(π)) + @testset "Modulo tests" begin + @test isequal(qsimplify(RotX(2π), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(RotY(2π), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(RotZ(2π), rewriter=qsimplify_rot), I) + + @test isequal(qsimplify(RotX(π) * RotX(π), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(RotY(π) * RotY(π), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(RotZ(π) * RotZ(π), rewriter=qsimplify_rot), I) + + @test isequal(qsimplify(2 * RotX(3π/2) * RotX(2π/2), rewriter=qsimplify_rot), 2RotX(π/2)) + @test isequal(qsimplify(2 * RotY(3π/2) * RotY(2π/2), rewriter=qsimplify_rot), 2RotY(π/2)) + @test isequal(qsimplify(2 * RotZ(3π/2) * RotZ(2π/2), rewriter=qsimplify_rot), 2RotZ(π/2)) end - @testset "modulo tests" + @testset "Exponential tests" begin + @test isequal(qsimplify(exp(-im * π/2 * X), rewriter=qsimplify_rot), RotX(1π)) + @test isequal(qsimplify(exp(-im * π/2 * Y), rewriter=qsimplify_rot), RotY(1π)) + @test isequal(qsimplify(exp(-im * π/2 * Z), rewriter=qsimplify_rot), RotZ(1π)) + + @test isequal(qsimplify(exp(-im * 2π/2 * X) * exp(-im * π/2 * X), rewriter=qsimplify_rot), RotX(1π)) + @test isequal(qsimplify(exp(-im * 2π/2 * Y) * exp(-im * π/2 * Y), rewriter=qsimplify_rot), RotY(1π)) + @test isequal(qsimplify(exp(-im * 2π/2 * Z) * exp(-im * π/2 * Z), rewriter=qsimplify_rot), RotZ(1π)) + end end \ No newline at end of file From 4b1f531d279546caf66853b6f20d76c68665cd37 Mon Sep 17 00:00:00 2001 From: sagnikpal2004 Date: Fri, 25 Apr 2025 22:23:23 -0400 Subject: [PATCH 08/14] gate renaming --- ext/QuantumOpticsExt/QuantumOpticsExt.jl | 16 +++---- src/QSymbolicsBase/QSymbolicsBase.jl | 4 +- src/QSymbolicsBase/predefined.jl | 36 ++++++++------- src/QSymbolicsBase/rules.jl | 24 +++++----- test/test_rotation.jl | 56 ++++++++++++------------ 5 files changed, 70 insertions(+), 66 deletions(-) diff --git a/ext/QuantumOpticsExt/QuantumOpticsExt.jl b/ext/QuantumOpticsExt/QuantumOpticsExt.jl index 9ee3e7c..463507d 100644 --- a/ext/QuantumOpticsExt/QuantumOpticsExt.jl +++ b/ext/QuantumOpticsExt/QuantumOpticsExt.jl @@ -4,7 +4,7 @@ using QuantumInterface, QuantumOpticsBase using QuantumInterface: samebases using QuantumSymbolics using QuantumSymbolics: - HGate, XGate, YGate, ZGate, RGate, CPHASEGate, CNOTGate, PauliP, PauliM, + HGate, XGate, YGate, ZGate, RotXGate, RotYGate, RotZGate, CPHASEGate, CNOTGate, PauliP, PauliM, XCXGate, XCYGate, XCZGate, YCXGate, YCYGate, YCZGate, ZCXGate, ZCYGate, ZCZGate, XBasisState, YBasisState, ZBasisState, NumberOp, CreateOp, DestroyOp, @@ -31,13 +31,9 @@ const _z = sigmaz(_b2) const _x = sigmax(_b2) const _y = sigmay(_b2) const _hadamard = (sigmaz(_b2)+sigmax(_b2))/√2 -const _r(g::RGate) = if g.dir == :x - cos(g.θ/2)*_id - im*sin(g.θ/2)*_x -elseif g.dir == :y - cos(g.θ/2)*_id - im*sin(g.θ/2)*_y -elseif g.dir == :z - cos(g.θ/2)*_id - im*sin(g.θ/2)*_z -end +const _rotx(g::RotXGate) = cos(g.θ/2)*_id - im*sin(g.θ/2)*_x +const _roty(g::RotYGate) = cos(g.θ/2)*_id - im*sin(g.θ/2)*_y +const _rotz(g::RotZGate) = cos(g.θ/2)*_id - im*sin(g.θ/2)*_z const _cnot = _l00⊗_id + _l11⊗_x const _cphase = _l00⊗_id + _l11⊗_z const _phase = _l00 + im*_l11 @@ -54,7 +50,9 @@ express_nolookup(::HGate, ::QuantumOpticsRepr) = _hadamard express_nolookup(::XGate, ::QuantumOpticsRepr) = _x express_nolookup(::YGate, ::QuantumOpticsRepr) = _y express_nolookup(::ZGate, ::QuantumOpticsRepr) = _z -express_nolookup(g::RGate, ::QuantumOpticsRepr) = _r(g) +express_nolookup(g::RotXGate, ::QuantumOpticsRepr) = _rotx(g.θ) +express_nolookup(g::RotYGate, ::QuantumOpticsRepr) = _roty(g.θ) +express_nolookup(g::RotZGate, ::QuantumOpticsRepr) = _rotz(g.θ) express_nolookup(::CPHASEGate, ::QuantumOpticsRepr) = _cphase express_nolookup(::CNOTGate, ::QuantumOpticsRepr) = _cnot diff --git a/src/QSymbolicsBase/QSymbolicsBase.jl b/src/QSymbolicsBase/QSymbolicsBase.jl index 39f88e4..fb7d638 100644 --- a/src/QSymbolicsBase/QSymbolicsBase.jl +++ b/src/QSymbolicsBase/QSymbolicsBase.jl @@ -27,7 +27,7 @@ export SymQObj,QObj, tensor,⊗, dagger,projector,commutator,anticommutator,conj,transpose,inv,exp,vec,tr,ptrace, I,X,Y,Z,σˣ,σʸ,σᶻ,Pm,Pp,σ₋,σ₊, - H,RotX,RotY,RotZ,CNOT,CPHASE,XCX,XCY,XCZ,YCX,YCY,YCZ,ZCX,ZCY,ZCZ, + H,Rx,Ry,Rz,CNOT,CPHASE,XCX,XCY,XCZ,YCX,YCY,YCZ,ZCX,ZCY,ZCZ, X1,X2,Y1,Y2,Z1,Z2,X₁,X₂,Y₁,Y₂,Z₁,Z₂,L0,L1,Lp,Lm,Lpi,Lmi,L₀,L₁,L₊,L₋,L₊ᵢ,L₋ᵢ, vac,F₀,F0,F₁,F1,inf_fock_basis, N,n̂,Create,âꜛ,Destroy,â,basis,SpinBasis,FockBasis, @@ -40,7 +40,7 @@ export SymQObj,QObj, SConjugate,STranspose,SProjector,SDagger,SInvOperator,SExpOperator,SVec,STrace,SPartialTrace, MixedState,IdentityOp, SApplyKet,SApplyBra,SMulOperator,SSuperOpApply,SCommutator,SAnticommutator,SBraKet,SOuterKetBra, - HGate,XGate,YGate,ZGate,CPHASEGate,CNOTGate, + HGate,XGate,YGate,ZGate,RotXGate,RotYGate,RotZGate,CPHASEGate,CNOTGate, XBasisState,YBasisState,ZBasisState,FockState,CoherentState,SqueezedState, NumberOp,CreateOp,DestroyOp,PhaseShiftOp,DisplaceOp,SqueezeOp, XCXGate,XCYGate,XCZGate,YCXGate,YCYGate,YCZGate,ZCXGate,ZCYGate,ZCZGate, diff --git a/src/QSymbolicsBase/predefined.jl b/src/QSymbolicsBase/predefined.jl index 8853e84..d772855 100644 --- a/src/QSymbolicsBase/predefined.jl +++ b/src/QSymbolicsBase/predefined.jl @@ -113,29 +113,29 @@ isexpr(::AbstractRotGate) = true iscall(::AbstractRotGate) = true arguments(x::AbstractRotGate) = [x.θ] -@withmetadata struct RotX <: AbstractRotGate +@withmetadata struct RotXGate <: AbstractRotGate θ end -operation(::RotX) = RotX -head(::RotX) = :RotX -children(x::RotX) = [:RotX, x.θ] -symbollabel(x::RotX) = "Rx($(x.θ))" +operation(::RotXGate) = Rx +head(::RotXGate) = :RotX +children(x::RotXGate) = [:RotX, x.θ] +symbollabel(x::RotXGate) = "Rx($(x.θ))" -@withmetadata struct RotY <: AbstractRotGate +@withmetadata struct RotYGate <: AbstractRotGate θ end -operation(::RotY) = RotY -head(::RotY) = :RotY -children(x::RotY) = [:RotY, x.θ] -symbollabel(x::RotY) = "Ry($(x.θ))" +operation(::RotYGate) = Ry +head(::RotYGate) = :RotY +children(x::RotYGate) = [:RotY, x.θ] +symbollabel(x::RotYGate) = "Ry($(x.θ))" -@withmetadata struct RotZ <: AbstractRotGate +@withmetadata struct RotZGate <: AbstractRotGate θ end -operation(::RotZ) = RotZ -head(::RotZ) = :RotZ -children(x::RotZ) = [:RotZ, x.θ] -symbollabel(x::RotZ) = "Rz($(x.θ))" +operation(::RotZGate) = Rz +head(::RotZGate) = :RotZ +children(x::RotZGate) = [:RotZ, x.θ] +symbollabel(x::RotZGate) = "Rz($(x.θ))" @withmetadata struct CNOTGate <: AbstractTwoQubitGate end symbollabel(::CNOTGate) = "CNOT" @@ -174,6 +174,12 @@ const Pm = const σ₋ = PauliM() const Pp = const σ₊ = PauliP() """Hadamard gate""" const H = HGate() +"""Rotation around the X axis""" +const Rx(θ) = RotXGate(θ) +"""Rotation around the Y axis""" +const Ry(θ) = RotYGate(θ) +"""Rotation around the Z axis""" +const Rz(θ) = RotZGate(θ) """CNOT gate""" const CNOT = CNOTGate() """CPHASE gate""" diff --git a/src/QSymbolicsBase/rules.jl b/src/QSymbolicsBase/rules.jl index 448d5bf..3aeb4d5 100644 --- a/src/QSymbolicsBase/rules.jl +++ b/src/QSymbolicsBase/rules.jl @@ -110,18 +110,18 @@ RULES_FOCK = [ ] RULES_ROT = [ - @rule(~r::_isa(RotX) => I where (~r).θ == 0), - @rule(~r::_isa(RotY) => I where (~r).θ == 0), - @rule(~r::_isa(RotZ) => I where (~r).θ == 0), - @rule(~r1::_isa(RotX) * ~r2::_isa(RotX) => try RotX((~r1).θ + (~r2).θ) catch end), - @rule(~r1::_isa(RotY) * ~r2::_isa(RotY) => try RotY((~r1).θ + (~r2).θ) catch end), - @rule(~r1::_isa(RotZ) * ~r2::_isa(RotZ) => try RotZ((~r1).θ + (~r2).θ) catch end), - @rule(~r::_isa(RotX) => try RotX(mod((~r).θ, 2π)) catch end), - @rule(~r::_isa(RotY) => try RotY(mod((~r).θ, 2π)) catch end), - @rule(~r::_isa(RotZ) => try RotZ(mod((~r).θ, 2π)) catch end), - @rule(exp(~α * ~x::_isa(XGate)) => try real(~α) == 0 ? RotX(-2imag(~α)) : nothing catch end), - @rule(exp(~α * ~x::_isa(YGate)) => try real(~α) == 0 ? RotY(-2imag(~α)) : nothing catch end), - @rule(exp(~α * ~x::_isa(ZGate)) => try real(~α) == 0 ? RotZ(-2imag(~α)) : nothing catch end) + @rule(~r::_isa(RotXGate) => I where (~r).θ == 0), + @rule(~r::_isa(RotYGate) => I where (~r).θ == 0), + @rule(~r::_isa(RotZGate) => I where (~r).θ == 0), + @rule(~r1::_isa(RotXGate) * ~r2::_isa(RotXGate) => try Rx((~r1).θ + (~r2).θ) catch end), + @rule(~r1::_isa(RotYGate) * ~r2::_isa(RotYGate) => try Ry((~r1).θ + (~r2).θ) catch end), + @rule(~r1::_isa(RotZGate) * ~r2::_isa(RotZGate) => try Rz((~r1).θ + (~r2).θ) catch end), + @rule(~r::_isa(RotXGate) => try Rx(mod((~r).θ, 2π)) catch end), + @rule(~r::_isa(RotYGate) => try Ry(mod((~r).θ, 2π)) catch end), + @rule(~r::_isa(RotZGate) => try Rz(mod((~r).θ, 2π)) catch end), + @rule(exp(~α * ~x::_isa(XGate)) => try real(~α) == 0 ? Rx(-2imag(~α)) : nothing catch end), + @rule(exp(~α * ~x::_isa(YGate)) => try real(~α) == 0 ? Ry(-2imag(~α)) : nothing catch end), + @rule(exp(~α * ~x::_isa(ZGate)) => try real(~α) == 0 ? Rz(-2imag(~α)) : nothing catch end) ] RULES_SIMPLIFY = [RULES_PAULI; RULES_COMMUTATOR; RULES_ANTICOMMUTATOR; RULES_FOCK; RULES_ROT] diff --git a/test/test_rotation.jl b/test/test_rotation.jl index 0cc9d67..fde347c 100644 --- a/test/test_rotation.jl +++ b/test/test_rotation.jl @@ -1,45 +1,45 @@ -@testitem "Test Rotation" begin +@testitem "Test Ration" begin @testset "Identity tests" begin - @test isequal(qsimplify(RotX(0), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(RotY(0), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(RotZ(0), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(Rx(0), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(Ry(0), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(Rz(0), rewriter=qsimplify_rot), I) end @testset "Fusion tests" begin - @test isequal(qsimplify(RotX(π/2) * RotX(π/2), rewriter=qsimplify_rot), RotX(1π)) - @test isequal(qsimplify(RotY(π/2) * RotY(π/2), rewriter=qsimplify_rot), RotY(1π)) - @test isequal(qsimplify(RotZ(π/2) * RotZ(π/2), rewriter=qsimplify_rot), RotZ(1π)) + @test isequal(qsimplify(Rx(π/2) * Rx(π/2), rewriter=qsimplify_rot), Rx(1π)) + @test isequal(qsimplify(Ry(π/2) * Ry(π/2), rewriter=qsimplify_rot), Ry(1π)) + @test isequal(qsimplify(Rz(π/2) * Rz(π/2), rewriter=qsimplify_rot), Rz(1π)) - @test isequal(qsimplify(RotX(π/2) * RotX(-π/2), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(RotY(π/2) * RotY(-π/2), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(RotZ(π/2) * RotZ(-π/2), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(Rx(π/2) * Rx(-π/2), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(Ry(π/2) * Ry(-π/2), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(Rz(π/2) * Rz(-π/2), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(2 * RotX(π/2) * RotX(π/2), rewriter=qsimplify_rot), 2RotX(1π)) - @test isequal(qsimplify(2 * RotY(π/2) * RotY(π/2), rewriter=qsimplify_rot), 2RotY(1π)) - @test isequal(qsimplify(2 * RotZ(π/2) * RotZ(π/2), rewriter=qsimplify_rot), 2RotZ(1π)) + @test isequal(qsimplify(2 * Rx(π/2) * Rx(π/2), rewriter=qsimplify_rot), 2Rx(1π)) + @test isequal(qsimplify(2 * Ry(π/2) * Ry(π/2), rewriter=qsimplify_rot), 2Ry(1π)) + @test isequal(qsimplify(2 * Rz(π/2) * Rz(π/2), rewriter=qsimplify_rot), 2Rz(1π)) end @testset "Modulo tests" begin - @test isequal(qsimplify(RotX(2π), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(RotY(2π), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(RotZ(2π), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(Rx(2π), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(Ry(2π), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(Rz(2π), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(RotX(π) * RotX(π), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(RotY(π) * RotY(π), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(RotZ(π) * RotZ(π), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(Rx(π) * Rx(π), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(Ry(π) * Ry(π), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(Rz(π) * Rz(π), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(2 * RotX(3π/2) * RotX(2π/2), rewriter=qsimplify_rot), 2RotX(π/2)) - @test isequal(qsimplify(2 * RotY(3π/2) * RotY(2π/2), rewriter=qsimplify_rot), 2RotY(π/2)) - @test isequal(qsimplify(2 * RotZ(3π/2) * RotZ(2π/2), rewriter=qsimplify_rot), 2RotZ(π/2)) + @test isequal(qsimplify(2 * Rx(3π/2) * Rx(2π/2), rewriter=qsimplify_rot), 2Rx(π/2)) + @test isequal(qsimplify(2 * Ry(3π/2) * Ry(2π/2), rewriter=qsimplify_rot), 2Ry(π/2)) + @test isequal(qsimplify(2 * Rz(3π/2) * Rz(2π/2), rewriter=qsimplify_rot), 2Rz(π/2)) end @testset "Exponential tests" begin - @test isequal(qsimplify(exp(-im * π/2 * X), rewriter=qsimplify_rot), RotX(1π)) - @test isequal(qsimplify(exp(-im * π/2 * Y), rewriter=qsimplify_rot), RotY(1π)) - @test isequal(qsimplify(exp(-im * π/2 * Z), rewriter=qsimplify_rot), RotZ(1π)) + @test isequal(qsimplify(exp(-im * π/2 * X), rewriter=qsimplify_rot), Rx(1π)) + @test isequal(qsimplify(exp(-im * π/2 * Y), rewriter=qsimplify_rot), Ry(1π)) + @test isequal(qsimplify(exp(-im * π/2 * Z), rewriter=qsimplify_rot), Rz(1π)) - @test isequal(qsimplify(exp(-im * 2π/2 * X) * exp(-im * π/2 * X), rewriter=qsimplify_rot), RotX(1π)) - @test isequal(qsimplify(exp(-im * 2π/2 * Y) * exp(-im * π/2 * Y), rewriter=qsimplify_rot), RotY(1π)) - @test isequal(qsimplify(exp(-im * 2π/2 * Z) * exp(-im * π/2 * Z), rewriter=qsimplify_rot), RotZ(1π)) + @test isequal(qsimplify(exp(-im * 2π/2 * X) * exp(-im * π/2 * X), rewriter=qsimplify_rot), Rx(1π)) + @test isequal(qsimplify(exp(-im * 2π/2 * Y) * exp(-im * π/2 * Y), rewriter=qsimplify_rot), Ry(1π)) + @test isequal(qsimplify(exp(-im * 2π/2 * Z) * exp(-im * π/2 * Z), rewriter=qsimplify_rot), Rz(1π)) end end \ No newline at end of file From 419eecade79f64f4325a61e8abfd19a750922440 Mon Sep 17 00:00:00 2001 From: Sagnik Pal Date: Sat, 26 Apr 2025 00:13:56 -0400 Subject: [PATCH 09/14] express qoptics --- ext/QuantumOpticsExt/QuantumOpticsExt.jl | 6 +++--- src/QSymbolicsBase/predefined.jl | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ext/QuantumOpticsExt/QuantumOpticsExt.jl b/ext/QuantumOpticsExt/QuantumOpticsExt.jl index 463507d..47079f0 100644 --- a/ext/QuantumOpticsExt/QuantumOpticsExt.jl +++ b/ext/QuantumOpticsExt/QuantumOpticsExt.jl @@ -31,9 +31,9 @@ const _z = sigmaz(_b2) const _x = sigmax(_b2) const _y = sigmay(_b2) const _hadamard = (sigmaz(_b2)+sigmax(_b2))/√2 -const _rotx(g::RotXGate) = cos(g.θ/2)*_id - im*sin(g.θ/2)*_x -const _roty(g::RotYGate) = cos(g.θ/2)*_id - im*sin(g.θ/2)*_y -const _rotz(g::RotZGate) = cos(g.θ/2)*_id - im*sin(g.θ/2)*_z +const _rotx(θ) = cos(θ/2)*_id - im*sin(θ/2)*_x +const _roty(θ) = cos(θ/2)*_id - im*sin(θ/2)*_y +const _rotz(θ) = cos(θ/2)*_id - im*sin(θ/2)*_z const _cnot = _l00⊗_id + _l11⊗_x const _cphase = _l00⊗_id + _l11⊗_z const _phase = _l00 + im*_l11 diff --git a/src/QSymbolicsBase/predefined.jl b/src/QSymbolicsBase/predefined.jl index d772855..be77c32 100644 --- a/src/QSymbolicsBase/predefined.jl +++ b/src/QSymbolicsBase/predefined.jl @@ -175,11 +175,11 @@ const Pp = const σ₊ = PauliP() """Hadamard gate""" const H = HGate() """Rotation around the X axis""" -const Rx(θ) = RotXGate(θ) +const Rx = RotXGate """Rotation around the Y axis""" -const Ry(θ) = RotYGate(θ) +const Ry = RotYGate """Rotation around the Z axis""" -const Rz(θ) = RotZGate(θ) +const Rz = RotZGate """CNOT gate""" const CNOT = CNOTGate() """CPHASE gate""" From 57cf767c10c7d9e47c93a4d451e680cf36c678b9 Mon Sep 17 00:00:00 2001 From: Sagnik Pal Date: Sat, 26 Apr 2025 01:59:10 -0400 Subject: [PATCH 10/14] updated rules --- src/QSymbolicsBase/rules.jl | 18 ++++++++----- test/test_rotation.jl | 52 ++++++++++++++++++++++++++----------- 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/src/QSymbolicsBase/rules.jl b/src/QSymbolicsBase/rules.jl index dc79336..1952126 100644 --- a/src/QSymbolicsBase/rules.jl +++ b/src/QSymbolicsBase/rules.jl @@ -113,15 +113,21 @@ RULES_ROT = [ @rule(~r::_isa(RotXGate) => I where (~r).θ == 0), @rule(~r::_isa(RotYGate) => I where (~r).θ == 0), @rule(~r::_isa(RotZGate) => I where (~r).θ == 0), + @rule(~r::_isa(RotXGate) => (-im*X) where (~r).θ in [π, 1π]), + @rule(~r::_isa(RotYGate) => (-im*Y) where (~r).θ in [π, 1π]), + @rule(~r::_isa(RotZGate) => (-im*Z) where (~r).θ in [π, 1π]), + @rule(~r::_isa(RotXGate) => try Rx(mod((~r).θ, 4π)) catch end), + @rule(~r::_isa(RotYGate) => try Ry(mod((~r).θ, 4π)) catch end), + @rule(~r::_isa(RotZGate) => try Rz(mod((~r).θ, 4π)) catch end), + @rule(~r::_isa(RotXGate) => try (~r).θ ≥ 2π ? -Rx((~r).θ - 2π) : nothing catch end), + @rule(~r::_isa(RotYGate) => try (~r).θ ≥ 2π ? -Ry((~r).θ - 2π) : nothing catch end), + @rule(~r::_isa(RotZGate) => try (~r).θ ≥ 2π ? -Rz((~r).θ - 2π) : nothing catch end), @rule(~r1::_isa(RotXGate) * ~r2::_isa(RotXGate) => try Rx((~r1).θ + (~r2).θ) catch end), @rule(~r1::_isa(RotYGate) * ~r2::_isa(RotYGate) => try Ry((~r1).θ + (~r2).θ) catch end), @rule(~r1::_isa(RotZGate) * ~r2::_isa(RotZGate) => try Rz((~r1).θ + (~r2).θ) catch end), - @rule(~r::_isa(RotXGate) => try Rx(mod((~r).θ, 2π)) catch end), - @rule(~r::_isa(RotYGate) => try Ry(mod((~r).θ, 2π)) catch end), - @rule(~r::_isa(RotZGate) => try Rz(mod((~r).θ, 2π)) catch end), - @rule(exp(~α * ~x::_isa(XGate)) => try real(~α) == 0 ? Rx(-2imag(~α)) : nothing catch end), - @rule(exp(~α * ~x::_isa(YGate)) => try real(~α) == 0 ? Ry(-2imag(~α)) : nothing catch end), - @rule(exp(~α * ~x::_isa(ZGate)) => try real(~α) == 0 ? Rz(-2imag(~α)) : nothing catch end) + @rule(exp(~α * ~x::_isa(XGate)) => try if real(~α) == 0 Rx(-2imag(~α)) end catch end), + @rule(exp(~α * ~x::_isa(YGate)) => try if real(~α) == 0 Ry(-2imag(~α)) end catch end), + @rule(exp(~α * ~x::_isa(ZGate)) => try if real(~α) == 0 Rz(-2imag(~α)) end catch end) ] RULES_SIMPLIFY = [RULES_PAULI; RULES_COMMUTATOR; RULES_ANTICOMMUTATOR; RULES_FOCK; RULES_ROT] diff --git a/test/test_rotation.jl b/test/test_rotation.jl index fde347c..154af7f 100644 --- a/test/test_rotation.jl +++ b/test/test_rotation.jl @@ -5,32 +5,54 @@ @test isequal(qsimplify(Rz(0), rewriter=qsimplify_rot), I) end + @testset "Pauli tests" begin + @test isequal(qsimplify(Rx(π), rewriter=qsimplify_rot), -im*X) + @test isequal(qsimplify(Ry(π), rewriter=qsimplify_rot), -im*Y) + @test isequal(qsimplify(Rz(π), rewriter=qsimplify_rot), -im*Z) + + @test isequal(qsimplify(Rx(1π), rewriter=qsimplify_rot), -im*X) + @test isequal(qsimplify(Ry(1π), rewriter=qsimplify_rot), -im*Y) + @test isequal(qsimplify(Rz(1π), rewriter=qsimplify_rot), -im*Z) + end + @testset "Fusion tests" begin - @test isequal(qsimplify(Rx(π/2) * Rx(π/2), rewriter=qsimplify_rot), Rx(1π)) - @test isequal(qsimplify(Ry(π/2) * Ry(π/2), rewriter=qsimplify_rot), Ry(1π)) - @test isequal(qsimplify(Rz(π/2) * Rz(π/2), rewriter=qsimplify_rot), Rz(1π)) + @test isequal(qsimplify(Rx(π/3) * Rx(π/3), rewriter=qsimplify_rot), Rx(2π/3)) + @test isequal(qsimplify(Ry(π/3) * Ry(π/3), rewriter=qsimplify_rot), Ry(2π/3)) + @test isequal(qsimplify(Rz(π/3) * Rz(π/3), rewriter=qsimplify_rot), Rz(2π/3)) @test isequal(qsimplify(Rx(π/2) * Rx(-π/2), rewriter=qsimplify_rot), I) @test isequal(qsimplify(Ry(π/2) * Ry(-π/2), rewriter=qsimplify_rot), I) @test isequal(qsimplify(Rz(π/2) * Rz(-π/2), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(2 * Rx(π/2) * Rx(π/2), rewriter=qsimplify_rot), 2Rx(1π)) - @test isequal(qsimplify(2 * Ry(π/2) * Ry(π/2), rewriter=qsimplify_rot), 2Ry(1π)) - @test isequal(qsimplify(2 * Rz(π/2) * Rz(π/2), rewriter=qsimplify_rot), 2Rz(1π)) + @test isequal(qsimplify(2 * Rx(π/2) * Rx(π/2), rewriter=qsimplify_rot), -2im*X) + @test isequal(qsimplify(2 * Ry(π/2) * Ry(π/2), rewriter=qsimplify_rot), -2im*Y) + @test isequal(qsimplify(2 * Rz(π/2) * Rz(π/2), rewriter=qsimplify_rot), -2im*Z) end @testset "Modulo tests" begin - @test isequal(qsimplify(Rx(2π), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(Ry(2π), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(Rz(2π), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(Rx(2π), rewriter=qsimplify_rot), -I) + @test isequal(qsimplify(Ry(2π), rewriter=qsimplify_rot), -I) + @test isequal(qsimplify(Rz(2π), rewriter=qsimplify_rot), -I) + + @test isequal(qsimplify(Rx(3π), rewriter=qsimplify_rot), im*X) + @test isequal(qsimplify(Ry(3π), rewriter=qsimplify_rot), im*Y) + @test isequal(qsimplify(Rz(3π), rewriter=qsimplify_rot), im*Z) + + @test isequal(qsimplify(Rx(4π), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(Ry(4π), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(Rz(4π), rewriter=qsimplify_rot), I) + + @test isequal(qsimplify(Rx(5π), rewriter=qsimplify_rot), -im*X) + @test isequal(qsimplify(Ry(5π), rewriter=qsimplify_rot), -im*Y) + @test isequal(qsimplify(Rz(5π), rewriter=qsimplify_rot), -im*Z) - @test isequal(qsimplify(Rx(π) * Rx(π), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(Ry(π) * Ry(π), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(Rz(π) * Rz(π), rewriter=qsimplify_rot), I) + @test isequal(qsimplify(Rx(π) * Rx(π), rewriter=qsimplify_rot), -I) + @test isequal(qsimplify(Ry(π) * Ry(π), rewriter=qsimplify_rot), -I) + @test isequal(qsimplify(Rz(π) * Rz(π), rewriter=qsimplify_rot), -I) - @test isequal(qsimplify(2 * Rx(3π/2) * Rx(2π/2), rewriter=qsimplify_rot), 2Rx(π/2)) - @test isequal(qsimplify(2 * Ry(3π/2) * Ry(2π/2), rewriter=qsimplify_rot), 2Ry(π/2)) - @test isequal(qsimplify(2 * Rz(3π/2) * Rz(2π/2), rewriter=qsimplify_rot), 2Rz(π/2)) + @test isequal(qsimplify(2 * Rx(3π/2) * Rx(2π/2), rewriter=qsimplify_rot), -2Rx(π/2)) + @test isequal(qsimplify(2 * Ry(3π/2) * Ry(2π/2), rewriter=qsimplify_rot), -2Ry(π/2)) + @test isequal(qsimplify(2 * Rz(3π/2) * Rz(2π/2), rewriter=qsimplify_rot), -2Rz(π/2)) end @testset "Exponential tests" begin From 1ec48716f201ac602fc8d33c81aa5ec4916e3980 Mon Sep 17 00:00:00 2001 From: Sagnik Pal Date: Sat, 26 Apr 2025 02:23:33 -0400 Subject: [PATCH 11/14] updated tests --- test/test_rotation.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/test_rotation.jl b/test/test_rotation.jl index 154af7f..d051cda 100644 --- a/test/test_rotation.jl +++ b/test/test_rotation.jl @@ -56,12 +56,12 @@ end @testset "Exponential tests" begin - @test isequal(qsimplify(exp(-im * π/2 * X), rewriter=qsimplify_rot), Rx(1π)) - @test isequal(qsimplify(exp(-im * π/2 * Y), rewriter=qsimplify_rot), Ry(1π)) - @test isequal(qsimplify(exp(-im * π/2 * Z), rewriter=qsimplify_rot), Rz(1π)) + @test isequal(qsimplify(exp(-im * π/2 * X), rewriter=qsimplify_rot), -im*X) + @test isequal(qsimplify(exp(-im * π/2 * Y), rewriter=qsimplify_rot), -im*Y) + @test isequal(qsimplify(exp(-im * π/2 * Z), rewriter=qsimplify_rot), -im*Z) - @test isequal(qsimplify(exp(-im * 2π/2 * X) * exp(-im * π/2 * X), rewriter=qsimplify_rot), Rx(1π)) - @test isequal(qsimplify(exp(-im * 2π/2 * Y) * exp(-im * π/2 * Y), rewriter=qsimplify_rot), Ry(1π)) - @test isequal(qsimplify(exp(-im * 2π/2 * Z) * exp(-im * π/2 * Z), rewriter=qsimplify_rot), Rz(1π)) + @test isequal(qsimplify(2 * exp(-im * 2π/2 * X) * exp(-im * 5π/2 * X), rewriter=qsimplify_rot), 2im*X) + @test isequal(qsimplify(2 * exp(-im * 2π/2 * Y) * exp(-im * 5π/2 * Y), rewriter=qsimplify_rot), 2im*Y) + @test isequal(qsimplify(2 * exp(-im * 2π/2 * Z) * exp(-im * 5π/2 * Z), rewriter=qsimplify_rot), 2im*Z) end end \ No newline at end of file From c71b5c98b903152f9357e566591c7d6e2882e3ad Mon Sep 17 00:00:00 2001 From: sagnikpal2004 Date: Mon, 9 Jun 2025 14:45:41 +0530 Subject: [PATCH 12/14] fixed rotation SymbolicUtils APIs --- src/QSymbolicsBase/predefined.jl | 24 ++++++++++++------------ src/QSymbolicsBase/rules.jl | 3 --- test/test_rotation.jl | 8 ++++---- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/QSymbolicsBase/predefined.jl b/src/QSymbolicsBase/predefined.jl index 88c9c20..5f8182f 100644 --- a/src/QSymbolicsBase/predefined.jl +++ b/src/QSymbolicsBase/predefined.jl @@ -117,25 +117,31 @@ arguments(x::AbstractRotGate) = [x.θ] θ end operation(::RotXGate) = Rx -head(::RotXGate) = :RotX -children(x::RotXGate) = [:RotX, x.θ] +head(::RotXGate) = :Rx +children(x::RotXGate) = [:Rx, x.θ] symbollabel(x::RotXGate) = "Rx($(x.θ))" +"""Rotation around the X axis""" +Rx(θ) = (θ == 0) ? I : RotXGate(θ) @withmetadata struct RotYGate <: AbstractRotGate θ end operation(::RotYGate) = Ry -head(::RotYGate) = :RotY -children(x::RotYGate) = [:RotY, x.θ] +head(::RotYGate) = :Ry +children(x::RotYGate) = [:Ry, x.θ] symbollabel(x::RotYGate) = "Ry($(x.θ))" +"""Rotation around the Y axis""" +Ry(θ) = (θ == 0) ? I : RotYGate(θ) @withmetadata struct RotZGate <: AbstractRotGate θ end operation(::RotZGate) = Rz -head(::RotZGate) = :RotZ -children(x::RotZGate) = [:RotZ, x.θ] +head(::RotZGate) = :Rz +children(x::RotZGate) = [:Rz, x.θ] symbollabel(x::RotZGate) = "Rz($(x.θ))" +"""Rotation around the Z axis""" +Rz(θ) = (θ == 0) ? I : RotZGate(θ) @withmetadata struct CNOTGate <: AbstractTwoQubitGate end symbollabel(::CNOTGate) = "CNOT" @@ -174,12 +180,6 @@ const Pm = const σ₋ = PauliM() const Pp = const σ₊ = PauliP() """Hadamard gate""" const H = HGate() -"""Rotation around the X axis""" -const Rx = RotXGate -"""Rotation around the Y axis""" -const Ry = RotYGate -"""Rotation around the Z axis""" -const Rz = RotZGate """CNOT gate""" const CNOT = CNOTGate() """CPHASE gate""" diff --git a/src/QSymbolicsBase/rules.jl b/src/QSymbolicsBase/rules.jl index 1952126..66494d0 100644 --- a/src/QSymbolicsBase/rules.jl +++ b/src/QSymbolicsBase/rules.jl @@ -110,9 +110,6 @@ RULES_FOCK = [ ] RULES_ROT = [ - @rule(~r::_isa(RotXGate) => I where (~r).θ == 0), - @rule(~r::_isa(RotYGate) => I where (~r).θ == 0), - @rule(~r::_isa(RotZGate) => I where (~r).θ == 0), @rule(~r::_isa(RotXGate) => (-im*X) where (~r).θ in [π, 1π]), @rule(~r::_isa(RotYGate) => (-im*Y) where (~r).θ in [π, 1π]), @rule(~r::_isa(RotZGate) => (-im*Z) where (~r).θ in [π, 1π]), diff --git a/test/test_rotation.jl b/test/test_rotation.jl index d051cda..f8df318 100644 --- a/test/test_rotation.jl +++ b/test/test_rotation.jl @@ -1,8 +1,8 @@ -@testitem "Test Ration" begin +@testitem "Test Rotation" begin @testset "Identity tests" begin - @test isequal(qsimplify(Rx(0), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(Ry(0), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(Rz(0), rewriter=qsimplify_rot), I) + @test isequal(Rx(0), I) + @test isequal(Ry(0), I) + @test isequal(Rz(0), I) end @testset "Pauli tests" begin From 7856f9e2d221d74d64b1eb44e45edc847ad6a063 Mon Sep 17 00:00:00 2001 From: sagnikpal2004 Date: Mon, 9 Jun 2025 14:45:41 +0530 Subject: [PATCH 13/14] fixed rotation TermInterface APIs --- src/QSymbolicsBase/predefined.jl | 24 ++++++++++++------------ src/QSymbolicsBase/rules.jl | 3 --- test/test_rotation.jl | 8 ++++---- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/QSymbolicsBase/predefined.jl b/src/QSymbolicsBase/predefined.jl index 88c9c20..5f8182f 100644 --- a/src/QSymbolicsBase/predefined.jl +++ b/src/QSymbolicsBase/predefined.jl @@ -117,25 +117,31 @@ arguments(x::AbstractRotGate) = [x.θ] θ end operation(::RotXGate) = Rx -head(::RotXGate) = :RotX -children(x::RotXGate) = [:RotX, x.θ] +head(::RotXGate) = :Rx +children(x::RotXGate) = [:Rx, x.θ] symbollabel(x::RotXGate) = "Rx($(x.θ))" +"""Rotation around the X axis""" +Rx(θ) = (θ == 0) ? I : RotXGate(θ) @withmetadata struct RotYGate <: AbstractRotGate θ end operation(::RotYGate) = Ry -head(::RotYGate) = :RotY -children(x::RotYGate) = [:RotY, x.θ] +head(::RotYGate) = :Ry +children(x::RotYGate) = [:Ry, x.θ] symbollabel(x::RotYGate) = "Ry($(x.θ))" +"""Rotation around the Y axis""" +Ry(θ) = (θ == 0) ? I : RotYGate(θ) @withmetadata struct RotZGate <: AbstractRotGate θ end operation(::RotZGate) = Rz -head(::RotZGate) = :RotZ -children(x::RotZGate) = [:RotZ, x.θ] +head(::RotZGate) = :Rz +children(x::RotZGate) = [:Rz, x.θ] symbollabel(x::RotZGate) = "Rz($(x.θ))" +"""Rotation around the Z axis""" +Rz(θ) = (θ == 0) ? I : RotZGate(θ) @withmetadata struct CNOTGate <: AbstractTwoQubitGate end symbollabel(::CNOTGate) = "CNOT" @@ -174,12 +180,6 @@ const Pm = const σ₋ = PauliM() const Pp = const σ₊ = PauliP() """Hadamard gate""" const H = HGate() -"""Rotation around the X axis""" -const Rx = RotXGate -"""Rotation around the Y axis""" -const Ry = RotYGate -"""Rotation around the Z axis""" -const Rz = RotZGate """CNOT gate""" const CNOT = CNOTGate() """CPHASE gate""" diff --git a/src/QSymbolicsBase/rules.jl b/src/QSymbolicsBase/rules.jl index 1952126..66494d0 100644 --- a/src/QSymbolicsBase/rules.jl +++ b/src/QSymbolicsBase/rules.jl @@ -110,9 +110,6 @@ RULES_FOCK = [ ] RULES_ROT = [ - @rule(~r::_isa(RotXGate) => I where (~r).θ == 0), - @rule(~r::_isa(RotYGate) => I where (~r).θ == 0), - @rule(~r::_isa(RotZGate) => I where (~r).θ == 0), @rule(~r::_isa(RotXGate) => (-im*X) where (~r).θ in [π, 1π]), @rule(~r::_isa(RotYGate) => (-im*Y) where (~r).θ in [π, 1π]), @rule(~r::_isa(RotZGate) => (-im*Z) where (~r).θ in [π, 1π]), diff --git a/test/test_rotation.jl b/test/test_rotation.jl index d051cda..f8df318 100644 --- a/test/test_rotation.jl +++ b/test/test_rotation.jl @@ -1,8 +1,8 @@ -@testitem "Test Ration" begin +@testitem "Test Rotation" begin @testset "Identity tests" begin - @test isequal(qsimplify(Rx(0), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(Ry(0), rewriter=qsimplify_rot), I) - @test isequal(qsimplify(Rz(0), rewriter=qsimplify_rot), I) + @test isequal(Rx(0), I) + @test isequal(Ry(0), I) + @test isequal(Rz(0), I) end @testset "Pauli tests" begin From a8b49221b99bc6dc7c51c8451d7fe49db334d504 Mon Sep 17 00:00:00 2001 From: sagnikpal2004 Date: Tue, 24 Jun 2025 19:38:46 +0530 Subject: [PATCH 14/14] const functions --- ext/QuantumOpticsExt/QuantumOpticsExt.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/QuantumOpticsExt/QuantumOpticsExt.jl b/ext/QuantumOpticsExt/QuantumOpticsExt.jl index 418ab49..c1a592e 100644 --- a/ext/QuantumOpticsExt/QuantumOpticsExt.jl +++ b/ext/QuantumOpticsExt/QuantumOpticsExt.jl @@ -31,9 +31,9 @@ const _z = sigmaz(_b2) const _x = sigmax(_b2) const _y = sigmay(_b2) const _hadamard = (sigmaz(_b2)+sigmax(_b2))/√2 -const _rotx(θ) = cos(θ/2)*_id - im*sin(θ/2)*_x -const _roty(θ) = cos(θ/2)*_id - im*sin(θ/2)*_y -const _rotz(θ) = cos(θ/2)*_id - im*sin(θ/2)*_z +_rotx(θ) = cos(θ/2)*_id - im*sin(θ/2)*_x +_roty(θ) = cos(θ/2)*_id - im*sin(θ/2)*_y +_rotz(θ) = cos(θ/2)*_id - im*sin(θ/2)*_z const _cnot = _l00⊗_id + _l11⊗_x const _cphase = _l00⊗_id + _l11⊗_z const _phase = _l00 + im*_l11