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

trace, partial trace, and superoperators #55

Merged
merged 26 commits into from
Jul 19, 2024

Conversation

apkille
Copy link
Member

@apkille apkille commented Jun 26, 2024

Added trace and partial trace functionalities with examples and tests. Also created a symbolic superoperator SSuperOperator, including an option to express instances of this composite type in the Kraus representation with the function kraus. Future work can be done to create additional superoperator representations and conversions between each of them.

In the process of developing this branch, I encountered a few bugs mentioned in #53 and #54, which I fix in this PR.

@apkille
Copy link
Member Author

apkille commented Jun 26, 2024

The failed tests seem to come from the recent bumped compat for TermInterface #52, although most recent docs (https://juliasymbolics.github.io/TermInterface.jl/dev/) say that implementing sorted_arguments is optional.

 MethodError: no method matching sorted_arguments(::QuantumSymbolics.STrace)
│    
│    Closest candidates are:
│      sorted_arguments(::SymbolicUtils.PolyForm)
│       @ SymbolicUtils ~/.julia/packages/SymbolicUtils/dtCid/src/polyform.jl:235
│      sorted_arguments(::SymbolicUtils.BasicSymbolic)
│       @ SymbolicUtils ~/.julia/packages/SymbolicUtils/dtCid/src/types.jl:119

Copy link

codecov bot commented Jun 26, 2024

Codecov Report

Attention: Patch coverage is 89.05109% with 15 lines in your changes missing coverage. Please review.

Project coverage is 74.23%. Comparing base (c9d8eed) to head (9f05adb).

Files Patch % Lines
src/QSymbolicsBase/basic_superops.jl 59.09% 9 Missing ⚠️
src/QSymbolicsBase/linalg.jl 91.54% 6 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #55      +/-   ##
==========================================
+ Coverage   70.46%   74.23%   +3.77%     
==========================================
  Files          17       18       +1     
  Lines         650      753     +103     
==========================================
+ Hits          458      559     +101     
- Misses        192      194       +2     

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

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.

great start! There are a few things I want us to discuss before considering for merging

src/QSymbolicsBase/QSymbolicsBase.jl 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
Comment on lines 371 to 376
function ptrace(x::STensorOperator, s)
terms = arguments(x)
sys_op = terms[s]
new_terms = deleteat!(copy(terms), s)
isone(length(new_terms)) ? tr(sys_op)*first(new_terms) : tr(sys_op)*STensorOperator(new_terms)
end
Copy link
Member

Choose a reason for hiding this comment

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

This is actually a bit worse than this. You can have @op A SpinBasis(1//2)^2, i.e. the symbolic operator is already over a composite basis. The number of subsystem would be the number of subsystems in basis, which might be different from the number of terms in the tensor product.

Also, what if flattening has not happened. E.g ptrace(A⊗(B⊗C+D⊗E), 2)?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, these are both fair comments. Will make changes.

Copy link
Member Author

Choose a reason for hiding this comment

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

Just found another small bug:

julia> @op A; @op B; @op C;

julia> tp = A⊗B⊗C
((A⊗B)⊗C)

julia> QuantumSymbolics.arguments(tp)
2-element Vector{Any}:
 (A⊗B)
 C

We would want tp to show (A⊗B⊗C) and QuantumSymbolics.arguments(tp) to be a 3-element vector of the symbolic operators.

Weird. I wonder why this doesn't happen for multiplication of operators:

julia> mp = A*B*C
ABC

julia> QuantumSymbolics.arguments(mp)
3-element Vector{Any}:
 A
 B
 C

Copy link
Member Author

Choose a reason for hiding this comment

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

Also, what if flattening has not happened. E.g ptrace(A⊗(B⊗C+D⊗E), 2)?

A question somewhat related to this: should we have a function in the package that expands expressions? For instance, if a user for some reason wanted to convert A⊗(B⊗C+D⊗E) into A⊗B⊗C+A⊗D⊗E, shouldn't they have a way to do that? Maybe we could call it qexpand, using the q prefix the same we do for qsimplify.

Copy link
Member

Choose a reason for hiding this comment

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

yup, let's have a qexpand for now. Maybe at some point we will just hook into the standard expand and at that point it can be just an alias without making a breaking release

concerning the difference between mul and tensor, I think it is because prefactorscalings were created for tensor, and it has been kinda hackishly applied to mul. We probably need to clean prefactorscalings to work on both. I will make a separate issue for that.

Copy link
Member

Choose a reason for hiding this comment

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

Wait, no that is overly complicated. Why not just have scalar=true always. Is there a situation that benefits from scalar=false?

Copy link
Member

Choose a reason for hiding this comment

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

yes about a new file

Copy link
Member Author

@apkille apkille Jun 28, 2024

Choose a reason for hiding this comment

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

It's my understanding that prefactorscalings was originally created for tensor product properties. For instance, |k1⟩⊗(A*|k2⟩) would give A|k1⟩|k2⟩.

Copy link
Member Author

Choose a reason for hiding this comment

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

Regardless, I will clean up the scaling and flattening functions.

Copy link
Member

Choose a reason for hiding this comment

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

prefactorscaling was always meant only for scalars. The operator identity you are giving is wrong because A is defined to act on the Hilbert space of k2, not on the composite hilbert space of k1k2.

@Krastanov
Copy link
Member

Just so that I do not get lost, could you point out in this comment thread what are the fixes for #53 and #54? And the corresponding test?

@Krastanov
Copy link
Member

For the spellchecker issue, BA can be whitelisted in https://github.com/QuantumSavory/QuantumSymbolics.jl/blob/main/.typos.toml

@@ -92,4 +106,4 @@ symbollabel(x::SZero) = "𝟎"
basis(x::SZero) = nothing

Base.show(io::IO, x::SZero) = print(io, symbollabel(x))
Base.iszero(x::SymQObj) = isa(x, SZero)
Base.iszero(x::Union{SymQObj, Symbolic{Number}, Symbolic{Complex}}) = isa(x, SZero)
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 the new iszero implementations here are type piracy. Where are they needed?

Copy link
Member Author

Choose a reason for hiding this comment

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

This fixes a bug mentioned in #54 as well: #54 (comment).

src/QSymbolicsBase/rules.jl Outdated Show resolved Hide resolved
@apkille apkille marked this pull request as draft June 29, 2024 01:34
@apkille
Copy link
Member Author

apkille commented Jun 29, 2024

I marked this PR as a draft because I first want to clean up the scaling and flattening functions, and also implement a qexpand function for expanding quantum expressions. Since this PR adds a lot of features, I would like to submit these changes in a separate PR.

@apkille apkille marked this pull request as ready for review July 2, 2024 19:24
@apkille apkille requested a review from Krastanov July 2, 2024 19:24
@Krastanov
Copy link
Member

The downstream buildkite error is known and unrelated.

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 did a quick review, I have not had a chance to go through everything yet. I think there are a few minor issues with basis checks.

src/QSymbolicsBase/QSymbolicsBase.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/basic_superops.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/basic_superops.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/basic_superops.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/basic_superops.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/linalg.jl Outdated Show resolved Hide resolved
test/test_expand.jl Outdated Show resolved Hide resolved
test/test_expand.jl Outdated Show resolved Hide resolved
test/test_expand.jl Outdated Show resolved Hide resolved
test/test_trace.jl Outdated Show resolved Hide resolved
@Krastanov
Copy link
Member

Just FYI, QuantumInterface.jl provides some basis checking foundations and error types: https://github.com/qojulia/QuantumInterface.jl/blob/main/src/bases.jl#L140-L180

@Krastanov Krastanov self-requested a review July 17, 2024 20:04
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 good!

I left a bunch of comments related to an annoyance with QuantumInterface and created an issue to track it qojulia/QuantumInterface.jl#25

I would suggest merging this without addressing that issue, as otherwise there will be too much delay (and it is not a correctness issue).

I left a few other minor comments. Feel free to merge this when you have chance to address them.

Thanks for setting all of this up!

src/QSymbolicsBase/basic_ops_homogeneous.jl Show resolved Hide resolved
src/QSymbolicsBase/basic_ops_homogeneous.jl Show resolved Hide resolved
src/QSymbolicsBase/basic_ops_homogeneous.jl Show resolved Hide resolved
src/QSymbolicsBase/basic_ops_inhomogeneous.jl Show resolved Hide resolved
src/QSymbolicsBase/basic_ops_inhomogeneous.jl Show resolved Hide resolved
src/QSymbolicsBase/linalg.jl Outdated Show resolved Hide resolved
src/QSymbolicsBase/linalg.jl Show resolved Hide resolved
src/QSymbolicsBase/linalg.jl Show resolved Hide resolved
src/QSymbolicsBase/predefined.jl Outdated Show resolved Hide resolved
test/test_basis_consistency.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 forgot to check the coverage. There are a couple of lines that would be nice to test (and one of them is related to a broken doctest)

head(x::KrausRepr) = :kraus
children(x::KrausRepr) = [:kraus; x.krausops]
kraus(xs::Symbolic{AbstractOperator}...) = KrausRepr(collect(xs))
basis(x::KrausRepr) = basis(first(x.krausops))
Copy link
Member

Choose a reason for hiding this comment

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

coverage review: could you add a test for this line

src/QSymbolicsBase/basic_superops.jl Show resolved Hide resolved
src/QSymbolicsBase/basic_superops.jl Show resolved Hide resolved
src/QSymbolicsBase/literal_objects.jl Show resolved Hide resolved
@apkille apkille dismissed Krastanov’s stale review July 19, 2024 18:24

Permission to merge

@apkille apkille merged commit 68fbe00 into QuantumSavory:main Jul 19, 2024
16 of 17 checks passed
@apkille apkille deleted the channels branch July 19, 2024 18:30
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.

None yet

2 participants