
"""simple docstring"""



from typing import Any


def 			_UpperCamelCase						(    _A       ,   _A       ,   _A       ,   _A       ,   _A       ,   )     ->	list:





    """simple docstring"""

    _validation(
        _A       ,   _A       ,   _A       ,   _A       ,   _A       ,   )
    # Creates data structures and fill initial step
    _UpperCAmelCase        = {}
    _UpperCAmelCase        = {}
    for state in states_space:
        _UpperCAmelCase        = observations_space[0]
        _UpperCAmelCase        = (
            initial_probabilities[state] * emission_probabilities[state][observation]
        )
        _UpperCAmelCase        = None

    # Fills the data structure with the probabilities of
    # different transitions and pointers to previous states
    for o in range(1       ,   len(_A   )   ):
        _UpperCAmelCase        = observations_space[o]
        _UpperCAmelCase        = observations_space[o - 1]
        for state in states_space:
            # Calculates the argmax for probability function
            _UpperCAmelCase        = """"""
            _UpperCAmelCase        = -1
            for k_state in states_space:
                _UpperCAmelCase        = (
                    probabilities[(k_state, prior_observation)]
                    * transition_probabilities[k_state][state]
                    * emission_probabilities[state][observation]
                )
                if probability > max_probability:
                    _UpperCAmelCase        = probability
                    _UpperCAmelCase        = k_state

            # Update probabilities and pointers dicts
            _UpperCAmelCase        = (
                probabilities[(arg_max, prior_observation)]
                * transition_probabilities[arg_max][state]
                * emission_probabilities[state][observation]
            )

            _UpperCAmelCase        = arg_max

    # The final observation
    _UpperCAmelCase        = observations_space[len(_A   ) - 1]

    # argmax for given final observation
    _UpperCAmelCase        = """"""
    _UpperCAmelCase        = -1
    for k_state in states_space:
        _UpperCAmelCase        = probabilities[(k_state, final_observation)]
        if probability > max_probability:
            _UpperCAmelCase        = probability
            _UpperCAmelCase        = k_state
    _UpperCAmelCase        = arg_max

    # Process pointers backwards
    _UpperCAmelCase        = last_state
    _UpperCAmelCase        = []
    for o in range(len(_A   ) - 1       ,   -1       ,   -1   ):
        result.append(_A   )
        _UpperCAmelCase        = pointers[previous, observations_space[o]]
    result.reverse()

    return result


def 			_UpperCamelCase						(    _A       ,   _A       ,   _A       ,   _A       ,   _A       ,   )     ->	None:





    """simple docstring"""

    _validate_not_empty(
        _A       ,   _A       ,   _A       ,   _A       ,   _A       ,   )
    _validate_lists(_A       ,   _A   )
    _validate_dicts(
        _A       ,   _A       ,   _A   )


def 			_UpperCamelCase						(    _A       ,   _A       ,   _A       ,   _A       ,   _A       ,   )     ->	None:





    """simple docstring"""

    if not all(
        [
            observations_space,
            states_space,
            initial_probabilities,
            transition_probabilities,
            emission_probabilities,
        ]   ):
        raise ValueError("""There's an empty parameter"""   )


def 			_UpperCamelCase						(    _A       ,   _A   )     ->	None:





    """simple docstring"""

    _validate_list(_A       ,   """observations_space"""   )
    _validate_list(_A       ,   """states_space"""   )


def 			_UpperCamelCase						(    _A       ,   _A   )     ->	None:





    """simple docstring"""

    if not isinstance(_object       ,   _A   ):
        _UpperCAmelCase        = F"""{var_name} must be a list"""
        raise ValueError(_A   )
    else:
        for x in _object:
            if not isinstance(_A       ,   _A   ):
                _UpperCAmelCase        = F"""{var_name} must be a list of strings"""
                raise ValueError(_A   )


def 			_UpperCamelCase						(    _A       ,   _A       ,   _A       ,   )     ->	None:





    """simple docstring"""

    _validate_dict(_A       ,   """initial_probabilities"""       ,   _A   )
    _validate_nested_dict(_A       ,   """transition_probabilities"""   )
    _validate_nested_dict(_A       ,   """emission_probabilities"""   )


def 			_UpperCamelCase						(    _A       ,   _A   )     ->	None:





    """simple docstring"""

    _validate_dict(_object       ,   _A       ,   _A   )
    for x in _object.values():
        _validate_dict(_A       ,   _A       ,   _A       ,   _A   )


def 			_UpperCamelCase						(    _A       ,   _A       ,   _A       ,   _A = False   )     ->	None:





    """simple docstring"""

    if not isinstance(_object       ,   _A   ):
        _UpperCAmelCase        = F"""{var_name} must be a dict"""
        raise ValueError(_A   )
    if not all(isinstance(_A       ,   _A   ) for x in _object   ):
        _UpperCAmelCase        = F"""{var_name} all keys must be strings"""
        raise ValueError(_A   )
    if not all(isinstance(_A       ,   _A   ) for x in _object.values()   ):
        _UpperCAmelCase        = """nested dictionary """ if nested else """"""
        _UpperCAmelCase        = F"""{var_name} {nested_text}all values must be {value_type.__name__}"""
        raise ValueError(_A   )


if __name__ == "__main__":
 from doctest import testmod

 testmod()

"""simple docstring"""



import math




class 		a_    :







    def   _snake_case       (      self      :							List[Any]  ,       __UpperCamelCase      :							list[list[float]]  ,       __UpperCamelCase      :							list[int]  )		->int:






        '''simple docstring'''






        _UpperCAmelCase        = 0.0
        _UpperCAmelCase        = 0.0
        for i in range(len(__UpperCamelCase  )  ):
            da += math.pow((sample[i] - weights[0][i])  ,       2  )
            da += math.pow((sample[i] - weights[1][i])  ,       2  )
            return 0 if da > da else 1
        return 0







    def   _snake_case       (      self      :							Dict  ,       __UpperCamelCase      :							list[list[int | float]]  ,       __UpperCamelCase      :							list[int]  ,       __UpperCamelCase      :							int  ,       __UpperCamelCase      :							float  )		->list[list[int | float]]:






        '''simple docstring'''






        for i in range(len(__UpperCamelCase  )  ):
            weights[j][i] += alpha * (sample[i] - weights[j][i])
        return weights







def 			_UpperCamelCase						(    )     ->	None:





    """simple docstring"""

    _UpperCAmelCase        = [[1, 1, 0, 0], [0, 0, 0, 1], [1, 0, 0, 0], [0, 0, 1, 1]]

    # weight initialization ( n, C )
    _UpperCAmelCase        = [[0.2, 0.6, 0.5, 0.9], [0.8, 0.4, 0.7, 0.3]]

    # training
    _UpperCAmelCase        = SelfOrganizingMap()
    _UpperCAmelCase        = 3
    _UpperCAmelCase        = 0.5

    for _ in range(_A   ):
        for j in range(len(_A   )   ):
            # training sample
            _UpperCAmelCase        = training_samples[j]

            # Compute the winning vector
            _UpperCAmelCase        = self_organizing_map.get_winner(_A       ,   _A   )

            # Update the winning vector
            _UpperCAmelCase        = self_organizing_map.update(_A       ,   _A       ,   _A       ,   _A   )

    # classify test sample
    _UpperCAmelCase        = [0, 0, 0, 1]
    _UpperCAmelCase        = self_organizing_map.get_winner(_A       ,   _A   )

    # results
    print(F"""Clusters that the test sample belongs to : {winner}"""   )
    print(F"""Weights that have been trained : {weights}"""   )


# running the main() function
if __name__ == "__main__":
 main()