






"""simple docstring"""






import tensorflow as tf

from ...tf_utils import shape_list





class       snake_case_       (    tf.keras.layers.Layer       ):



	"""simple docstring"""

	def __init__(      self  ,					__a  ,					__a  ,					__a  ,					__a  ,					__a=1  ,					__a=False  ,					**__a						):


					"""simple docstring"""

					super().__init__(**__a						)

					A__							 =       vocab_size
					A__							 =       d_embed
					A__							 =       d_proj

					A__							 =       cutoffs + [vocab_size]
					A__							 =       [0] + self.cutoffs
					A__							 =       div_val

					A__							 =       self.cutoffs[0]
					A__							 =       len(self.cutoffs						) - 1
					A__							 =       self.shortlist_size + self.n_clusters
					A__							 =       keep_order

					A__							 =       []
					A__							 =       []


	def       _UpperCAmelCase						(      self  ,					__a						):


					"""simple docstring"""

					if self.n_clusters > 0:
									A__							 =       self.add_weight(
									    shape=(self.n_clusters, self.d_embed)  ,					initializer='zeros'  ,					trainable=__a  ,					name='cluster_weight'						)
									A__							 =       self.add_weight(
									    shape=(self.n_clusters,)  ,					initializer='zeros'  ,					trainable=__a  ,					name='cluster_bias'						)

					if self.div_val == 1:
									for i in range(len(self.cutoffs						)						):
													if self.d_proj != self.d_embed:
																	A__							 =       self.add_weight(
																	    shape=(self.d_embed, self.d_proj)  ,					initializer='zeros'  ,					trainable=__a  ,					name=f'''out_projs_._{i}'''  ,					)
																	self.out_projs.append(__a						)
													else:
																	self.out_projs.append(__a						)
													A__							 =       self.add_weight(
													    shape=(self.vocab_size, self.d_embed)  ,					initializer='zeros'  ,					trainable=__a  ,					name=f'''out_layers_._{i}_._weight'''  ,					)
													A__							 =       self.add_weight(
													    shape=(self.vocab_size,)  ,					initializer='zeros'  ,					trainable=__a  ,					name=f'''out_layers_._{i}_._bias'''  ,					)
													self.out_layers.append((weight, bias)						)
					else:
									for i in range(len(self.cutoffs						)						):
													A__ ,			A__							 =       self.cutoff_ends[i], self.cutoff_ends[i + 1]
													A__							 =       self.d_embed // (self.div_val**i)

													A__							 =       self.add_weight(
													    shape=(d_emb_i, self.d_proj)  ,					initializer='zeros'  ,					trainable=__a  ,					name=f'''out_projs_._{i}'''						)
													self.out_projs.append(__a						)
													A__							 =       self.add_weight(
													    shape=(r_idx - l_idx, d_emb_i)  ,					initializer='zeros'  ,					trainable=__a  ,					name=f'''out_layers_._{i}_._weight'''  ,					)
													A__							 =       self.add_weight(
													    shape=(r_idx - l_idx,)  ,					initializer='zeros'  ,					trainable=__a  ,					name=f'''out_layers_._{i}_._bias'''  ,					)
													self.out_layers.append((weight, bias)						)
					super().build(__a						)


	@staticmethod
	def       _UpperCAmelCase						(      __a  ,					__a  ,					__a  ,					__a=None						):


					"""simple docstring"""

					A__							 =       x
					if proj is not None:
									A__							 =       tf.einsum('ibd,ed->ibe'  ,					__a  ,					__a						)
					return tf.einsum('ibd,nd->ibn'  ,					__a  ,					__a						) + b


	@staticmethod
	def       _UpperCAmelCase						(      __a  ,					__a						):


					"""simple docstring"""

					A__							 =       shape_list(__a						)
					A__							 =       tf.range(lp_size[0]  ,					dtype=target.dtype						)
					A__							 =       tf.stack([r, target]  ,					1						)
					return tf.gather_nd(__a  ,					__a						)






	def       _UpperCAmelCase						(      self  ,					__a  ,					__a  ,					__a=True  ,					__a=False						):


					"""simple docstring"""

					A__							 =       0
					if self.n_clusters == 0:
									A__							 =       self._logit(__a  ,					self.out_layers[0][0]  ,					self.out_layers[0][1]  ,					self.out_projs[0]						)
									if target is not None:
													A__							 =       tf.nn.sparse_softmax_cross_entropy_with_logits(labels=__a  ,					logits=__a						)
									A__							 =       tf.nn.log_softmax(__a  ,					axis=-1						)
					else:
									A__							 =       shape_list(__a						)
									A__							 =       []
									A__							 =       tf.zeros(hidden_sizes[:2]						)
									for i in range(len(self.cutoffs						)						):
													A__ ,			A__							 =       self.cutoff_ends[i], self.cutoff_ends[i + 1]
													if target is not None:
																	A__							 =       (target >= l_idx) & (target < r_idx)
																	A__							 =       tf.where(__a						)
																	A__							 =       tf.boolean_mask(__a  ,					__a						) - l_idx

													if self.div_val == 1:
																	A__							 =       self.out_layers[0][0][l_idx:r_idx]
																	A__							 =       self.out_layers[0][1][l_idx:r_idx]
													else:
																	A__							 =       self.out_layers[i][0]
																	A__							 =       self.out_layers[i][1]

													if i == 0:
																	A__							 =       tf.concat([cur_W, self.cluster_weight]  ,					0						)
																	A__							 =       tf.concat([cur_b, self.cluster_bias]  ,					0						)

																	A__							 =       self._logit(__a  ,					__a  ,					__a  ,					self.out_projs[0]						)
																	A__							 =       tf.nn.log_softmax(__a						)
																	out.append(head_logprob[..., : self.cutoffs[0]]						)
																	if target is not None:
																					A__							 =       tf.boolean_mask(__a  ,					__a						)
																					A__							 =       self._gather_logprob(__a  ,					__a						)
													else:
																	A__							 =       self._logit(__a  ,					__a  ,					__a  ,					self.out_projs[i]						)
																	A__							 =       tf.nn.log_softmax(__a						)
																	A__							 =       self.cutoffs[0] + i - 1  # No probability for the head cluster
																	A__							 =       head_logprob[..., cluster_prob_idx, None] + tail_logprob
																	out.append(__a						)
																	if target is not None:
																					A__							 =       tf.boolean_mask(__a  ,					__a						)
																					A__							 =       tf.boolean_mask(__a  ,					__a						)
																					A__							 =       self._gather_logprob(__a  ,					__a						)
																					cur_logprob += cur_head_logprob[:, self.cutoff_ends[1] + i - 1]
													if target is not None:
																	loss += tf.scatter_nd(__a  ,					-cur_logprob  ,					shape_list(__a						)						)
									A__							 =       tf.concat(__a  ,					axis=-1						)

					if target is not None:
									if return_mean:
													A__							 =       tf.reduce_mean(__a						)
									# Add the training-time loss value to the layer using `self.add_loss()`.
									self.add_loss(__a						)

									# Log the loss as a metric (we could log arbitrary metrics,
									# including different metrics for training and inference.
									self.add_metric(__a  ,					name=self.name  ,					aggregation='mean' if return_mean else ''						)

					return out










"""simple docstring"""






from math import factorial, pi



def  __lowerCamelCase					(					lowerCAmelCase__       ,lowerCAmelCase__ = 30				):

				if not isinstance(lowerCAmelCase__       ,(int, float)				):
								raise ValueError('maclaurin_sin() requires either an int or float for theta'				)

				if not isinstance(lowerCAmelCase__       ,lowerCAmelCase__				) or accuracy <= 0:
								raise ValueError('maclaurin_sin() requires a positive int for accuracy'				)

				A__							 =       float(lowerCAmelCase__				)
				A__							 =       theta // (2 * pi)
				theta -= 2 * div * pi
				return sum(
				    (-1) ** r * theta ** (2 * r + 1) / factorial(2 * r + 1				) for r in range(lowerCAmelCase__				)				)



def  __lowerCamelCase					(					lowerCAmelCase__       ,lowerCAmelCase__ = 30				):

				if not isinstance(lowerCAmelCase__       ,(int, float)				):
								raise ValueError('maclaurin_cos() requires either an int or float for theta'				)

				if not isinstance(lowerCAmelCase__       ,lowerCAmelCase__				) or accuracy <= 0:
								raise ValueError('maclaurin_cos() requires a positive int for accuracy'				)

				A__							 =       float(lowerCAmelCase__				)
				A__							 =       theta // (2 * pi)
				theta -= 2 * div * pi
				return sum((-1) ** r * theta ** (2 * r) / factorial(2 * r				) for r in range(lowerCAmelCase__				)				)


if __name__ == "__main__":
					import doctest

					doctest.testmod()

					print(maclaurin_sin(10))
					print(maclaurin_sin(-10))
					print(maclaurin_sin(10, 15))
					print(maclaurin_sin(-10, 15))

					print(maclaurin_cos(5))
					print(maclaurin_cos(-5))
					print(maclaurin_cos(10, 15))
					print(maclaurin_cos(-10, 15))


