-
Notifications
You must be signed in to change notification settings - Fork 376
Conversation
Refactor shor
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.
Hi @MetcalfeTom,
thanks for the work! I've left a few style comments and I've got two more points I think we should address:
-
You're giving names to the operations but they are lost as we use
compose
, since this method adds the contents of the appended circuit directly. By usingappend(circuit.to_instruction)
we can keep the label. I think we should do this, since then printing the circuit is much more organized and people can actually see a circuit that resembles the paper instead of just seeing standard gate operations.┌───┐┌──────────────────────┐ ┌────────────────────────┐ up_0: ┤ H ├┤0 ├─■──■─┤0 ├───┤│ │ │ │ │ up_1: ┤ H ├┤1 ├─┼──┼─┤1 ├───┤│ │ │ │ │ up_2: ┤ H ├┤2 ├─┼──┼─┤2 ├───┤│ │ │ │ │ up_3: ┤ H ├┤3 ├─┼──┼─┤3 ├───┤│ │ │ │ │ down_0: ┤ X ├┤4 ├─X──┼─┤4 └───┘│ multiply_by_2_mod_3 │ │ │ │ multiply_by_2_mod_3_dg down_1: ─────┤5 ├─┼──X─┤5 │ │ │ │ │ aux_0: ─────┤6 ├─X──┼─┤6 │ │ │ │ aux_1: ─────┤7 ├────X─┤7 │ │ │ aux_2: ─────┤8 ├──────┤8 │ │ │ aux_3: ─────┤9 ├──────┤9 └──────────────────────┘ └────────────────────────┘
Also it seems that
compose
is slower thanappend
after doing some timings, sorry for proposing it in the first place! Thoughts? -
I've looked at rebuilding the circuits again and I think we can do this better after all by using parameter binds. Conceptually this is what I'm thinking
angle_params = ParameterVector('angles', len=self._n + 1) controlled_controlled_phi_add_N = .. # build once using the parameters angle_params for i, ctl_up in ... : angles = self._get_angles(a) bound = controlled_controlled_phi_add_N.assign_parameters({angle_params: angles}) # append `bound` to the circuit
So don't compute the angles for the value
a
, but parameterize the circuit on these angles. Then we can bind the correct angles when we add the circuit. Does that make sense?
@Cryoris Thanks for reviewing my code I will take on the suggestion to cast to instruction and append in order to keep the circuit drawings more perspicuous. Though I think that it's a little misleading that these instructions lie across all qubits in the Thanks for the tip about the |
Co-authored-by: Julien Gacon <gaconju@gmail.com>
Just so I can follow, you'd want the results to now look like:
i.e. do not append the error messages to the In that case I would propose altering the output of |
As you are refactoring the algorithm I guess the question would be whether all that detail in the "results", whether an error or factors found is meaningful in anyway as a return. Having it all logged under debug, whether an error or success would allow anyone wanting to see more detail to have it without having a large unwieldy result object. |
If we put additional information I think some data about the complexity is most interesting. Giving the counts and successful counts already somewhat does that, so we'd have something like:
Is there some other information we could include? Since we already return a dict/AlgorithmResult I think its fair to add some information. Otherwise, if it just contains the factors, we could also return them (as list). But that would be an inconsistent return type across the other algos. |
That return format seems quite reasonable. Lets go with that. When we more broadly update the algorithms with interface types and return result we may want a FactorizerResult with some common methods to access result parts and the above count information may be part of some ShorResult subclass thereof. For now lets keep things more as they are and go with the return format as proposed above. |
Refactor result section of Shor
@woodsp-ibm, @Cryoris I addressed the changes. Since we are no longer gathering the reasons for failure, I tried to clean up the |
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.
I think this is good to go! Thanks a lot for the refactor, the constructed circuit looks much nicer now and can be decomposed step-by-step and we're up-to-date with current Terra functionality.
Great work 👍
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.
@MetcalfeTom Thanks for undertaking this refactoring and completing the work. It's much appreciated and it's great to have the algorithm refreshed and brought more up to date.
Thanks for the guidance @Cryoris @woodsp-ibm ! On to the next one 😊 |
* Use AlgorithmResult for return from run() * Store phi_add as a gate, create _init_circuit method * Use inverse and control logic inside controlled_controlled_phi_add_mod_N * Use a separate circuit to be inverted during _controlled_multiple_mod_N * Typing on _get_factors * Import Gate from qiskit.circuit * Use name in init_circuit * Use inverse of controlled_multiple_mod_N * Use gates for multiplication functions * Reduce gate name and keep register order consistent * Revert back to circuit functions * Update documentation and extract modinv * Update documentation in accordance with contribution guidelines * Add tests * Update for spell check * Apply suggestions from code review Co-authored-by: Julien Gacon <gaconju@gmail.com> * Rename to double_controlled_phi_add * Initialise QuantumCircuit without private method * Make modinv error message more meaningful * Remove phi_add_gate test * Add int type hint * Omit quantum register in _phi_add_gate * replace compose calls with append * Use angles ParameterVector and rewrite double_controlled_phi_add_mod_N * Mak phi_add_gate static * Update indexing in _double_controlled_phi_add_mod_N * Move inverted controlled addition into _controlled_multiple_mod_N * Update documentation * Apply angles correctly * Revert "Remove phi_add_gate test" This reverts commit 907e861. * Optimize imports * Update phi_add_gate test logic * Remove phi_add_gate test * Remove redundant qubit index call * rename multiple_mod_N to gate, update formatting * Add extra test case for modinv test * Use circuit.qubits explicitly when reconstructing registers * replace append calls in controlled addition circuit * Make qft an instruction during __init__ * replace compose calls in _controlled_multiple_mod_N_gate * Update docstrings * Apply IQFT at the end of the exponentiation * refactor logging formatting for results * Make trivial factor check less verbose * Return counts of successful results instead of each measurement * Refactor factorization logic and logging in _get_factors() * Add test cases for result counts * Use % for logging statements * extract continued fraction logic * Sort factors in return of _get_factors * rename x_value to x_final * Fix type hint * Do not evaluate i = N+1 in _get_factors() Co-authored-by: Manoel Marques <manoel@us.ibm.com> Co-authored-by: Julien Gacon <jules.gacon@googlemail.com> Co-authored-by: Julien Gacon <gaconju@gmail.com>
* Use AlgorithmResult for return from run() * Store phi_add as a gate, create _init_circuit method * Use inverse and control logic inside controlled_controlled_phi_add_mod_N * Use a separate circuit to be inverted during _controlled_multiple_mod_N * Typing on _get_factors * Import Gate from qiskit.circuit * Use name in init_circuit * Use inverse of controlled_multiple_mod_N * Use gates for multiplication functions * Reduce gate name and keep register order consistent * Revert back to circuit functions * Update documentation and extract modinv * Update documentation in accordance with contribution guidelines * Add tests * Update for spell check * Apply suggestions from code review Co-authored-by: Julien Gacon <gaconju@gmail.com> * Rename to double_controlled_phi_add * Initialise QuantumCircuit without private method * Make modinv error message more meaningful * Remove phi_add_gate test * Add int type hint * Omit quantum register in _phi_add_gate * replace compose calls with append * Use angles ParameterVector and rewrite double_controlled_phi_add_mod_N * Mak phi_add_gate static * Update indexing in _double_controlled_phi_add_mod_N * Move inverted controlled addition into _controlled_multiple_mod_N * Update documentation * Apply angles correctly * Revert "Remove phi_add_gate test" This reverts commit 907e86136b505b627d491251f5f0e54ab9918971. * Optimize imports * Update phi_add_gate test logic * Remove phi_add_gate test * Remove redundant qubit index call * rename multiple_mod_N to gate, update formatting * Add extra test case for modinv test * Use circuit.qubits explicitly when reconstructing registers * replace append calls in controlled addition circuit * Make qft an instruction during __init__ * replace compose calls in _controlled_multiple_mod_N_gate * Update docstrings * Apply IQFT at the end of the exponentiation * refactor logging formatting for results * Make trivial factor check less verbose * Return counts of successful results instead of each measurement * Refactor factorization logic and logging in _get_factors() * Add test cases for result counts * Use % for logging statements * extract continued fraction logic * Sort factors in return of _get_factors * rename x_value to x_final * Fix type hint * Do not evaluate i = N+1 in _get_factors() Co-authored-by: Manoel Marques <manoel@us.ibm.com> Co-authored-by: Julien Gacon <jules.gacon@googlemail.com> Co-authored-by: Julien Gacon <gaconju@gmail.com>
* Use AlgorithmResult for return from run() * Store phi_add as a gate, create _init_circuit method * Use inverse and control logic inside controlled_controlled_phi_add_mod_N * Use a separate circuit to be inverted during _controlled_multiple_mod_N * Typing on _get_factors * Import Gate from qiskit.circuit * Use name in init_circuit * Use inverse of controlled_multiple_mod_N * Use gates for multiplication functions * Reduce gate name and keep register order consistent * Revert back to circuit functions * Update documentation and extract modinv * Update documentation in accordance with contribution guidelines * Add tests * Update for spell check * Apply suggestions from code review Co-authored-by: Julien Gacon <gaconju@gmail.com> * Rename to double_controlled_phi_add * Initialise QuantumCircuit without private method * Make modinv error message more meaningful * Remove phi_add_gate test * Add int type hint * Omit quantum register in _phi_add_gate * replace compose calls with append * Use angles ParameterVector and rewrite double_controlled_phi_add_mod_N * Mak phi_add_gate static * Update indexing in _double_controlled_phi_add_mod_N * Move inverted controlled addition into _controlled_multiple_mod_N * Update documentation * Apply angles correctly * Revert "Remove phi_add_gate test" This reverts commit 907e86136b505b627d491251f5f0e54ab9918971. * Optimize imports * Update phi_add_gate test logic * Remove phi_add_gate test * Remove redundant qubit index call * rename multiple_mod_N to gate, update formatting * Add extra test case for modinv test * Use circuit.qubits explicitly when reconstructing registers * replace append calls in controlled addition circuit * Make qft an instruction during __init__ * replace compose calls in _controlled_multiple_mod_N_gate * Update docstrings * Apply IQFT at the end of the exponentiation * refactor logging formatting for results * Make trivial factor check less verbose * Return counts of successful results instead of each measurement * Refactor factorization logic and logging in _get_factors() * Add test cases for result counts * Use % for logging statements * extract continued fraction logic * Sort factors in return of _get_factors * rename x_value to x_final * Fix type hint * Do not evaluate i = N+1 in _get_factors() Co-authored-by: Manoel Marques <manoel@us.ibm.com> Co-authored-by: Julien Gacon <jules.gacon@googlemail.com> Co-authored-by: Julien Gacon <gaconju@gmail.com>
Fixes #933
Summary
phi_add()
was casted to aGate
instance, allowing.inverse()
and.control()
methods to be used during the construction of the circuit in Shor's algorithmParameterVector
was used during circuit construction to store the phi anglescontrol
andinverse
methods were removed fromShor
H
,X
) where possibleShor
run
method now returns aAlgorithmResult
instance instead of a dictionaryrun
, rather just a count of the total/successful factorizations after executing the quantum circuitDetails and comments
I think it might also be possible to cast the two remaining
controlled
methods toGate
instances as well, then explicitly call.control()
. However since they are parametrised bya
(and theParameterVector
does not support enough complex computations to be used) the gates would have to be recreated multiple times when constructing the circuit, so they have been kept as circuit-level functions.