# Copyright 2018 The Cirq Developers
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import Union, Optional, overload
import numpy as np
from cirq.value import symbol
[docs]def chosen_angle_to_half_turns(
half_turns: Optional[Union[symbol.Symbol, float]] = None,
rads: Optional[float] = None,
degs: Optional[float] = None,
default: float = 1.0,
) -> Union[symbol.Symbol, float]:
"""Returns a half_turns value based on the given arguments.
At most one of half_turns, rads, degs must be specified. If none are
specified, the output defaults to half_turns=1.
Args:
half_turns: The number of half turns to rotate by.
rads: The number of radians to rotate by.
degs: The number of degrees to rotate by
default: The half turns angle to use if nothing else is specified.
Returns:
A number of half turns.
"""
if len([1 for e in [half_turns, rads, degs] if e is not None]) > 1:
raise ValueError('Redundant angle specification. '
'Use ONE of half_turns, rads, or degs.')
if rads is not None:
return rads / np.pi
if degs is not None:
return degs / 180
if half_turns is not None:
return half_turns
return default
[docs]def chosen_angle_to_canonical_half_turns(
half_turns: Optional[Union[symbol.Symbol, float]] = None,
rads: Optional[float] = None,
degs: Optional[float] = None,
default: float = 1.0,
) -> Union[symbol.Symbol, float]:
"""Returns a canonicalized half_turns based on the given arguments.
At most one of half_turns, rads, degs must be specified. If none are
specified, the output defaults to half_turns=1.
Args:
half_turns: The number of half turns to rotate by.
rads: The number of radians to rotate by.
degs: The number of degrees to rotate by
default: The half turns angle to use if nothing else is specified.
Returns:
A number of half turns.
"""
return canonicalize_half_turns(
chosen_angle_to_half_turns(
half_turns=half_turns,
rads=rads,
degs=degs,
default=default))
# pylint: disable=function-redefined
@overload
def canonicalize_half_turns(half_turns: float) -> float:
pass
@overload
def canonicalize_half_turns(half_turns: symbol.Symbol) -> symbol.Symbol:
pass
[docs]def canonicalize_half_turns(
half_turns: Union[symbol.Symbol, float]
) -> Union[symbol.Symbol, float]:
"""Wraps the input into the range (-1, +1]."""
if isinstance(half_turns, symbol.Symbol):
return half_turns
half_turns %= 2
if half_turns > 1:
half_turns -= 2
return half_turns
# pylint: enable=function-redefined