'''simple docstring'''







from __future__ import annotations

import numpy as np
from numpy import floataa
from numpy.typing import NDArray


def    lowerCamelCase       (			UpperCAmelCase__				:  NDArray[floataa]				,						UpperCAmelCase__				:  NDArray[floataa]				,						UpperCAmelCase__				:  list[int]				,						UpperCAmelCase__				:  int				,						)			->	list[float]:


							'''simple docstring'''






							SCREAMING_SNAKE_CASE__    ,      SCREAMING_SNAKE_CASE__     :Any						    = coefficient_matrix.shape
							SCREAMING_SNAKE_CASE__    ,      SCREAMING_SNAKE_CASE__     :List[str]						    = constant_matrix.shape

							if rowsa != colsa:
														SCREAMING_SNAKE_CASE__     :Optional[int]						    = F'''Coefficient matrix dimensions must be nxn but received {rowsa}x{colsa}'''
														raise ValueError(UpperCAmelCase__		)

							if colsa != 1:
														SCREAMING_SNAKE_CASE__     :Optional[int]						    = F'''Constant matrix must be nx1 but received {rowsa}x{colsa}'''
														raise ValueError(UpperCAmelCase__		)

							if rowsa != rowsa:
														SCREAMING_SNAKE_CASE__     :str						    = (
														    'Coefficient and constant matrices dimensions must be nxn and nx1 but '
														    F'''received {rowsa}x{colsa} and {rowsa}x{colsa}'''
														)
														raise ValueError(UpperCAmelCase__		)

							if len(UpperCAmelCase__		) != rowsa:
														SCREAMING_SNAKE_CASE__     :Optional[int]						    = (
														    'Number of initial values must be equal to number of rows in coefficient '
														    F'''matrix but received {len(UpperCAmelCase__		)} and {rowsa}'''
														)
														raise ValueError(UpperCAmelCase__		)

							if iterations <= 0:
														raise ValueError('Iterations must be at least 1'		)

							SCREAMING_SNAKE_CASE__     :NDArray[floataa]						    = np.concatenate(
							    (coefficient_matrix, constant_matrix)				,						axis=1		)

							SCREAMING_SNAKE_CASE__    ,      SCREAMING_SNAKE_CASE__     :Tuple						    = table.shape

							strictly_diagonally_dominant(UpperCAmelCase__		)

							# Iterates the whole matrix for given number of times
							for _ in range(UpperCAmelCase__		):
														SCREAMING_SNAKE_CASE__     :List[Any]						    = []
														for row in range(UpperCAmelCase__		):
																					SCREAMING_SNAKE_CASE__     :str						    = 0
																					for col in range(UpperCAmelCase__		):
																												if col == row:
																																			SCREAMING_SNAKE_CASE__     :Union[str, Any]						    = table[row][col]
																												elif col == cols - 1:
																																			SCREAMING_SNAKE_CASE__     :List[Any]						    = table[row][col]
																												else:
																																			temp += (-1) * table[row][col] * init_val[col]
																					SCREAMING_SNAKE_CASE__     :Any						    = (temp + val) / denom
																					new_val.append(UpperCAmelCase__		)
														SCREAMING_SNAKE_CASE__     :Any						    = new_val

							return [float(UpperCAmelCase__		) for i in new_val]


def    lowerCamelCase       (			UpperCAmelCase__				:  NDArray[floataa]		)			->	bool:


							'''simple docstring'''






							SCREAMING_SNAKE_CASE__    ,      SCREAMING_SNAKE_CASE__     :Tuple						    = table.shape

							SCREAMING_SNAKE_CASE__     :Optional[int]						    = True

							for i in range(0				,						UpperCAmelCase__		):
														SCREAMING_SNAKE_CASE__     :Optional[int]						    = 0
														for j in range(0				,						cols - 1		):
																					if i == j:
																												continue
																					else:
																												total += table[i][j]

														if table[i][i] <= total:
																					raise ValueError('Coefficient matrix is not strictly diagonally dominant'		)

							return is_diagonally_dominant


# Test Cases
if __name__ == "__main__":
		import doctest

		doctest.testmod()







'''simple docstring'''







import numpy as np
import qiskit


def    lowerCamelCase       (			UpperCAmelCase__				:  int = 8				,						UpperCAmelCase__				:  int | None = None		)			->	str:


							'''simple docstring'''






							SCREAMING_SNAKE_CASE__     :Union[str, Any]						    = np.random.default_rng(seed=UpperCAmelCase__		)

							# Roughly 25% of the qubits will contribute to the key.
							# So we take more than we need.
							SCREAMING_SNAKE_CASE__     :Optional[int]						    = 6 * key_len
							# Measurement basis for Alice's qubits.
							SCREAMING_SNAKE_CASE__     :Union[str, Any]						    = rng.integers(2				,						size=UpperCAmelCase__		)
							# The set of states Alice will prepare.
							SCREAMING_SNAKE_CASE__     :List[Any]						    = rng.integers(2				,						size=UpperCAmelCase__		)
							# Measurement basis for Bob's qubits.
							SCREAMING_SNAKE_CASE__     :str						    = rng.integers(2				,						size=UpperCAmelCase__		)

							# Quantum Circuit to simulate BB84
							SCREAMING_SNAKE_CASE__     :int						    = qiskit.QuantumCircuit(UpperCAmelCase__				,						name='BB84'		)

							# Alice prepares her qubits according to rules above.
							for index, _ in enumerate(UpperCAmelCase__		):
														if alice_state[index] == 1:
																					bbaa_circ.x(UpperCAmelCase__		)
														if alice_basis[index] == 1:
																					bbaa_circ.h(UpperCAmelCase__		)
							bbaa_circ.barrier()

							# Bob measures the received qubits according to rules above.
							for index, _ in enumerate(UpperCAmelCase__		):
														if bob_basis[index] == 1:
																					bbaa_circ.h(UpperCAmelCase__		)

							bbaa_circ.barrier()
							bbaa_circ.measure_all()

							# Simulate the quantum circuit.
							SCREAMING_SNAKE_CASE__     :str						    = qiskit.Aer.get_backend('aer_simulator'		)
							# We only need to run one shot because the key is unique.
							# Multiple shots will produce the same key.
							SCREAMING_SNAKE_CASE__     :int						    = qiskit.execute(UpperCAmelCase__				,						UpperCAmelCase__				,						shots=1				,						seed_simulator=UpperCAmelCase__		)
							# Returns the result of measurement.
							SCREAMING_SNAKE_CASE__     :List[Any]						    = job.result().get_counts(UpperCAmelCase__		).most_frequent()

							# Extracting the generated key from the simulation results.
							# Only keep measurement results where Alice and Bob chose the same basis.
							SCREAMING_SNAKE_CASE__     :Any						    = ''.join(
							    [
							        result_bit
							        for alice_basis_bit, bob_basis_bit, result_bit in zip(
							            UpperCAmelCase__				,						UpperCAmelCase__				,						UpperCAmelCase__		)
							        if alice_basis_bit == bob_basis_bit
							    ]		)

							# Get final key. Pad with 0 if too short, otherwise truncate.
							SCREAMING_SNAKE_CASE__     :Optional[Any]						    = gen_key[:key_len] if len(UpperCAmelCase__		) >= key_len else gen_key.ljust(UpperCAmelCase__				,						'0'		)
							return key


if __name__ == "__main__":
		print(f"The generated key is : {bbaa(8, seed=0)}")
		from doctest import testmod

		testmod()






