


'''simple docstring'''



import unittest

from .lib import (
    Matrix,
    Vector,
    axpy,
    square_zero_matrix,
    unit_basis_vector,
    zero_vector,
)


class 						_snake_case   (       unittest.TestCase		):




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   str       				=       Vector([1, 2, 3])
								self.assertEqual(x.component(0)							,							1)
								self.assertEqual(x.component(2)							,							3)
								UpperCAmelCase__					:   List[str]       				=       Vector()




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   Any       				=       Vector([0, 0, 0, 0, 0, 1])
								self.assertEqual(str(_lowerCamelCase)							,							"""(0,0,0,0,0,1)""")




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   Optional[int]       				=       Vector([1, 2, 3, 4])
								self.assertEqual(len(_lowerCamelCase)							,							4)




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   List[str]       				=       Vector([1, 2])
								UpperCAmelCase__					:   Optional[int]       				=       Vector([1, 2, 3, 4, 5])
								UpperCAmelCase__					:   Optional[Any]       				=       Vector([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
								UpperCAmelCase__					:   Union[str, Any]       				=       Vector([1, -1, 1, -1, 2, -3, 4, -5])
								self.assertAlmostEqual(x.euclidean_length()							,							2.236							,							3)
								self.assertAlmostEqual(y.euclidean_length()							,							7.416							,							3)
								self.assertEqual(z.euclidean_length()							,							0)
								self.assertAlmostEqual(w.euclidean_length()							,							7.616							,							3)




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   int       				=       Vector([1, 2, 3])
								UpperCAmelCase__					:   Optional[Any]       				=       Vector([1, 1, 1])
								self.assertEqual((x + y).component(0)							,							2)
								self.assertEqual((x + y).component(1)							,							3)
								self.assertEqual((x + y).component(2)							,							4)




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   Optional[int]       				=       Vector([1, 2, 3])
								UpperCAmelCase__					:   Dict       				=       Vector([1, 1, 1])
								self.assertEqual((x - y).component(0)							,							0)
								self.assertEqual((x - y).component(1)							,							1)
								self.assertEqual((x - y).component(2)							,							2)




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   Tuple       				=       Vector([1, 2, 3])
								UpperCAmelCase__					:   Optional[int]       				=       Vector([2, -1, 4])  # for test of dot product
								UpperCAmelCase__					:   Any       				=       Vector([1, -2, -1])
								self.assertEqual(str(x * 3.0)							,							"""(3.0,6.0,9.0)""")
								self.assertEqual((a * b)							,							0)




					def 			snake_case__  ( self):
								self.assertEqual(str(zero_vector(10)).count("""0""")							,							10)




					def 			snake_case__  ( self):
								self.assertEqual(str(unit_basis_vector(3							,							1))							,							"""(0,1,0)""")




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   Any       				=       Vector([1, 2, 3])
								UpperCAmelCase__					:   List[str]       				=       Vector([1, 0, 1])
								self.assertEqual(str(axpy(2							,							_lowerCamelCase							,							_lowerCamelCase))							,							"""(3,4,7)""")




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   Optional[int]       				=       Vector([1, 0, 0, 0, 0, 0])
								UpperCAmelCase__					:   Optional[int]       				=       x.copy()
								self.assertEqual(str(_lowerCamelCase)							,							str(_lowerCamelCase))




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   str       				=       Vector([1, 0, 0])
								x.change_component(0							,							0)
								x.change_component(1							,							1)
								self.assertEqual(str(_lowerCamelCase)							,							"""(0,1,0)""")




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   str       				=       Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]]							,							3							,							3)
								self.assertEqual("""|1,2,3|\n|2,4,5|\n|6,7,8|\n"""							,							str(_lowerCamelCase))




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   List[str]       				=       Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]]							,							3							,							3)
								UpperCAmelCase__					:   Dict       				=       [[-3, -14, -10], [-5, -10, -5], [-2, -1, 0]]
								for x in range(a.height()):
											for y in range(a.width()):
														self.assertEqual(minors[x][y]							,							a.minor(_lowerCamelCase							,							_lowerCamelCase))




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   Any       				=       Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]]							,							3							,							3)
								UpperCAmelCase__					:   Tuple       				=       [[-3, 14, -10], [5, -10, 5], [-2, 1, 0]]
								for x in range(a.height()):
											for y in range(a.width()):
														self.assertEqual(cofactors[x][y]							,							a.cofactor(_lowerCamelCase							,							_lowerCamelCase))




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   Any       				=       Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]]							,							3							,							3)
								self.assertEqual(-5							,							a.determinant())




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   str       				=       Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]							,							3							,							3)
								UpperCAmelCase__					:   List[Any]       				=       Vector([1, 2, 3])
								self.assertEqual("""(14,32,50)"""							,							str(a * x))
								self.assertEqual("""|2,4,6|\n|8,10,12|\n|14,16,18|\n"""							,							str(a * 2))




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   Union[str, Any]       				=       Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]]							,							3							,							3)
								a.change_component(0							,							2							,							5)
								self.assertEqual("""|1,2,5|\n|2,4,5|\n|6,7,8|\n"""							,							str(_lowerCamelCase))




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   Any       				=       Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]]							,							3							,							3)
								self.assertEqual(7							,							a.component(2							,							1)							,							0.01)




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   str       				=       Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]]							,							3							,							3)
								UpperCAmelCase__					:   List[Any]       				=       Matrix([[1, 2, 7], [2, 4, 5], [6, 7, 10]]							,							3							,							3)
								self.assertEqual("""|2,4,10|\n|4,8,10|\n|12,14,18|\n"""							,							str(a + b))




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   List[Any]       				=       Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]]							,							3							,							3)
								UpperCAmelCase__					:   Dict       				=       Matrix([[1, 2, 7], [2, 4, 5], [6, 7, 10]]							,							3							,							3)
								self.assertEqual("""|0,0,-4|\n|0,0,0|\n|0,0,-2|\n"""							,							str(a - b))




					def 			snake_case__  ( self):
								self.assertEqual(
								    """|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|\n"""							,							str(square_zero_matrix(5))							,							)


if __name__ == "__main__":
		unittest.main()



'''simple docstring'''



import numpy


class 						_snake_case   :




					def __init__( self							,							_lowerCamelCase							,							_lowerCamelCase):
								UpperCAmelCase__					:   Dict       				=       input_array

								# Random initial weights are assigned where first argument is the
								# number of nodes in previous layer and second argument is the
								# number of nodes in the next layer.

								# Random initial weights are assigned.
								# self.input_array.shape[1] is used to represent number of nodes in input layer.
								# First hidden layer consists of 4 nodes.
								UpperCAmelCase__					:   Optional[Any]       				=       numpy.random.rand(
								    self.input_array.shape[1]							,							4)

								# Random initial values for the first hidden layer.
								# First hidden layer has 4 nodes.
								# Second hidden layer has 3 nodes.
								UpperCAmelCase__					:   Optional[int]       				=       numpy.random.rand(
								    4							,							3)

								# Random initial values for the second hidden layer.
								# Second hidden layer has 3 nodes.
								# Output layer has 1 node.
								UpperCAmelCase__					:   Any       				=       numpy.random.rand(3							,							1)

								# Real output values provided.
								UpperCAmelCase__					:   Tuple       				=       output_array

								# Predicted output values by the neural network.
								# Predicted_output array initially consists of zeroes.
								UpperCAmelCase__					:   Union[str, Any]       				=       numpy.zeros(output_array.shape)




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   List[str]       				=       sigmoid(
								    numpy.dot(self.input_array							,							self.input_layer_and_first_hidden_layer_weights))

								# layer_between_first_hidden_layer_and_second_hidden_layer is the layer
								# connecting the first hidden set of nodes with the second hidden set of nodes.
								UpperCAmelCase__					:   Any       				=       sigmoid(
								    numpy.dot(
								        self.layer_between_input_and_first_hidden_layer							,							self.first_hidden_layer_and_second_hidden_layer_weights							,							))

								# layer_between_second_hidden_layer_and_output is the layer connecting
								# second hidden layer with the output node.
								UpperCAmelCase__					:   Tuple       				=       sigmoid(
								    numpy.dot(
								        self.layer_between_first_hidden_layer_and_second_hidden_layer							,							self.second_hidden_layer_and_output_layer_weights							,							))

								return self.layer_between_second_hidden_layer_and_output




					def 			snake_case__  ( self):
								UpperCAmelCase__					:   Optional[int]       				=       numpy.dot(
								    self.layer_between_first_hidden_layer_and_second_hidden_layer.T							,							2
								    * (self.output_array - self.predicted_output)
								    * sigmoid_derivative(self.predicted_output)							,							)
								UpperCAmelCase__					:   str       				=       numpy.dot(
								    self.layer_between_input_and_first_hidden_layer.T							,							numpy.dot(
								        2
								        * (self.output_array - self.predicted_output)
								        * sigmoid_derivative(self.predicted_output)							,							self.second_hidden_layer_and_output_layer_weights.T							,							)
								    * sigmoid_derivative(
								        self.layer_between_first_hidden_layer_and_second_hidden_layer)							,							)
								UpperCAmelCase__					:   Any       				=       numpy.dot(
								    self.input_array.T							,							numpy.dot(
								        numpy.dot(
								            2
								            * (self.output_array - self.predicted_output)
								            * sigmoid_derivative(self.predicted_output)							,							self.second_hidden_layer_and_output_layer_weights.T							,							)
								        * sigmoid_derivative(
								            self.layer_between_first_hidden_layer_and_second_hidden_layer)							,							self.first_hidden_layer_and_second_hidden_layer_weights.T							,							)
								    * sigmoid_derivative(self.layer_between_input_and_first_hidden_layer)							,							)

								self.input_layer_and_first_hidden_layer_weights += (
								    updated_input_layer_and_first_hidden_layer_weights
								)
								self.first_hidden_layer_and_second_hidden_layer_weights += (
								    updated_first_hidden_layer_and_second_hidden_layer_weights
								)
								self.second_hidden_layer_and_output_layer_weights += (
								    updated_second_hidden_layer_and_output_layer_weights
								)




					def 			snake_case__  ( self							,							_lowerCamelCase							,							_lowerCamelCase							,							_lowerCamelCase):
								for iteration in range(1							,							iterations + 1):
											UpperCAmelCase__					:   Optional[Any]       				=       self.feedforward()
											self.back_propagation()
											if give_loss:
														UpperCAmelCase__					:   str       				=       numpy.mean(numpy.square(output - self.feedforward()))
														print(f'''Iteration {iteration} Loss: {loss}''')




					def 			snake_case__  ( self							,							_lowerCamelCase):
								UpperCAmelCase__					:   List[Any]       				=       input_arr

								UpperCAmelCase__					:   Tuple       				=       sigmoid(
								    numpy.dot(self.array							,							self.input_layer_and_first_hidden_layer_weights))

								UpperCAmelCase__					:   List[Any]       				=       sigmoid(
								    numpy.dot(
								        self.layer_between_input_and_first_hidden_layer							,							self.first_hidden_layer_and_second_hidden_layer_weights							,							))

								UpperCAmelCase__					:   Optional[Any]       				=       sigmoid(
								    numpy.dot(
								        self.layer_between_first_hidden_layer_and_second_hidden_layer							,							self.second_hidden_layer_and_output_layer_weights							,							))

								return int(self.layer_between_second_hidden_layer_and_output > 0.6)







def       _UpperCamelCase (						UpperCamelCase__   ):
			return 1 / (1 + numpy.exp(-value   ))







def       _UpperCamelCase (						UpperCamelCase__   ):
			return (value) * (1 - (value))







def       _UpperCamelCase (						):
			UpperCAmelCase__					:   Union[str, Any]       				=       numpy.array(
			    (
			        [0, 0, 0],
			        [0, 0, 1],
			        [0, 1, 0],
			        [0, 1, 1],
			        [1, 0, 0],
			        [1, 0, 1],
			        [1, 1, 0],
			        [1, 1, 1],
			    )	, dtype=numpy.floataa	, )

			# True output values for the given input values.
			UpperCAmelCase__					:   str       				=       numpy.array(([0], [1], [1], [0], [1], [0], [0], [1])	, dtype=numpy.floataa   )

			# Calling neural network class.
			UpperCAmelCase__					:   List[Any]       				=       TwoHiddenLayerNeuralNetwork(
			    input_array=UpperCamelCase__	, output_array=UpperCamelCase__   )

			# Calling training function.
			# Set give_loss to True if you want to see loss in every iteration.
			neural_network.train(output=UpperCamelCase__	, iterations=1_0	, give_loss=UpperCamelCase__   )

			return neural_network.predict(numpy.array(([1, 1, 1])	, dtype=numpy.floataa   )   )


if __name__ == "__main__":
		example()