-
Notifications
You must be signed in to change notification settings - Fork 34
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
Added multiplication of LazyOperators #108
Conversation
Codecov Report
@@ Coverage Diff @@
## master #108 +/- ##
==========================================
+ Coverage 93.33% 93.39% +0.05%
==========================================
Files 24 24
Lines 2881 2907 +26
==========================================
+ Hits 2689 2715 +26
Misses 192 192
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
for i in eachindex(a.operators) | ||
c[i] = LazyProduct(a.operators[i]) * b | ||
end | ||
LazySum(a.basis_l, b.basis_r, a.factors, (c...,)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have an array typed to AbstractOperator
. If your array is already meant to contain abstract types, there is not much reason to do anything more specific than Any
, especially given that it would be slightly more readable code.
More importantly though, here you create a temporary array and then you immediately destroy it. It is a bit wasteful (causing unnecessary allocations). It might be a bit simpler to just use a "generator" (a "lazy" object that does not actually compute the content until it is queried):
julia> generator = (i for i in 1:10)
Base.Generator{UnitRange{Int64}, typeof(identity)}(identity, 1:10)
julia> tuple = (generator...,)
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
So your code can be simplified to something like LazySum(bl, br, a.factors, ((LazyProduct(op)*b for op in a.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...,)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same simplificaiton here
I suggested some minor simplifications, but they are more of a style suggestion, no need to actually follow up on them. They will save one allocation each, but this is not a place in the codebase that saving an allocation is very valuable. Especially given that for the third method you have defined, they are not much of a simplification anyway. Looks good to merge for me! I would also love to have access to this as work is picking up momentum on QuantumSavory and QuantumSymbolics. Could you also bump the version number to 0.4.4. I will wait for a couple of days if anyone else wants to comment on this before merging. |
Actually, the bump in Project.toml should be to 0.4.5 |
I take the comment about merging in the nearterm back. I think this overlaps a bit with #104 which we should evaluate first, as it brings up a bunch of other functionality as well. |
@mabuni1998 , now that #104 is merged, I think we can close this one as it is a subset of #104. Please let me know if anything is missing from #104 and we can cherry pick it into a new PR. |
Added functions for multiplying two LazySum operators, LazySum with LazyTensor / LazyProduct and LazyTensor with LazyProduct. I also added tests for the new functions.
Although debatable whether necessary, there might be situations where you would prefer not to explicitly have to calculate the product and create the appropriate LazyOperator. For example, if you wanted to create a unitary time evolution operator you might write:
where H is a LazyOperator. This is currently not possible, but with the few added lines of code here, you can do the above.
One thing to note is that when multiplying a non-lazy operator with a LazyOperator currently the following functions are used:
QuantumOpticsBase.jl/src/operators_dense.jl
Lines 91 to 110 in f98ec89
The LazyOperators are thus not contagious with non-lazy operators in multiplication. This is, however, probably for the best since the above lines of code are also used when computing multiplication with a density matrix (which is represented as an operator) and in this instance, we don't want to create a LazyOperator but actually calculate e.g. the expectation value. If we wanted to have contagious LazyOperators in multiplication we would have to distinguish between operators and density matrices.