Source code for qcp.cli.interpret

# Copyright 2022 Tiernan8r
#
# 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
#
#     http://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.
"""
Convert the given CLI arguments and flags into usable input for the algorithms
"""
import sys
from typing import Dict, List, Tuple

from qcp.algorithms.phase_estimation_unitary_matrices import UnitaryMatrices
from qcp.cli.constants import (DEFAULT_EIGENVECTOR_IDX, DEFAULT_PHASE,
                               DEFAULT_TARGET, DEFAULT_UNITARY,
                               EIGENVECTOR_LONG, PHASE_LONG, TARGET_LONG,
                               UNITARY_LONG)
from qcp.cli.options import AlgorithmOption
from qcp.matrices import Matrix


[docs]def interpret_arguments(opt: AlgorithmOption, args: List[str], flags: Dict[str, str]): """ Parse the CLI arguments/flags based off of the algorithm type to simulate :param AlgorithmOption opt: The algorithm chosen :param List[str]: The CLI arguments provided :param Dict[str, str]: The CLI flags provided """ if opt is AlgorithmOption.Grovers: return determine_grover(args, flags) elif opt is AlgorithmOption.PhaseEstimation: return determine_phase_estimation(args, flags) elif opt is AlgorithmOption.Sudoku: return determine_sudoku(args, flags) return ()
[docs]def _determine_qbits(args: List[str]) -> int: """ Read the number of qbits to simulate from the CLI arguments list :param List[str] args: The CLI arguments returns: int: The number of qbits """ # Determine the number of qbits if len(args) < 1: print("Must provide the number of qbits to simulate", file=sys.stderr) exit(1) elif len(args) > 1: print("Too many arguments provided, ignoring extras...", file=sys.stderr) # Take the number to interpret to be the first value in the arguments # list nqbits_str = args[0] nqbits = 2 try: nqbits = int(nqbits_str) except ValueError: print( f"Provided number of qbits '{nqbits_str}' is not an integer!", file=sys.stderr) exit(1) if nqbits < 2: print("Number of qbits to simulate must be >= 2!", file=sys.stderr) exit(1) return nqbits
[docs]def determine_grover(args: List[str], flags: Dict[str, str] ) -> Tuple[int, int]: """ Read the given flags dictionary and arguments map and convert to usable input for the Grover's algorithm. The Grover's Algorithm needs two input. The first is the number of qbits to simulate, and the second is the target state to search for. :param List[str] args: The CLI arguments :param Dict[str,str] flags: The CLI flags returns: Tuple[int, int]: Tuple of the parameters for the constructor, the first is the number of qbits, the second the target bit. """ # Determine the number of qbits nqbits = _determine_qbits(args) # Read the target value from the flag target = DEFAULT_TARGET if TARGET_LONG not in flags: print( f"No target bit provided, defaulting to {DEFAULT_TARGET}", file=sys.stderr) else: target_str = flags[TARGET_LONG] try: target = int(target_str) except ValueError: print( f"Provided target '{target_str}' is not an integer!", file=sys.stderr) exit(1) return nqbits, target
[docs]def determine_phase_estimation(args: List[str], flags: Dict[str, str] ) -> Tuple[int, Matrix, Matrix]: """ Read the given flags dictionary and arguments map and convert to usable input for the PhaseEstimation algorithm. The PhaseEstimation algorithm needs the number of qbits to simulate, and two matrices. The first to use as the unitary matrix in the algorithm and the second to use as the eigenvector. :param List[str] args: The CLI arguments :param Dict[str,str] flags: The CLI flags returns: Tuple[int, Matrix, Matrix]: Tuple of the parameters for the constructor, the first is the number of qbits to simulate, the second the Unitary Matrix to use, and the third the eigenvector. """ # Determine the number of qbits: nqbits = _determine_qbits(args) # Determine the phase shift to use: phase = DEFAULT_PHASE if PHASE_LONG in flags: phase_str = flags[PHASE_LONG] try: phase = float(phase_str) except ValueError: print( f"Provided phase '{phase_str}' is not a number!", file=sys.stderr) exit(1) # Determining the unitary matrix unitary_str = DEFAULT_UNITARY unitary_matrix = UnitaryMatrices(DEFAULT_UNITARY) if UNITARY_LONG not in flags: print( f"No unitary matrix type provided, defaulting to '{unitary_str}'", file=sys.stderr) else: unitary_str = flags[UNITARY_LONG].lower() if unitary_str not in UnitaryMatrices.list(): err_str = "Unitary matrix option '{0}' is not a valid option!" print( err_str.format(unitary_str), file=sys.stderr) print( f"The options are: {UnitaryMatrices.list()}", file=sys.stderr) exit(1) unitary_matrix = UnitaryMatrices(unitary_str) # Determining the Eigenvector to use DEFAULT_EIGENVECTOR_NAME = unitary_matrix.basis_names()[ DEFAULT_EIGENVECTOR_IDX] if EIGENVECTOR_LONG not in flags: flags[EIGENVECTOR_LONG] = DEFAULT_EIGENVECTOR_NAME eigenvector_str = flags[EIGENVECTOR_LONG] bases = unitary_matrix.basis_names() # Get just the inner value of the bra-ket notation, since bash terminals # don't let you type '>' easily # so |0> becomes just 0 available_eigenvectors = [b[1] for b in bases] if eigenvector_str not in available_eigenvectors: print( f"'{eigenvector_str}' is not a valid eigenvector choice, " f"the choices for the '{unitary_matrix.value}'" f" are: {available_eigenvectors}", file=sys.stderr) exit(1) eigenvec_idx = available_eigenvectors.index(eigenvector_str) eigenvec = unitary_matrix.basis()[eigenvec_idx] return nqbits, unitary_matrix.get(phase), eigenvec
[docs]def determine_sudoku(args: List[str], flags: Dict[str, str]): """ Read the given flags dictionary and arguments map and convert to usable input for the Sudoku algorithm. The sudoku algorithm takes no input... :param List[str] args: The CLI arguments :param Dict[str,str] flags: The CLI flags """ return ()