Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding Commutators, Anticommutator, Daggers #40

Merged
merged 24 commits into from
Jun 19, 2024

Conversation

apkille
Copy link
Member

@apkille apkille commented Jun 4, 2024

Defined constructors for bra, product of operators, commutator, anti commutator, and dagger. Also added scaling and a few simplification rules.

@Krastanov
Copy link
Member

I left a couple of minor comments, nothing to interesting, and you might have already been thinking about some of these things.

I will convert this to a draft. When it is ready for review and it has all tests pass, just convert it back and request a review.

@Krastanov Krastanov marked this pull request as draft June 5, 2024 03:48
Copy link

codecov bot commented Jun 7, 2024

Codecov Report

Attention: Patch coverage is 63.09524% with 62 lines in your changes missing coverage. Please review.

Project coverage is 62.78%. Comparing base (8a75466) to head (af3c073).

Files Patch % Lines
src/QSymbolicsBase/predefined.jl 51.92% 25 Missing ⚠️
src/QSymbolicsBase/basic_ops_homogeneous.jl 61.22% 19 Missing ⚠️
src/QSymbolicsBase/literal_objects.jl 57.14% 9 Missing ⚠️
src/QSymbolicsBase/basic_ops_inhomogeneous.jl 75.00% 5 Missing ⚠️
src/QSymbolicsBase/rules.jl 80.00% 3 Missing ⚠️
src/QSymbolicsBase/QSymbolicsBase.jl 90.90% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #40      +/-   ##
==========================================
+ Coverage   54.70%   62.78%   +8.07%     
==========================================
  Files          14       15       +1     
  Lines         446      575     +129     
==========================================
+ Hits          244      361     +117     
- Misses        202      214      +12     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@apkille apkille marked this pull request as ready for review June 14, 2024 16:00
@apkille
Copy link
Member Author

apkille commented Jun 14, 2024

I updated functionalities of (anti)commutator and dagger. Also added operator properties (hermitian, unitary, and commutative) and wrote corresponding simplification rules, which are all tested. I added doctests as well for basic operations.

Copy link
Member

@Krastanov Krastanov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a very solid start and I am very happy to see the momentum you already have!

I have a ton of questions for now, that will inform me how to understand this work. Let's go through them and then we can do another round of review and changes.

Converting back to draft -- convert to nondraft and request a review when you feel it is appropriate.

.vscode/settings.json Outdated Show resolved Hide resolved
src/QSymbolicsBase/QSymbolicsBase.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/objects.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/objects.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/objects.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/rules.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/QSymbolicsBase.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/QSymbolicsBase.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/basic_ops_homogeneous.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/basic_ops_homogeneous.jl Outdated Show resolved Hide resolved
@Krastanov Krastanov marked this pull request as draft June 15, 2024 00:39
@apkille apkille marked this pull request as ready for review June 15, 2024 17:27
Copy link
Member

@Krastanov Krastanov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! A few minor things left to polish and it should be ready for merging.

src/QSymbolicsBase/rules.jl Show resolved Hide resolved
src/QSymbolicsBase/rules.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/rules.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/rules.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/QSymbolicsBase.jl Show resolved Hide resolved
if isexpr(x)
if operation(x)==operation(y)
ax,ay = arguments(x),arguments(y)
(length(ax) == length(ay)) && all(x -> _in(x, y), ax)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be just Set(ax)==Set(ay) -- should be asymptotically faster too, although I am not sure it matters for the sizes of expressions we would typically work with.

Having canonical order of arguments is also a good idea as you had already mentioned. I believe it is a better solution than what you currently have. But it is indeed not necessary for now.

However, to clean up some code repetition, I think I would prefer if this method is deleted and the already existing method is modified to basically say:

if operation(x) === :+
    Set(ax) == Set(ay)
else
    (length(ax) == length(ay)) && all(zip(ax,ay)) do xy isequal(xy...) end
end

Copy link
Member Author

@apkille apkille Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set doesn't appear to work here, as equality of sets relies on == rather than isequal function. Here's an example:

julia> A = SOperator(:A, SpinBasis(1//2)); B = SOperator(:B, SpinBasis(1//2));

julia> Set([A+B]) == Set([A+B])
false

julia> isequal(A+B, A+B)
true

julia> A+B == A+B
false

Copy link
Member Author

@apkille apkille Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I defined set containment of arguments of expressions containing quantum objects with _in(x::SymQObj, y::SymQObj). Performance-wise, it's probably not better, but unless we want to redefine == for quantum objects, it might be better to stick with this option.

src/QSymbolicsBase/basic_ops_inhomogeneous.jl Show resolved Hide resolved
src/QSymbolicsBase/predefined.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/predefined.jl Outdated Show resolved Hide resolved
test/test_express_opt.jl Outdated Show resolved Hide resolved
Copy link
Member

@Krastanov Krastanov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there are 3 very minor correctness issues and the rest looks great!

src/QSymbolicsBase/basic_ops_homogeneous.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/basic_ops_homogeneous.jl Outdated Show resolved Hide resolved
dagger(x::Symbolic{AbstractBra}) = SDagger{AbstractKet}(x)
dagger(x::Symbolic{AbstractKet}) = SDagger{AbstractBra}(x)
dagger(x::Symbolic{AbstractOperator}) = SDagger{AbstractOperator}(x)
dagger(x::SKet) = SBra(x.name, x.basis)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I disagree with this one. You are tinkering beyond the domain of expression trees by doing this operation, while symbolics is usually only about the expression trees. This is a precedent that can make future work more difficult because now expression manipulation logic can not be simply encoded as tree-traversal.

In other words, there is no convenient way to say that SKet(:x) and SBra(:x) are related in the symbolic language we have here, because the pattern matching rules can not peek inside of a leaf term in the expression tree.

This is also related to the commented out test.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, suppose we have a symbolic ket, say |a⟩, and we want to apply dagger to this ket. So instead of following the definition that dagger(|a⟩) == ⟨a|, as done in this PR, we should leave it as dagger(|a⟩) == |a⟩†? And this is because we are kind of cheating with the former approach, rather than traversing the expression tree? I'm not disagreeing with you, I'm just making sure I'm understanding what you're saying.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, that is it. There is no guarantee that |a⟩ and ⟨a| are related at all (except for you implicitly deciding so). To make it explicit you need to write some pattern matching rule that makes it evident that they are related. Such a pattern matching rule would be difficult in a setup that is not based on the expressions API. By just creating a new expression type dagger, that problem of implicit relationships disappears -- everything becomes explicit.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, just made changes.

src/QSymbolicsBase/predefined.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/rules.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/rules.jl Outdated Show resolved Hide resolved
@Krastanov Krastanov merged commit ea51dbf into QuantumSavory:main Jun 19, 2024
13 of 17 checks passed
@Krastanov
Copy link
Member

Woohoo!

@apkille
Copy link
Member Author

apkille commented Jun 19, 2024

Excellent! 😁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants