





import numpy as np
import torch
from torch.utils.data import Dataset, IterableDataset

from ..utils.generic import ModelOutput


class 							__UpperCAmelCase							(						__snake_case   ):



						"""simple docstring"""







						def __init__(   self	,		SCREAMING_SNAKE_CASE	,		SCREAMING_SNAKE_CASE	,		SCREAMING_SNAKE_CASE				) ->      Dict:





												"""simple docstring"""
												UpperCamelCase  							= dataset
												UpperCamelCase  							= process
												UpperCamelCase  							= params




						def __len__(   self				) ->      Any:





												"""simple docstring"""
												return len(self.dataset				)




						def __getitem__(   self	,		SCREAMING_SNAKE_CASE				) ->      int:





												"""simple docstring"""
												UpperCamelCase  							= self.dataset[i]
												UpperCamelCase  							= self.process(SCREAMING_SNAKE_CASE	,		**self.params				)
												return processed


class 							__UpperCAmelCase							(						__snake_case   ):



						"""simple docstring"""







						def __init__(   self	,		SCREAMING_SNAKE_CASE	,		SCREAMING_SNAKE_CASE	,		SCREAMING_SNAKE_CASE	,		SCREAMING_SNAKE_CASE=None				) ->      Optional[int]:





												"""simple docstring"""
												UpperCamelCase  							= loader
												UpperCamelCase  							= infer
												UpperCamelCase  							= params
												if loader_batch_size == 1:
																		# Let's spare some time by deactivating altogether
																		UpperCamelCase  							= None
												UpperCamelCase  							= loader_batch_size

												# Internal bookkeeping
												UpperCamelCase  							= None
												UpperCamelCase  							= None




						def __len__(   self				) ->      Any:





												"""simple docstring"""
												return len(self.loader				)




						def __iter__(   self				) ->      Optional[Any]:





												"""simple docstring"""
												UpperCamelCase  							= iter(self.loader				)
												return self




						def 		__lowerCAmelCase			(   self				) ->      List[str]:





												"""simple docstring"""
												if isinstance(self._loader_batch_data	,		torch.Tensor				):
																		# Batch data is simple tensor, just fetch the slice
																		UpperCamelCase  							= self._loader_batch_data[self._loader_batch_index]
												else:
																		# Batch data is assumed to be BaseModelOutput (or dict)
																		UpperCamelCase  							= {}
																		for k, element in self._loader_batch_data.items():
																								if isinstance(SCREAMING_SNAKE_CASE	,		SCREAMING_SNAKE_CASE				):
																														# Convert ModelOutput to tuple first
																														UpperCamelCase  							= element.to_tuple()
																														if isinstance(element[0]	,		torch.Tensor				):
																																				UpperCamelCase  							= tuple(el[self._loader_batch_index].unsqueeze(0				) for el in element				)
																														elif isinstance(element[0]	,		np.ndarray				):
																																				UpperCamelCase  							= tuple(np.expand_dims(el[self._loader_batch_index]	,		0				) for el in element				)
																														continue
																								if k in {"hidden_states", "past_key_values", "attentions"} and isinstance(SCREAMING_SNAKE_CASE	,		SCREAMING_SNAKE_CASE				):
																														# Those are stored as lists of tensors so need specific unbatching.
																														if isinstance(element[0]	,		torch.Tensor				):
																																				UpperCamelCase  							= tuple(el[self._loader_batch_index].unsqueeze(0				) for el in element				)
																														elif isinstance(element[0]	,		np.ndarray				):
																																				UpperCamelCase  							= tuple(np.expand_dims(el[self._loader_batch_index]	,		0				) for el in element				)
																														continue
																								if element is None:
																														# This can happen for optional data that get passed around
																														UpperCamelCase  							= None
																								elif isinstance(element[self._loader_batch_index]	,		torch.Tensor				):
																														# Take correct batch data, but make it looked like batch_size=1
																														# For compatibility with other methods within transformers

																														UpperCamelCase  							= element[self._loader_batch_index].unsqueeze(0				)
																								elif isinstance(element[self._loader_batch_index]	,		np.ndarray				):
																														# Take correct batch data, but make it looked like batch_size=1
																														# For compatibility with other methods within transformers
																														UpperCamelCase  							= np.expand_dims(element[self._loader_batch_index]	,		0				)
																								else:
																														# This is typically a list, so no need to `unsqueeze`.
																														UpperCamelCase  							= element[self._loader_batch_index]
            # Recreate the element by reusing the original class to make it look
            # batch_size=1
																		UpperCamelCase  							= self._loader_batch_data.__class__(SCREAMING_SNAKE_CASE				)
												self._loader_batch_index += 1
												return result




						def 		__lowerCAmelCase			(   self				) ->      str:





												"""simple docstring"""
												if self._loader_batch_index is not None and self._loader_batch_index < self.loader_batch_size:
																		# We are currently unrolling a batch so we just need to return
																		# the current item within a batch
																		return self.loader_batch_item()

												# We're out of items within a batch
												UpperCamelCase  							= next(self.iterator				)
												UpperCamelCase  							= self.infer(SCREAMING_SNAKE_CASE	,		**self.params				)
												# We now have a batch of "inferred things".
												if self.loader_batch_size is not None:
																		# Try to infer the size of the batch
																		if isinstance(SCREAMING_SNAKE_CASE	,		torch.Tensor				):
																								UpperCamelCase  							= processed
																		else:
																								UpperCamelCase  							= list(processed.keys()				)[0]
																								UpperCamelCase  							= processed[key]
																		if isinstance(SCREAMING_SNAKE_CASE	,		SCREAMING_SNAKE_CASE				):
																								UpperCamelCase  							= len(SCREAMING_SNAKE_CASE				)
																		else:
																								UpperCamelCase  							= first_tensor.shape[0]
																		if 0 < observed_batch_size < self.loader_batch_size:
																								# could be last batch so we can't unroll as many
																								# elements.
																								UpperCamelCase  							= observed_batch_size
																		# Setting internal index to unwrap the batch
																		UpperCamelCase  							= processed
																		UpperCamelCase  							= 0
																		return self.loader_batch_item()
												else:
																		# We're not unrolling batches
																		return processed


class 							__UpperCAmelCase							(						__snake_case   ):



						"""simple docstring"""







						def __init__(   self	,		SCREAMING_SNAKE_CASE	,		SCREAMING_SNAKE_CASE	,		SCREAMING_SNAKE_CASE	,		SCREAMING_SNAKE_CASE=None				) ->      List[str]:





												"""simple docstring"""
												super().__init__(SCREAMING_SNAKE_CASE	,		SCREAMING_SNAKE_CASE	,		SCREAMING_SNAKE_CASE				)




						def __iter__(   self				) ->      str:





												"""simple docstring"""
												UpperCamelCase  							= iter(self.loader				)
												UpperCamelCase  							= None
												return self




						def 		__lowerCAmelCase			(   self				) ->      Optional[int]:





												"""simple docstring"""
												if self.subiterator is None:
																		UpperCamelCase  							= self.infer(next(self.iterator				)	,		**self.params				)
												try:
																		# Try to return next item
																		UpperCamelCase  							= next(self.subiterator				)
												except StopIteration:
																		# When a preprocess iterator ends, we can start lookig at the next item
																		# ChunkIterator will keep feeding until ALL elements of iterator
																		# all have created their subiterator and have been iterating against.
																		#
																		# Another way to look at it, is we're basically flattening lists of lists
																		# into a single list, but with generators
																		UpperCamelCase  							= self.infer(next(self.iterator				)	,		**self.params				)
																		UpperCamelCase  							= next(self.subiterator				)
												return processed


class 							__UpperCAmelCase							(						__snake_case   ):



						"""simple docstring"""







						def __iter__(   self				) ->      List[str]:





												"""simple docstring"""
												UpperCamelCase  							= iter(self.loader				)
												return self




						def 		__lowerCAmelCase			(   self				) ->      Union[str, Any]:





												"""simple docstring"""
												# Extremely similar to PipelineIterator in its unpacking mechanism
												# BUT, we have an extra required item which is the presence of `is_last`
												# That is because everything is flattened by `PipelineChunkIterator` we
												# need to keep track of how to regroup here in the original `process`
												# boundaries so that `process` and `postprocess` see the same data.

												# This iterator accumulates items (possibly while unbatching) until it
												# its a `is_last` and then just passes it on to the caller.
												UpperCamelCase  							= False
												UpperCamelCase  							= []
												if self._loader_batch_index is not None and self._loader_batch_index < self.loader_batch_size:
																		while self._loader_batch_index < self.loader_batch_size:
																								UpperCamelCase  							= self.loader_batch_item()
																								UpperCamelCase  							= item.pop("is_last"				)
																								accumulator.append(SCREAMING_SNAKE_CASE				)
																								if is_last:
																														return accumulator

												while not is_last:
																		UpperCamelCase  							= self.infer(next(self.iterator				)	,		**self.params				)
																		if self.loader_batch_size is not None:
																								if isinstance(SCREAMING_SNAKE_CASE	,		torch.Tensor				):
																														UpperCamelCase  							= processed
																								else:
																														UpperCamelCase  							= list(processed.keys()				)[0]
																														UpperCamelCase  							= processed[key]
																								if isinstance(SCREAMING_SNAKE_CASE	,		SCREAMING_SNAKE_CASE				):
																														UpperCamelCase  							= len(SCREAMING_SNAKE_CASE				)
																								else:
																														UpperCamelCase  							= first_tensor.shape[0]
																								if 0 < observed_batch_size < self.loader_batch_size:
																														# could be last batch so we can't unroll as many
																														# elements.
																														UpperCamelCase  							= observed_batch_size
																								UpperCamelCase  							= processed
																								UpperCamelCase  							= 0
																								while self._loader_batch_index < self.loader_batch_size:
																														UpperCamelCase  							= self.loader_batch_item()
																														UpperCamelCase  							= item.pop("is_last"				)
																														accumulator.append(SCREAMING_SNAKE_CASE				)
																														if is_last:
																																				return accumulator
																		else:
																								UpperCamelCase  							= processed
																								UpperCamelCase  							= item.pop("is_last"				)
																								accumulator.append(SCREAMING_SNAKE_CASE				)
												return accumulator


class 							__UpperCAmelCase							(						__snake_case   ):



						"""simple docstring"""







						def __init__(   self	,		SCREAMING_SNAKE_CASE	,		SCREAMING_SNAKE_CASE				) ->      List[Any]:





												"""simple docstring"""
												UpperCamelCase  							= dataset
												UpperCamelCase  							= key




						def __len__(   self				) ->      Union[str, Any]:





												"""simple docstring"""
												return len(self.dataset				)




						def __getitem__(   self	,		SCREAMING_SNAKE_CASE				) ->      Any:





												"""simple docstring"""
												return self.dataset[i][self.key]


class 							__UpperCAmelCase							(						__snake_case   ):



						"""simple docstring"""







						def __init__(   self	,		SCREAMING_SNAKE_CASE	,		SCREAMING_SNAKE_CASE	,		SCREAMING_SNAKE_CASE				) ->      Dict:





												"""simple docstring"""
												UpperCamelCase  							= dataset
												UpperCamelCase  							= keya
												UpperCamelCase  							= keya




						def __len__(   self				) ->      Union[str, Any]:





												"""simple docstring"""
												return len(self.dataset				)




						def __getitem__(   self	,		SCREAMING_SNAKE_CASE				) ->      int:





												"""simple docstring"""
												return {"text": self.dataset[i][self.keya], "text_pair": self.dataset[i][self.keya]}






import math




class   __lowercase						:






	def       _a(self				: Dict      ,	snake_case				: list[list[float]]      ,	snake_case				: list[int]    ) ->			int:
							_lowercase       :	List[Any]           =   0.0
							_lowercase       :	Any           =   0.0
							for i in range(len(snake_case    )    ):
													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       _a(self				: Dict      ,	snake_case				: list[list[int | float]]      ,	snake_case				: list[int]      ,	snake_case				: int      ,	snake_case				: float    ) ->			list[list[int | float]]:
							for i in range(len(snake_case    )    ):
													weights[j][i] += alpha * (sample[i] - weights[j][i])
							return weights



def 		UpperCamelCase     (       )   ->			None:






						'''simple docstring'''

						_lowercase       :	Union[str, Any]           =   [[1, 1, 0, 0], [0, 0, 0, 1], [1, 0, 0, 0], [0, 0, 1, 1]]

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

						# training
						_lowercase       :	List[Any]           =   SelfOrganizingMap()
						_lowercase       :	Any           =   3
						_lowercase       :	Optional[Any]           =   0.5

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

																		# Compute the winning vector
																		_lowercase       :	Tuple           =   self_organizing_map.get_winner(_UpperCAmelCase ,			_UpperCAmelCase  )

																		# Update the winning vector
																		_lowercase       :	str           =   self_organizing_map.update(_UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase ,			_UpperCAmelCase  )

    # classify test sample
						_lowercase       :	Any           =   [0, 0, 0, 1]
						_lowercase       :	Dict           =   self_organizing_map.get_winner(_UpperCAmelCase ,			_UpperCAmelCase  )

						# 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()




