Merge branch 'TheAlgorithms:master' into master

This commit is contained in:
Tianyi Zheng 2023-01-02 09:13:18 -08:00 committed by GitHub
commit 8b44f10376
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 125 additions and 101 deletions

View File

@ -1,76 +1,84 @@
#!/usr/bin/python """
Author Anurag Kumar | anuragkumarak95@gmail.com | git/anuragkumarak95
"""Author Anurag Kumar | anuragkumarak95@gmail.com | git/anuragkumarak95 Simple example of fractal generation using recursion.
Simple example of Fractal generation using recursive function. What is the Sierpiński Triangle?
The Sierpiński triangle (sometimes spelled Sierpinski), also called the
Sierpiński gasket or Sierpiński sieve, is a fractal attractive fixed set with
the overall shape of an equilateral triangle, subdivided recursively into
smaller equilateral triangles. Originally constructed as a curve, this is one of
the basic examples of self-similar setsthat is, it is a mathematically
generated pattern that is reproducible at any magnification or reduction. It is
named after the Polish mathematician Wacław Sierpiński, but appeared as a
decorative pattern many centuries before the work of Sierpiński.
What is Sierpinski Triangle?
>>The Sierpinski triangle (also with the original orthography Sierpinski), also called
the Sierpinski gasket or the Sierpinski Sieve, is a fractal and attractive fixed set
with the overall shape of an equilateral triangle, subdivided recursively into smaller
equilateral triangles. Originally constructed as a curve, this is one of the basic
examples of self-similar sets, i.e., it is a mathematically generated pattern that can
be reproducible at any magnification or reduction. It is named after the Polish
mathematician Wacław Sierpinski, but appeared as a decorative pattern many centuries
prior to the work of Sierpinski.
Requirements(pip): Usage: python sierpinski_triangle.py <int:depth_for_fractal>
- turtle
Python:
- 2.6
Usage:
- $python sierpinski_triangle.py <int:depth_for_fractal>
Credits: This code was written by editing the code from
https://www.riannetrujillo.com/blog/python-fractal/
Credits:
The above description is taken from
https://en.wikipedia.org/wiki/Sierpi%C5%84ski_triangle
This code was written by editing the code from
https://www.riannetrujillo.com/blog/python-fractal/
""" """
import sys import sys
import turtle import turtle
PROGNAME = "Sierpinski Triangle"
points = [[-175, -125], [0, 175], [175, -125]] # size of triangle def get_mid(p1: tuple[float, float], p2: tuple[float, float]) -> tuple[float, float]:
"""
Find the midpoint of two points
>>> get_mid((0, 0), (2, 2))
(1.0, 1.0)
>>> get_mid((-3, -3), (3, 3))
(0.0, 0.0)
>>> get_mid((1, 0), (3, 2))
(2.0, 1.0)
>>> get_mid((0, 0), (1, 1))
(0.5, 0.5)
>>> get_mid((0, 0), (0, 0))
(0.0, 0.0)
"""
return (p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2
def get_mid(p1, p2): def triangle(
return ((p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2) # find midpoint vertex1: tuple[float, float],
vertex2: tuple[float, float],
vertex3: tuple[float, float],
def triangle(points, depth): depth: int,
) -> None:
"""
Recursively draw the Sierpinski triangle given the vertices of the triangle
and the recursion depth
"""
my_pen.up() my_pen.up()
my_pen.goto(points[0][0], points[0][1]) my_pen.goto(vertex1[0], vertex1[1])
my_pen.down() my_pen.down()
my_pen.goto(points[1][0], points[1][1]) my_pen.goto(vertex2[0], vertex2[1])
my_pen.goto(points[2][0], points[2][1]) my_pen.goto(vertex3[0], vertex3[1])
my_pen.goto(points[0][0], points[0][1]) my_pen.goto(vertex1[0], vertex1[1])
if depth > 0: if depth == 0:
triangle( return
[points[0], get_mid(points[0], points[1]), get_mid(points[0], points[2])],
depth - 1, triangle(vertex1, get_mid(vertex1, vertex2), get_mid(vertex1, vertex3), depth - 1)
) triangle(vertex2, get_mid(vertex1, vertex2), get_mid(vertex2, vertex3), depth - 1)
triangle( triangle(vertex3, get_mid(vertex3, vertex2), get_mid(vertex1, vertex3), depth - 1)
[points[1], get_mid(points[0], points[1]), get_mid(points[1], points[2])],
depth - 1,
)
triangle(
[points[2], get_mid(points[2], points[1]), get_mid(points[0], points[2])],
depth - 1,
)
if __name__ == "__main__": if __name__ == "__main__":
if len(sys.argv) != 2: if len(sys.argv) != 2:
raise ValueError( raise ValueError(
"right format for using this script: " "Correct format for using this script: "
"$python fractals.py <int:depth_for_fractal>" "python fractals.py <int:depth_for_fractal>"
) )
my_pen = turtle.Turtle() my_pen = turtle.Turtle()
my_pen.ht() my_pen.ht()
my_pen.speed(5) my_pen.speed(5)
my_pen.pencolor("red") my_pen.pencolor("red")
triangle(points, int(sys.argv[1]))
vertices = [(-175, -125), (0, 175), (175, -125)] # vertices of triangle
triangle(vertices[0], vertices[1], vertices[2], int(sys.argv[1]))

View File

@ -1,76 +1,86 @@
# Required imports to run this file
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
# weighted matrix def weighted_matrix(
def weighted_matrix(point: np.mat, training_data_x: np.mat, bandwidth: float) -> np.mat: point: np.array, training_data_x: np.array, bandwidth: float
) -> np.array:
""" """
Calculate the weight for every point in the Calculate the weight for every point in the data set.
data set. It takes training_point , query_point, and tau point --> the x value at which we want to make predictions
Here Tau is not a fixed value it can be varied depends on output. >>> weighted_matrix(
tau --> bandwidth ... np.array([1., 1.]),
xmat -->Training data ... np.array([[16.99, 10.34], [21.01,23.68], [24.59,25.69]]),
point --> the x where we want to make predictions ... 0.6
>>> weighted_matrix(np.array([1., 1.]),np.mat([[16.99, 10.34], [21.01,23.68], ... )
... [24.59,25.69]]), 0.6) array([[1.43807972e-207, 0.00000000e+000, 0.00000000e+000],
matrix([[1.43807972e-207, 0.00000000e+000, 0.00000000e+000],
[0.00000000e+000, 0.00000000e+000, 0.00000000e+000], [0.00000000e+000, 0.00000000e+000, 0.00000000e+000],
[0.00000000e+000, 0.00000000e+000, 0.00000000e+000]]) [0.00000000e+000, 0.00000000e+000, 0.00000000e+000]])
""" """
# m is the number of training samples m, _ = np.shape(training_data_x) # m is the number of training samples
m, n = np.shape(training_data_x) weights = np.eye(m) # Initializing weights as identity matrix
# Initializing weights as identity matrix
weights = np.mat(np.eye(m))
# calculating weights for all training examples [x(i)'s] # calculating weights for all training examples [x(i)'s]
for j in range(m): for j in range(m):
diff = point - training_data_x[j] diff = point - training_data_x[j]
weights[j, j] = np.exp(diff * diff.T / (-2.0 * bandwidth**2)) weights[j, j] = np.exp(diff @ diff.T / (-2.0 * bandwidth**2))
return weights return weights
def local_weight( def local_weight(
point: np.mat, training_data_x: np.mat, training_data_y: np.mat, bandwidth: float point: np.array,
) -> np.mat: training_data_x: np.array,
training_data_y: np.array,
bandwidth: float,
) -> np.array:
""" """
Calculate the local weights using the weight_matrix function on training data. Calculate the local weights using the weight_matrix function on training data.
Return the weighted matrix. Return the weighted matrix.
>>> local_weight(np.array([1., 1.]),np.mat([[16.99, 10.34], [21.01,23.68], >>> local_weight(
... [24.59,25.69]]),np.mat([[1.01, 1.66, 3.5]]), 0.6) ... np.array([1., 1.]),
matrix([[0.00873174], ... np.array([[16.99, 10.34], [21.01,23.68], [24.59,25.69]]),
... np.array([[1.01, 1.66, 3.5]]),
... 0.6
... )
array([[0.00873174],
[0.08272556]]) [0.08272556]])
""" """
weight = weighted_matrix(point, training_data_x, bandwidth) weight = weighted_matrix(point, training_data_x, bandwidth)
w = (training_data_x.T * (weight * training_data_x)).I * ( w = np.linalg.inv(training_data_x.T @ (weight @ training_data_x)) @ (
training_data_x.T * weight * training_data_y.T training_data_x.T @ weight @ training_data_y.T
) )
return w return w
def local_weight_regression( def local_weight_regression(
training_data_x: np.mat, training_data_y: np.mat, bandwidth: float training_data_x: np.array, training_data_y: np.array, bandwidth: float
) -> np.mat: ) -> np.array:
""" """
Calculate predictions for each data point on axis. Calculate predictions for each data point on axis
>>> local_weight_regression(np.mat([[16.99, 10.34], [21.01,23.68], >>> local_weight_regression(
... [24.59,25.69]]),np.mat([[1.01, 1.66, 3.5]]), 0.6) ... np.array([[16.99, 10.34], [21.01, 23.68], [24.59, 25.69]]),
... np.array([[1.01, 1.66, 3.5]]),
... 0.6
... )
array([1.07173261, 1.65970737, 3.50160179]) array([1.07173261, 1.65970737, 3.50160179])
""" """
m, n = np.shape(training_data_x) m, _ = np.shape(training_data_x)
ypred = np.zeros(m) ypred = np.zeros(m)
for i, item in enumerate(training_data_x): for i, item in enumerate(training_data_x):
ypred[i] = item * local_weight( ypred[i] = item @ local_weight(
item, training_data_x, training_data_y, bandwidth item, training_data_x, training_data_y, bandwidth
) )
return ypred return ypred
def load_data(dataset_name: str, cola_name: str, colb_name: str) -> np.mat: def load_data(
dataset_name: str, cola_name: str, colb_name: str
) -> tuple[np.array, np.array, np.array, np.array]:
""" """
Function used for loading data from the seaborn splitting into x and y points Load data from seaborn and split it into x and y points
""" """
import seaborn as sns import seaborn as sns
@ -78,23 +88,25 @@ def load_data(dataset_name: str, cola_name: str, colb_name: str) -> np.mat:
col_a = np.array(data[cola_name]) # total_bill col_a = np.array(data[cola_name]) # total_bill
col_b = np.array(data[colb_name]) # tip col_b = np.array(data[colb_name]) # tip
mcol_a = np.mat(col_a) mcol_a = col_a.copy()
mcol_b = np.mat(col_b) mcol_b = col_b.copy()
m = np.shape(mcol_b)[1] one = np.ones(np.shape(mcol_b)[0], dtype=int)
one = np.ones((1, m), dtype=int)
# horizontal stacking # pairing elements of one and mcol_a
training_data_x = np.hstack((one.T, mcol_a.T)) training_data_x = np.column_stack((one, mcol_a))
return training_data_x, mcol_b, col_a, col_b return training_data_x, mcol_b, col_a, col_b
def get_preds(training_data_x: np.mat, mcol_b: np.mat, tau: float) -> np.ndarray: def get_preds(training_data_x: np.array, mcol_b: np.array, tau: float) -> np.array:
""" """
Get predictions with minimum error for each training data Get predictions with minimum error for each training data
>>> get_preds(np.mat([[16.99, 10.34], [21.01,23.68], >>> get_preds(
... [24.59,25.69]]),np.mat([[1.01, 1.66, 3.5]]), 0.6) ... np.array([[16.99, 10.34], [21.01, 23.68], [24.59, 25.69]]),
... np.array([[1.01, 1.66, 3.5]]),
... 0.6
... )
array([1.07173261, 1.65970737, 3.50160179]) array([1.07173261, 1.65970737, 3.50160179])
""" """
ypred = local_weight_regression(training_data_x, mcol_b, tau) ypred = local_weight_regression(training_data_x, mcol_b, tau)
@ -102,15 +114,15 @@ def get_preds(training_data_x: np.mat, mcol_b: np.mat, tau: float) -> np.ndarray
def plot_preds( def plot_preds(
training_data_x: np.mat, training_data_x: np.array,
predictions: np.ndarray, predictions: np.array,
col_x: np.ndarray, col_x: np.array,
col_y: np.ndarray, col_y: np.array,
cola_name: str, cola_name: str,
colb_name: str, colb_name: str,
) -> plt.plot: ) -> plt.plot:
""" """
This function used to plot predictions and display the graph Plot predictions and display the graph
""" """
xsort = training_data_x.copy() xsort = training_data_x.copy()
xsort.sort(axis=0) xsort.sort(axis=0)
@ -128,6 +140,10 @@ def plot_preds(
if __name__ == "__main__": if __name__ == "__main__":
import doctest
doctest.testmod()
training_data_x, mcol_b, col_a, col_b = load_data("tips", "total_bill", "tip") training_data_x, mcol_b, col_a, col_b = load_data("tips", "total_bill", "tip")
predictions = get_preds(training_data_x, mcol_b, 0.5) predictions = get_preds(training_data_x, mcol_b, 0.5)
plot_preds(training_data_x, predictions, col_a, col_b, "total_bill", "tip") plot_preds(training_data_x, predictions, col_a, col_b, "total_bill", "tip")