Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

[pull] master from TheAlgorithms:master #75

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@
* [Haralick Descriptors](computer_vision/haralick_descriptors.py)
* [Harris Corner](computer_vision/harris_corner.py)
* [Horn Schunck](computer_vision/horn_schunck.py)
* [Intensity Based Segmentation](computer_vision/intensity_based_segmentation.py)
* [Mean Threshold](computer_vision/mean_threshold.py)
* [Mosaic Augmentation](computer_vision/mosaic_augmentation.py)
* [Pooling Functions](computer_vision/pooling_functions.py)
Expand Down Expand Up @@ -507,6 +508,7 @@
* [Kahns Algorithm Long](graphs/kahns_algorithm_long.py)
* [Kahns Algorithm Topo](graphs/kahns_algorithm_topo.py)
* [Karger](graphs/karger.py)
* [Lanczos Eigenvectors](graphs/lanczos_eigenvectors.py)
* [Markov Chain](graphs/markov_chain.py)
* [Matching Min Vertex Cover](graphs/matching_min_vertex_cover.py)
* [Minimum Path Sum](graphs/minimum_path_sum.py)
Expand Down Expand Up @@ -886,6 +888,7 @@
* [N Body Simulation](physics/n_body_simulation.py)
* [Newtons Law Of Gravitation](physics/newtons_law_of_gravitation.py)
* [Newtons Second Law Of Motion](physics/newtons_second_law_of_motion.py)
* [Period Of Pendulum](physics/period_of_pendulum.py)
* [Photoelectric Effect](physics/photoelectric_effect.py)
* [Potential Energy](physics/potential_energy.py)
* [Rainfall Intensity](physics/rainfall_intensity.py)
Expand Down
52 changes: 52 additions & 0 deletions graphics/digital_differential_analyzer_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import matplotlib.pyplot as plt


def digital_differential_analyzer_line(
p1: tuple[int, int], p2: tuple[int, int]
) -> list[tuple[int, int]]:
"""
Draws a line between two points using the DDA algorithm.

Args:
- p1: Coordinates of the starting point.
- p2: Coordinates of the ending point.
Returns:
- List of coordinate points that form the line.

>>> digital_differential_analyzer_line((1, 1), (4, 4))
[(2, 2), (3, 3), (4, 4)]
"""
x1, y1 = p1
x2, y2 = p2
dx = x2 - x1
dy = y2 - y1
steps = max(abs(dx), abs(dy))
x_increment = dx / float(steps)
y_increment = dy / float(steps)
coordinates = []
x: float = x1
y: float = y1
for _ in range(steps):
x += x_increment
y += y_increment
coordinates.append((int(round(x)), int(round(y))))
return coordinates


if __name__ == "__main__":
import doctest

doctest.testmod()

x1 = int(input("Enter the x-coordinate of the starting point: "))
y1 = int(input("Enter the y-coordinate of the starting point: "))
x2 = int(input("Enter the x-coordinate of the ending point: "))
y2 = int(input("Enter the y-coordinate of the ending point: "))
coordinates = digital_differential_analyzer_line((x1, y1), (x2, y2))
x_points, y_points = zip(*coordinates)
plt.plot(x_points, y_points, marker="o")
plt.title("Digital Differential Analyzer Line Drawing Algorithm")
plt.xlabel("X-axis")
plt.ylabel("Y-axis")
plt.grid()
plt.show()
55 changes: 55 additions & 0 deletions maths/geometric_mean.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"""
The Geometric Mean of n numbers is defined as the n-th root of the product
of those numbers. It is used to measure the central tendency of the numbers.
https://en.wikipedia.org/wiki/Geometric_mean
"""


def compute_geometric_mean(*args: int) -> float:
"""
Return the geometric mean of the argument numbers.
>>> compute_geometric_mean(2,8)
4.0
>>> compute_geometric_mean('a', 4)
Traceback (most recent call last):
...
TypeError: Not a Number
>>> compute_geometric_mean(5, 125)
25.0
>>> compute_geometric_mean(1, 0)
0.0
>>> compute_geometric_mean(1, 5, 25, 5)
5.0
>>> compute_geometric_mean(2, -2)
Traceback (most recent call last):
...
ArithmeticError: Cannot Compute Geometric Mean for these numbers.
>>> compute_geometric_mean(-5, 25, 1)
-5.0
"""
product = 1
for number in args:
if not isinstance(number, int) and not isinstance(number, float):
raise TypeError("Not a Number")
product *= number
# Cannot calculate the even root for negative product.
# Frequently they are restricted to being positive.
if product < 0 and len(args) % 2 == 0:
raise ArithmeticError("Cannot Compute Geometric Mean for these numbers.")
mean = abs(product) ** (1 / len(args))
# Since python calculates complex roots for negative products with odd roots.
if product < 0:
mean = -mean
# Since it does floating point arithmetic, it gives 64**(1/3) as 3.99999996
possible_mean = float(round(mean))
# To check if the rounded number is actually the mean.
if possible_mean ** len(args) == product:
mean = possible_mean
return mean


if __name__ == "__main__":
from doctest import testmod

testmod(name="compute_geometric_mean")
print(compute_geometric_mean(-3, -27))
97 changes: 55 additions & 42 deletions maths/trapezoidal_rule.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
"""
Numerical integration or quadrature for a smooth function f with known values at x_i

This method is the classical approach of suming 'Equally Spaced Abscissas'

method 1:
"extended trapezoidal rule"
int(f) = dx/2 * (f1 + 2f2 + ... + fn)

"""


def method_1(boundary, steps):
def trapezoidal_rule(boundary, steps):
"""
Apply the extended trapezoidal rule to approximate the integral of function f(x)
over the interval defined by 'boundary' with the number of 'steps'.

Args:
boundary (list of floats): A list containing the start and end values [a, b].
steps (int): The number of steps or subintervals.
Returns:
float: Approximation of the integral of f(x) over [a, b].
Examples:
>>> method_1([0, 1], 10)
0.3349999999999999
Implements the extended trapezoidal rule for numerical integration.
The function f(x) is provided below.

:param boundary: List containing the lower and upper bounds of integration [a, b]
:param steps: The number of steps (intervals) used in the approximation
:return: The numerical approximation of the integral

>>> abs(trapezoidal_rule([0, 1], 10) - 0.33333) < 0.01
True
>>> abs(trapezoidal_rule([0, 1], 100) - 0.33333) < 0.01
True
>>> abs(trapezoidal_rule([0, 2], 1000) - 2.66667) < 0.01
True
>>> abs(trapezoidal_rule([1, 2], 1000) - 2.33333) < 0.01
True
"""
h = (boundary[1] - boundary[0]) / steps
a = boundary[0]
Expand All @@ -31,57 +28,73 @@ def method_1(boundary, steps):
y = 0.0
y += (h / 2.0) * f(a)
for i in x_i:
# print(i)
y += h * f(i)
y += (h / 2.0) * f(b)
return y


def make_points(a, b, h):
"""
Generates points between 'a' and 'b' with step size 'h', excluding the end points.
Args:
a (float): Start value
b (float): End value
h (float): Step size
Examples:
Generates points between a and b with step size h for trapezoidal integration.

:param a: The lower bound of integration
:param b: The upper bound of integration
:param h: The step size
:yield: The next x-value in the range (a, b)

>>> list(make_points(0, 1, 0.1)) # doctest: +NORMALIZE_WHITESPACE
[0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7, 0.7999999999999999, \
0.8999999999999999]
>>> list(make_points(0, 10, 2.5))
[2.5, 5.0, 7.5]

>>> list(make_points(0, 10, 2))
[2, 4, 6, 8]

>>> list(make_points(1, 21, 5))
[6, 11, 16]

>>> list(make_points(1, 5, 2))
[3]

>>> list(make_points(1, 4, 3))
[]
"""
x = a + h
while x <= (b - h):
yield x
x = x + h
x += h


def f(x): # enter your function here
def f(x):
"""
Example:
>>> f(2)
4
This is the function to integrate, f(x) = (x - 0)^2 = x^2.

:param x: The input value
:return: The value of f(x)

>>> f(0)
0
>>> f(1)
1
>>> f(0.5)
0.25
"""
y = (x - 0) * (x - 0)
return y
return x**2


def main():
a = 0.0 # Lower bound of integration
b = 1.0 # Upper bound of integration
steps = 10.0 # define number of steps or resolution
boundary = [a, b] # define boundary of integration
y = method_1(boundary, steps)
"""
Main function to test the trapezoidal rule.
:a: Lower bound of integration
:b: Upper bound of integration
:steps: define number of steps or resolution
:boundary: define boundary of integration

>>> main()
y = 0.3349999999999999
"""
a = 0.0
b = 1.0
steps = 10.0
boundary = [a, b]
y = trapezoidal_rule(boundary, steps)
print(f"y = {y}")


Expand Down
53 changes: 53 additions & 0 deletions physics/period_of_pendulum.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""
Title : Computing the time period of a simple pendulum

The simple pendulum is a mechanical system that sways or moves in an
oscillatory motion. The simple pendulum comprises of a small bob of
mass m suspended by a thin string of length L and secured to a platform
at its upper end. Its motion occurs in a vertical plane and is mainly
driven by gravitational force. The period of the pendulum depends on the
length of the string and the amplitude (the maximum angle) of oscillation.
However, the effect of the amplitude can be ignored if the amplitude is
small. It should be noted that the period does not depend on the mass of
the bob.

For small amplitudes, the period of a simple pendulum is given by the
following approximation:
T ≈ 2π * √(L / g)

where:
L = length of string from which the bob is hanging (in m)
g = acceleration due to gravity (approx 9.8 m/s²)

Reference : https://byjus.com/jee/simple-pendulum/
"""

from math import pi

from scipy.constants import g


def period_of_pendulum(length: float) -> float:
"""
>>> period_of_pendulum(1.23)
2.2252155506257845
>>> period_of_pendulum(2.37)
3.0888278441908574
>>> period_of_pendulum(5.63)
4.76073193364765
>>> period_of_pendulum(-12)
Traceback (most recent call last):
...
ValueError: The length should be non-negative
>>> period_of_pendulum(0)
0.0
"""
if length < 0:
raise ValueError("The length should be non-negative")
return 2 * pi * (length / g) ** 0.5


if __name__ == "__main__":
import doctest

doctest.testmod()
Loading