TheAlgorithms-Python/linear_algebra/src/polynom_for_points.py
Maxim Smolskiy 4f2a346c27
Reduce the complexity of linear_algebra/src/polynom_for_points.py (#8605)
* Reduce the complexity of linear_algebra/src/polynom_for_points.py

* updating DIRECTORY.md

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fix

* Fix review issues

---------

Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-08-13 03:05:42 -07:00

98 lines
3.7 KiB
Python

def points_to_polynomial(coordinates: list[list[int]]) -> str:
"""
coordinates is a two dimensional matrix: [[x, y], [x, y], ...]
number of points you want to use
>>> print(points_to_polynomial([]))
Traceback (most recent call last):
...
ValueError: The program cannot work out a fitting polynomial.
>>> print(points_to_polynomial([[]]))
Traceback (most recent call last):
...
ValueError: The program cannot work out a fitting polynomial.
>>> print(points_to_polynomial([[1, 0], [2, 0], [3, 0]]))
f(x)=x^2*0.0+x^1*-0.0+x^0*0.0
>>> print(points_to_polynomial([[1, 1], [2, 1], [3, 1]]))
f(x)=x^2*0.0+x^1*-0.0+x^0*1.0
>>> print(points_to_polynomial([[1, 3], [2, 3], [3, 3]]))
f(x)=x^2*0.0+x^1*-0.0+x^0*3.0
>>> print(points_to_polynomial([[1, 1], [2, 2], [3, 3]]))
f(x)=x^2*0.0+x^1*1.0+x^0*0.0
>>> print(points_to_polynomial([[1, 1], [2, 4], [3, 9]]))
f(x)=x^2*1.0+x^1*-0.0+x^0*0.0
>>> print(points_to_polynomial([[1, 3], [2, 6], [3, 11]]))
f(x)=x^2*1.0+x^1*-0.0+x^0*2.0
>>> print(points_to_polynomial([[1, -3], [2, -6], [3, -11]]))
f(x)=x^2*-1.0+x^1*-0.0+x^0*-2.0
>>> print(points_to_polynomial([[1, 5], [2, 2], [3, 9]]))
f(x)=x^2*5.0+x^1*-18.0+x^0*18.0
"""
if len(coordinates) == 0 or not all(len(pair) == 2 for pair in coordinates):
raise ValueError("The program cannot work out a fitting polynomial.")
if len({tuple(pair) for pair in coordinates}) != len(coordinates):
raise ValueError("The program cannot work out a fitting polynomial.")
set_x = {x for x, _ in coordinates}
if len(set_x) == 1:
return f"x={coordinates[0][0]}"
if len(set_x) != len(coordinates):
raise ValueError("The program cannot work out a fitting polynomial.")
x = len(coordinates)
# put the x and x to the power values in a matrix
matrix: list[list[float]] = [
[
coordinates[count_of_line][0] ** (x - (count_in_line + 1))
for count_in_line in range(x)
]
for count_of_line in range(x)
]
# put the y values into a vector
vector: list[float] = [coordinates[count_of_line][1] for count_of_line in range(x)]
for count in range(x):
for number in range(x):
if count == number:
continue
fraction = matrix[number][count] / matrix[count][count]
for counting_columns, item in enumerate(matrix[count]):
# manipulating all the values in the matrix
matrix[number][counting_columns] -= item * fraction
# manipulating the values in the vector
vector[number] -= vector[count] * fraction
# make solutions
solution: list[str] = [
str(vector[count] / matrix[count][count]) for count in range(x)
]
solved = "f(x)="
for count in range(x):
remove_e: list[str] = solution[count].split("E")
if len(remove_e) > 1:
solution[count] = f"{remove_e[0]}*10^{remove_e[1]}"
solved += f"x^{x - (count + 1)}*{solution[count]}"
if count + 1 != x:
solved += "+"
return solved
if __name__ == "__main__":
print(points_to_polynomial([]))
print(points_to_polynomial([[]]))
print(points_to_polynomial([[1, 0], [2, 0], [3, 0]]))
print(points_to_polynomial([[1, 1], [2, 1], [3, 1]]))
print(points_to_polynomial([[1, 3], [2, 3], [3, 3]]))
print(points_to_polynomial([[1, 1], [2, 2], [3, 3]]))
print(points_to_polynomial([[1, 1], [2, 4], [3, 9]]))
print(points_to_polynomial([[1, 3], [2, 6], [3, 11]]))
print(points_to_polynomial([[1, -3], [2, -6], [3, -11]]))
print(points_to_polynomial([[1, 5], [2, 2], [3, 9]]))