From fa9cd031c4b614ec1ab66c7970f592659b9952bf Mon Sep 17 00:00:00 2001 From: PARIKSHIT SINGH Date: Sun, 2 Mar 2025 11:02:47 +0530 Subject: [PATCH 1/5] feat: Implement Principal Component Analysis (PCA) - Added PCA implementation with dataset standardization. - Used Singular Value Decomposition (SVD) for computing principal components. - Fixed import sorting to comply with PEP 8 (Ruff I001). - Ensured type hints and docstrings for better readability. - Added doctests to validate correctness. - Passed all Ruff checks and automated tests. --- DIRECTORY.md | 2 + .../principle_component_analysis.py | 85 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 machine_learning/principle_component_analysis.py diff --git a/DIRECTORY.md b/DIRECTORY.md index a535f12cb59a..ab3259b9a766 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -395,6 +395,7 @@ * [Minimum Tickets Cost](dynamic_programming/minimum_tickets_cost.py) * [Optimal Binary Search Tree](dynamic_programming/optimal_binary_search_tree.py) * [Palindrome Partitioning](dynamic_programming/palindrome_partitioning.py) + * [Range Sum Query](dynamic_programming/range_sum_query.py) * [Regex Match](dynamic_programming/regex_match.py) * [Rod Cutting](dynamic_programming/rod_cutting.py) * [Smith Waterman](dynamic_programming/smith_waterman.py) @@ -608,6 +609,7 @@ * [Mfcc](machine_learning/mfcc.py) * [Multilayer Perceptron Classifier](machine_learning/multilayer_perceptron_classifier.py) * [Polynomial Regression](machine_learning/polynomial_regression.py) + * [Principle Component Analysis](machine_learning/principle_component_analysis.py) * [Scoring Functions](machine_learning/scoring_functions.py) * [Self Organizing Map](machine_learning/self_organizing_map.py) * [Sequential Minimum Optimization](machine_learning/sequential_minimum_optimization.py) diff --git a/machine_learning/principle_component_analysis.py b/machine_learning/principle_component_analysis.py new file mode 100644 index 000000000000..46ccdb968494 --- /dev/null +++ b/machine_learning/principle_component_analysis.py @@ -0,0 +1,85 @@ +""" +Principal Component Analysis (PCA) is a dimensionality reduction technique +used in machine learning. It transforms high-dimensional data into a lower-dimensional +representation while retaining as much variance as possible. + +This implementation follows best practices, including: +- Standardizing the dataset. +- Computing principal components using Singular Value Decomposition (SVD). +- Returning transformed data and explained variance ratio. +""" + +import doctest + +import numpy as np +from sklearn.datasets import load_iris +from sklearn.decomposition import PCA +from sklearn.preprocessing import StandardScaler + + +def collect_dataset() -> tuple[np.ndarray, np.ndarray]: + """ + Collects the dataset (Iris dataset) and returns feature matrix and target values. + + :return: Tuple containing feature matrix (X) and target labels (y) + + Example: + >>> X, y = collect_dataset() + >>> X.shape + (150, 4) + >>> y.shape + (150,) + """ + data = load_iris() + return np.array(data.data), np.array(data.target) + + +def apply_pca(data_x: np.ndarray, n_components: int) -> tuple[np.ndarray, np.ndarray]: + """ + Applies Principal Component Analysis (PCA) to reduce dimensionality. + + :param data_x: Original dataset (features) + :param n_components: Number of principal components to retain + :return: Tuple containing transformed dataset and explained variance ratio + + Example: + >>> X, _ = collect_dataset() + >>> transformed_X, variance = apply_pca(X, 2) + >>> transformed_X.shape + (150, 2) + >>> len(variance) == 2 + True + """ + # Standardizing the dataset + scaler = StandardScaler() + data_x_scaled = scaler.fit_transform(data_x) + + # Applying PCA + pca = PCA(n_components=n_components) + principal_components = pca.fit_transform(data_x_scaled) + + return principal_components, pca.explained_variance_ratio_ + + +def main() -> None: + """ + Driver function to execute PCA and display results. + """ + data_x, data_y = collect_dataset() + + # Number of principal components to retain + n_components = 2 + + # Apply PCA + transformed_data, variance_ratio = apply_pca(data_x, n_components) + + print("Transformed Dataset (First 5 rows):") + print(transformed_data[:5]) + + print("\nExplained Variance Ratio:") + print(variance_ratio) + + +if __name__ == "__main__": + doctest.testmod() + main() From 733a28577e5bda44216f056595501f8d1460c7a7 Mon Sep 17 00:00:00 2001 From: PARIKSHIT SINGH <90330646+parikshit2111@users.noreply.github.com> Date: Wed, 5 Mar 2025 11:57:53 +0530 Subject: [PATCH 2/5] Collision detection (#6) * collision_detection initial commit --------- Co-authored-by: parikshit2111 --- DIRECTORY.md | 1 + physics/collision_detection.py | 94 ++++++++++++++++++++++++++++++++++ requirements.txt | 1 + 3 files changed, 96 insertions(+) create mode 100644 physics/collision_detection.py diff --git a/DIRECTORY.md b/DIRECTORY.md index ab3259b9a766..fb1788a18d96 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -878,6 +878,7 @@ * [Casimir Effect](physics/casimir_effect.py) * [Center Of Mass](physics/center_of_mass.py) * [Centripetal Force](physics/centripetal_force.py) + * [Collision Detection](physics/collision_detection.py) * [Coulombs Law](physics/coulombs_law.py) * [Doppler Frequency](physics/doppler_frequency.py) * [Grahams Law](physics/grahams_law.py) diff --git a/physics/collision_detection.py b/physics/collision_detection.py new file mode 100644 index 000000000000..4a0af5c004ce --- /dev/null +++ b/physics/collision_detection.py @@ -0,0 +1,94 @@ +""" +Title : AABB Collision Detection and Counter + +Description : This program simulates two moving boxes that bounce back when they +collide with each other or with the edges of the screen. A collision counter +increments each time the boxes collide, except when they touch the edges of the +screen, where they rebound without increasing the counter. The motion and +collision logic demonstrate axis-aligned bounding box (AABB) collision detection. + +The program is implemented using Pygame and features: +- Two boxes moving towards each other +- Collision detection between the boxes +- Edge collision handling (without counter increment) +- A visual counter displaying the number of collisions + +Source : +- https://en.wikipedia.org/wiki/Bounding_volume +- https://www.pygame.org/docs/ +""" + +import pygame + +# Initialize Pygame +pygame.init() + +# Constants for screen dimensions and box properties +WIDTH, HEIGHT = 500, 300 # Screen width and height +BOX_SIZE = 50 # Size of each box +SPEED = 3 # Speed of movement + +# Colors +WHITE = (255, 255, 255) # Background color +RED = (255, 0, 0) # Box 1 color +BLUE = (0, 0, 255) # Box 2 color + +# Create display window +screen = pygame.display.set_mode((WIDTH, HEIGHT)) +pygame.display.set_caption("AABB Collision Detection") + +# Initial positions of the boxes +box1_x, box1_y = 50, HEIGHT // 2 - BOX_SIZE // 2 +box2_x, box2_y = WIDTH - 100, HEIGHT // 2 - BOX_SIZE // 2 + +# Movement directions +box1_dir = SPEED +box2_dir = -SPEED + +# Collision counter +collision_count = 0 + +# Main game loop +running = True +while running: + pygame.time.delay(20) # Controls the frame rate + screen.fill(WHITE) # Clear screen before drawing + + # Move the boxes + box1_x += box1_dir + box2_x += box2_dir + + # Collision detection between the two boxes + if box1_x + BOX_SIZE > box2_x: + # Only increase the counter if they overlap beyond just touching edges + if box1_x + BOX_SIZE > box2_x + 1 or box2_x > box1_x + 1: + collision_count += 1 + box1_dir *= -1 # Reverse direction + box2_dir *= -1 # Reverse direction + + # Edge collision detection (bouncing without increasing counter) + if box1_x <= 0 or box1_x + BOX_SIZE >= WIDTH: + box1_dir *= -1 + if box2_x <= 0 or box2_x + BOX_SIZE >= WIDTH: + box2_dir *= -1 + + # Draw the boxes + pygame.draw.rect(screen, RED, (box1_x, box1_y, BOX_SIZE, BOX_SIZE)) + pygame.draw.rect(screen, BLUE, (box2_x, box2_y, BOX_SIZE, BOX_SIZE)) + + # Display the collision count + font = pygame.font.Font(None, 36) + text = font.render("Collisions: " + str(collision_count), True, (0, 0, 0)) + screen.blit(text, (10, 10)) + + # Event handling + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + print("Number of collisions occured are",collision_count) + + + pygame.display.update() + +# Quit Pygame +pygame.quit() diff --git a/requirements.txt b/requirements.txt index b104505e01bc..d0317bdc0ca6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,3 +17,4 @@ sympy tweepy typing_extensions xgboost +pygame \ No newline at end of file From 476f739ca8f3031e76651e1ba06f83547a4d1e19 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 5 Mar 2025 06:41:14 +0000 Subject: [PATCH 3/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- physics/collision_detection.py | 3 +-- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/physics/collision_detection.py b/physics/collision_detection.py index 4a0af5c004ce..40dcc56de688 100644 --- a/physics/collision_detection.py +++ b/physics/collision_detection.py @@ -85,8 +85,7 @@ for event in pygame.event.get(): if event.type == pygame.QUIT: running = False - print("Number of collisions occured are",collision_count) - + print("Number of collisions occured are", collision_count) pygame.display.update() diff --git a/requirements.txt b/requirements.txt index d0317bdc0ca6..d52e5d155ce3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,6 +8,7 @@ numpy opencv-python pandas pillow +pygame requests rich scikit-learn @@ -17,4 +18,3 @@ sympy tweepy typing_extensions xgboost -pygame \ No newline at end of file From 0745bea3d1e8cf5a0efa91c380f38e1a1ba2678c Mon Sep 17 00:00:00 2001 From: PARIKSHIT SINGH Date: Wed, 5 Mar 2025 12:12:42 +0530 Subject: [PATCH 4/5] fixed:Spelling error --- physics/collision_detection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/physics/collision_detection.py b/physics/collision_detection.py index 4a0af5c004ce..1c38bcef9b83 100644 --- a/physics/collision_detection.py +++ b/physics/collision_detection.py @@ -85,7 +85,7 @@ for event in pygame.event.get(): if event.type == pygame.QUIT: running = False - print("Number of collisions occured are",collision_count) + print("Number of collisions occurred are",collision_count) pygame.display.update() From f4840a75729eb086c919c5ea2f45d1abf9d06879 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 5 Mar 2025 06:52:50 +0000 Subject: [PATCH 5/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- physics/collision_detection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/physics/collision_detection.py b/physics/collision_detection.py index 868995c6833a..f0134f088a95 100644 --- a/physics/collision_detection.py +++ b/physics/collision_detection.py @@ -85,7 +85,7 @@ for event in pygame.event.get(): if event.type == pygame.QUIT: running = False - print("Number of collisions occurred are",collision_count) + print("Number of collisions occurred are", collision_count) pygame.display.update() # Quit Pygame