import numpy as np
from numpy.typing import ArrayLike, NDArray

class ESS:
    def __init__(self, e_max: int, n_max: int, ask: int) -> None: ...
    def n_max(self) -> int: ...
    def e_max(self) -> int: ...
    def ask_num(self) -> int: ...
    def encode(self, index_bits: ArrayLike) -> NDArray[np.uint64]: ...
    def multi_encode(self, multi_index_bits: ArrayLike) -> NDArray[np.uint64]: ...
    def decode(self, sequence: ArrayLike) -> NDArray[np.uint64]: ...
    def multi_decode(self, sequences: ArrayLike) -> NDArray[np.uint64]: ...
    def num_data_bits(self) -> int: ...
    def amplitude_distribution(self) -> NDArray[np.float32]: ...
    def energy_distribution(self) -> NDArray[np.float32]: ...
    def average_energy(self) -> float: ...
    def num_sequences(self) -> str: ...
    def num_sequences_possible(self) -> str: ...

class OESS:
    @staticmethod
    def optimal_e_max(e_max: int, n_max: int, ask_num: int): ...
    def __init__(self, e_max: int, n_max: int, ask: int) -> None: ...
    def n_max(self) -> int: ...
    def e_max(self) -> int: ...
    def ask_num(self) -> int: ...
    def encode(self, index_bits: ArrayLike) -> NDArray[np.uint64]: ...
    def multi_encode(self, multi_index_bits: ArrayLike) -> NDArray[np.uint64]: ...
    def decode(self, sequence: ArrayLike) -> NDArray[np.uint64]: ...
    def multi_decode(self, sequences: ArrayLike) -> NDArray[np.uint64]: ...
    def num_data_bits(self) -> int: ...
    def amplitude_distribution(self) -> NDArray[np.float32]: ...
    def energy_distribution(self) -> NDArray[np.float32]: ...
    def average_energy(self) -> float: ...
    def num_sequences(self) -> str: ...
    def num_sequences_possible(self) -> str: ...
