




import unittest

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




class       _A				(		unittest.TestCase     ):






  def 				UpperCAmelCase (    self			):
        _UpperCAmelCase      =			Vector([1, 2, 3]			)
        self.assertEqual(x.component(0			)						,		1			)
        self.assertEqual(x.component(2			)						,		3			)
        _UpperCAmelCase      =			Vector()






  def 				UpperCAmelCase (    self			):
        _UpperCAmelCase      =			Vector([0, 0, 0, 0, 0, 1]			)
        self.assertEqual(str(_SCREAMING_SNAKE_CASE			)						,		"""(0,0,0,0,0,1)"""			)






  def 				UpperCAmelCase (    self			):
        _UpperCAmelCase      =			Vector([1, 2, 3, 4]			)
        self.assertEqual(len(_SCREAMING_SNAKE_CASE			)						,		4			)






  def 				UpperCAmelCase (    self			):
        _UpperCAmelCase      =			Vector([1, 2]			)
        _UpperCAmelCase      =			Vector([1, 2, 3, 4, 5]			)
        _UpperCAmelCase      =			Vector([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]			)
        _UpperCAmelCase      =			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 				UpperCAmelCase (    self			):
        _UpperCAmelCase      =			Vector([1, 2, 3]			)
        _UpperCAmelCase      =			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 				UpperCAmelCase (    self			):
        _UpperCAmelCase      =			Vector([1, 2, 3]			)
        _UpperCAmelCase      =			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 				UpperCAmelCase (    self			):
        _UpperCAmelCase      =			Vector([1, 2, 3]			)
        _UpperCAmelCase      =			Vector([2, -1, 4]			)  # for test of dot product
        _UpperCAmelCase      =			Vector([1, -2, -1]			)
        self.assertEqual(str(x * 3.0			)						,		"""(3.0,6.0,9.0)"""			)
        self.assertEqual((a * b)						,		0			)






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






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






  def 				UpperCAmelCase (    self			):
        _UpperCAmelCase      =			Vector([1, 2, 3]			)
        _UpperCAmelCase      =			Vector([1, 0, 1]			)
        self.assertEqual(str(axpy(2						,		_SCREAMING_SNAKE_CASE						,		_SCREAMING_SNAKE_CASE			)			)						,		"""(3,4,7)"""			)






  def 				UpperCAmelCase (    self			):
        _UpperCAmelCase      =			Vector([1, 0, 0, 0, 0, 0]			)
        _UpperCAmelCase      =			x.copy()
        self.assertEqual(str(_SCREAMING_SNAKE_CASE			)						,		str(_SCREAMING_SNAKE_CASE			)			)






  def 				UpperCAmelCase (    self			):
        _UpperCAmelCase      =			Vector([1, 0, 0]			)
        x.change_component(0						,		0			)
        x.change_component(1						,		1			)
        self.assertEqual(str(_SCREAMING_SNAKE_CASE			)						,		"""(0,1,0)"""			)






  def 				UpperCAmelCase (    self			):
        _UpperCAmelCase      =			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(_SCREAMING_SNAKE_CASE			)			)






  def 				UpperCAmelCase (    self			):
        _UpperCAmelCase      =			Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]]						,		3						,		3			)
        _UpperCAmelCase      =			[[-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(_SCREAMING_SNAKE_CASE						,		_SCREAMING_SNAKE_CASE			)			)






  def 				UpperCAmelCase (    self			):
        _UpperCAmelCase      =			Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]]						,		3						,		3			)
        _UpperCAmelCase      =			[[-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(_SCREAMING_SNAKE_CASE						,		_SCREAMING_SNAKE_CASE			)			)






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






  def 				UpperCAmelCase (    self			):
        _UpperCAmelCase      =			Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]						,		3						,		3			)
        _UpperCAmelCase      =			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 				UpperCAmelCase (    self			):
        _UpperCAmelCase      =			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(_SCREAMING_SNAKE_CASE			)			)






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






  def 				UpperCAmelCase (    self			):
        _UpperCAmelCase      =			Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]]						,		3						,		3			)
        _UpperCAmelCase      =			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 				UpperCAmelCase (    self			):
        _UpperCAmelCase      =			Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]]						,		3						,		3			)
        _UpperCAmelCase      =			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 				UpperCAmelCase (    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()





from __future__ import annotations

from scipy.special import comb  # type: ignore




class       _A				:






		def __init__(    self						,		_SCREAMING_SNAKE_CASE			):
								_UpperCAmelCase      =			list_of_points
								# Degree determines the flexibility of the curve.
								# Degree = 1 will produce a straight line.
								_UpperCAmelCase      =			len(_SCREAMING_SNAKE_CASE			) - 1






		def 				UpperCAmelCase (    self						,		_SCREAMING_SNAKE_CASE			):
								assert 0 <= t <= 1, "Time t must be between 0 and 1."
								_UpperCAmelCase      =			[]
								for i in range(len(self.list_of_points			)			):
														# basis function for each i
														output_values.append(
														    comb(self.degree						,		_SCREAMING_SNAKE_CASE			) * ((1 - t) ** (self.degree - i)) * (t**i)			)
								# the basis must sum up to 1 for it to produce a valid Bezier curve.
								assert round(sum(_SCREAMING_SNAKE_CASE			)						,		5			) == 1
								return output_values






		def 				UpperCAmelCase (    self						,		_SCREAMING_SNAKE_CASE			):
								assert 0 <= t <= 1, "Time t must be between 0 and 1."

								_UpperCAmelCase      =			self.basis_function(_SCREAMING_SNAKE_CASE			)
								_UpperCAmelCase      =			0.0
								_UpperCAmelCase      =			0.0
								for i in range(len(self.list_of_points			)			):
														# For all points, sum up the product of i-th basis function and i-th point.
														x += basis_function[i] * self.list_of_points[i][0]
														y += basis_function[i] * self.list_of_points[i][1]
								return (x, y)






		def 				UpperCAmelCase (    self						,		_SCREAMING_SNAKE_CASE = 0.01			):
								from matplotlib import pyplot as plt  # type: ignore

								_UpperCAmelCase      =			[]  # x coordinates of points to plot
								_UpperCAmelCase      =			[]  # y coordinates of points to plot

								_UpperCAmelCase      =			0.0
								while t <= 1:
														_UpperCAmelCase      =			self.bezier_curve_function(_SCREAMING_SNAKE_CASE			)
														to_plot_x.append(value[0]			)
														to_plot_y.append(value[1]			)
														t += step_size

								_UpperCAmelCase      =			[i[0] for i in self.list_of_points]
								_UpperCAmelCase      =			[i[1] for i in self.list_of_points]

								plt.plot(
								    _SCREAMING_SNAKE_CASE						,		_SCREAMING_SNAKE_CASE						,		color="""blue"""						,		label="""Curve of Degree """ + str(self.degree			)						,		)
								plt.scatter(_SCREAMING_SNAKE_CASE						,		_SCREAMING_SNAKE_CASE						,		color="""red"""						,		label="""Control Points"""			)
								plt.legend()
								plt.show()


if __name__ == "__main__":
				import doctest

				doctest.testmod()

				BezierCurve([(1, 2), (3, 5)]).plot_curve()  # degree 1
				BezierCurve([(0, 0), (5, 5), (5, 0)]).plot_curve()  # degree 2
				BezierCurve([(0, 0), (5, 5), (5, 0), (2.5, -2.5)]).plot_curve()  # degree 3