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
Hadamard transform efficient #1688
Hadamard transform efficient #1688
Conversation
For loops are slow.
…tinez/qutip into hadamard_transform_efficient
@BoxiLi How should we handle such changes to qutip/qip in v4.6 since for qutip 5 this will be deprecated. Should these improvements be made directly to qutip-qip? We do not want to end up with three different versions (qutip 4.x, qutip 5 and qutip-qip). |
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.
Left one tiny suggestion, but this looks great -- easier to read and 70x faster. Thank you for adding the test.
What made you trip over this?
Co-authored-by: Simon Cross <hodgestar+github@gmail.com>
@quantshah @BoxiLi I assume the plan is to backport this to qutip-qip (as with the other qutip.qip changes in 4.X)? @AGaliciaMartinez You're welcome to open a copy of this change in the qutip-qip repo once it's merged if you like? That would save @BoxiLi doing it (and it's good to have more eyes on qutip-qip). |
I was using this function with N=13 for some testing code I have and realised it took too long to create the matrix. |
Co-authored-by: Simon Cross <hodgestar+github@gmail.com>
As it is quite a short (but efficient!) change, we can keep it both in qutip and in qutip-qip. Also, I remember this function is also used in the control module (also for testing I think). So we need it in qutip anyway. Eventually, I think it is best to keep these commonly used function in |
There's another interesting technique that's sometimes applicable in these sort of repeating cases. Rather than passing a list of the same elements to out, tmp = H, H
for i in n.bit_length():
tmp = tensor(tmp, tmp)
if n & (1 << i):
out = tensor(out, tmp) (very very approximately - I've almost certainly got the indexing wrong). The idea is that you only perform Now, this might not actually give you much of a speed up in this case, because the calculation is still going to be dominated by the final tensor product, since the output matrix keeps getting larger. But in things like integer matrix powers, bigint calculations, or binomial expansions, this type of thing can be super useful! QuTiP 5 uses an algorithm like this for matrix powers. (I imagine SciPy does too, but for all the normal reasons, we don't use their implementation.) edit: here it is: Lines 17 to 39 in 559387e
|
…m_efficient Improve Hadamard transform efficiency by up to ~70x.
Description
Improved efficiency of the hadamard gate creation time as it was using python for loops which are terribly slow. For N=10 it goes down from 522ms to roughly 7ms.
Changelog
Improved hadamard_transform efficiency (70x faster for N=10).