Open thomashaener opened 6 years ago
I proposed a solution specific to ResourceCounter
in #195 . It might not be the best way. Is there any reason any other compiler engine would need to keep track of an angle tolerance? I can see the potential for that when we do single-qubit rotation synthesis; are there any plans for that yet?
I think it would be nicer to have one global interface instead of users having to specify all tolerances in every compiler engine which may need them (rotation synthesis, optimizers, ...). If we know that angles will only ever be approximated to a certain tolerance, we can perform the merging / cancelling of rotation gates using this information. Since angles are now rounded upon initialization, we have a pretty good setup to achieve this and all we need is an interface exposing ANGLE_TOLERANCE (or PRECISION) to the user (with more to come at a later point). Rotation gates could then be given an additional (optional) tolerance parameter in __init__
(the global angle tolerance being the default value), so tolerances can be specified on a per-object basis if users wish to do so. More generally, also higher-level gates should have such a parameter (e.g., QFT).
I still think that adding more options to the resource counter would be nice (but this is somewhat separate from this issue). It would definitely be useful if there were options to control the grouping of gates in the output. Your PR which adds grouping by '(control count + ) class names' is a good first step.
There are no concrete plans yet but we will definitely need to implement rotation synthesis at some point :-)
What if we made the angle precision a property of MainEngine
, or an attribute with getter and setter methods? Then any compiler engine can obtain the value through its reference to its main engine. The MainEngine could round all angles before forwarding commands to the next engine (though this might not work together with per-object tolerances).
I think gate tolerances should be exposed on a more global level, e.g., in projectq.ops.config
. There, we can define default values and users can use something like projectq.ops.configure('some file')
to change these default values (and maybe more functions to change individual or groups of values).
This would allow easy handling of both per-class and per-object tolerances since every gate can just access the global tolerance and use it as the default value in __init__
.
Having per-object tolerances would of course introduce the need for more complicated merge and comparison functions because once there are different tolerances, those can no longer be implemented via rounding upon initialization.
Write an interface which makes it easier for users to define tolerances (e.g., rotation angles).