Skip to content
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

Added Fast Inverse Square Root #11054

Merged
merged 8 commits into from
Oct 29, 2023
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
10 changes: 10 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
* [Bitwise Addition Recursive](bit_manipulation/bitwise_addition_recursive.py)
* [Count 1S Brian Kernighan Method](bit_manipulation/count_1s_brian_kernighan_method.py)
* [Count Number Of One Bits](bit_manipulation/count_number_of_one_bits.py)
* [Excess 3 Code](bit_manipulation/excess_3_code.py)
* [Gray Code Sequence](bit_manipulation/gray_code_sequence.py)
* [Highest Set Bit](bit_manipulation/highest_set_bit.py)
* [Index Of Rightmost Set Bit](bit_manipulation/index_of_rightmost_set_bit.py)
Expand Down Expand Up @@ -170,7 +171,10 @@
* Arrays
* [Equilibrium Index In Array](data_structures/arrays/equilibrium_index_in_array.py)
* [Find Triplets With 0 Sum](data_structures/arrays/find_triplets_with_0_sum.py)
* [Index 2D Array In 1D](data_structures/arrays/index_2d_array_in_1d.py)
* [Kth Largest Element](data_structures/arrays/kth_largest_element.py)
* [Median Two Array](data_structures/arrays/median_two_array.py)
* [Monotonic Array](data_structures/arrays/monotonic_array.py)
* [Pairs With Given Sum](data_structures/arrays/pairs_with_given_sum.py)
* [Permutations](data_structures/arrays/permutations.py)
* [Prefix Sum](data_structures/arrays/prefix_sum.py)
Expand Down Expand Up @@ -368,6 +372,7 @@
## Electronics
* [Apparent Power](electronics/apparent_power.py)
* [Builtin Voltage](electronics/builtin_voltage.py)
* [Capacitor Equivalence](electronics/capacitor_equivalence.py)
* [Carrier Concentration](electronics/carrier_concentration.py)
* [Charging Capacitor](electronics/charging_capacitor.py)
* [Charging Inductor](electronics/charging_inductor.py)
Expand Down Expand Up @@ -531,12 +536,14 @@
## Machine Learning
* [Apriori Algorithm](machine_learning/apriori_algorithm.py)
* [Astar](machine_learning/astar.py)
* [Automatic Differentiation](machine_learning/automatic_differentiation.py)
* [Data Transformations](machine_learning/data_transformations.py)
* [Decision Tree](machine_learning/decision_tree.py)
* [Dimensionality Reduction](machine_learning/dimensionality_reduction.py)
* Forecasting
* [Run](machine_learning/forecasting/run.py)
* [Frequent Pattern Growth](machine_learning/frequent_pattern_growth.py)
* [Gradient Boosting Classifier](machine_learning/gradient_boosting_classifier.py)
* [Gradient Descent](machine_learning/gradient_descent.py)
* [K Means Clust](machine_learning/k_means_clust.py)
* [K Nearest Neighbours](machine_learning/k_nearest_neighbours.py)
Expand Down Expand Up @@ -598,6 +605,7 @@
* [Extended Euclidean Algorithm](maths/extended_euclidean_algorithm.py)
* [Factorial](maths/factorial.py)
* [Factors](maths/factors.py)
* [Fast Inverse Sqrt](maths/fast_inverse_sqrt.py)
* [Fermat Little Theorem](maths/fermat_little_theorem.py)
* [Fibonacci](maths/fibonacci.py)
* [Find Max](maths/find_max.py)
Expand Down Expand Up @@ -648,6 +656,7 @@
* [Numerical Integration](maths/numerical_analysis/numerical_integration.py)
* [Runge Kutta](maths/numerical_analysis/runge_kutta.py)
* [Runge Kutta Fehlberg 45](maths/numerical_analysis/runge_kutta_fehlberg_45.py)
* [Runge Kutta Gills](maths/numerical_analysis/runge_kutta_gills.py)
* [Secant Method](maths/numerical_analysis/secant_method.py)
* [Simpson Rule](maths/numerical_analysis/simpson_rule.py)
* [Square Root](maths/numerical_analysis/square_root.py)
Expand Down Expand Up @@ -814,6 +823,7 @@
* [Ideal Gas Law](physics/ideal_gas_law.py)
* [In Static Equilibrium](physics/in_static_equilibrium.py)
* [Kinetic Energy](physics/kinetic_energy.py)
* [Lens Formulae](physics/lens_formulae.py)
* [Lorentz Transformation Four Vector](physics/lorentz_transformation_four_vector.py)
* [Malus Law](physics/malus_law.py)
* [Mass Energy Equivalence](physics/mass_energy_equivalence.py)
Expand Down
54 changes: 54 additions & 0 deletions maths/fast_inverse_sqrt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""
Fast inverse square root (1/sqrt(x)) using the Quake III algorithm.
Reference: https://en.wikipedia.org/wiki/Fast_inverse_square_root
Accuracy: https://en.wikipedia.org/wiki/Fast_inverse_square_root#Accuracy
"""

import struct


def fast_inverse_sqrt(number: float) -> float:
"""
Compute the fast inverse square root of a floating-point number using the famous
Quake III algorithm.

:param float number: Input number for which to calculate the inverse square root.
:return float: The fast inverse square root of the input number.

Example:
>>> fast_inverse_sqrt(10)
0.3156857923527257
>>> fast_inverse_sqrt(4)
0.49915357479239103
>>> fast_inverse_sqrt(4.1)
0.4932849504615651
>>> fast_inverse_sqrt(0)
Traceback (most recent call last):
...
ValueError: Input must be a positive number.
>>> fast_inverse_sqrt(-1)
Traceback (most recent call last):
...
ValueError: Input must be a positive number.
>>> from math import isclose, sqrt
>>> all(isclose(fast_inverse_sqrt(i), 1 / sqrt(i), rel_tol=0.00132)
... for i in range(50, 60))
True
"""
if number <= 0:
raise ValueError("Input must be a positive number.")
i = struct.unpack(">i", struct.pack(">f", number))[0]
i = 0x5F3759DF - (i >> 1)
y = struct.unpack(">f", struct.pack(">i", i))[0]
return y * (1.5 - 0.5 * number * y * y)


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

testmod()
# https://en.wikipedia.org/wiki/Fast_inverse_square_root#Accuracy
from math import sqrt

for i in range(5, 101, 5):
print(f"{i:>3}: {(1 / sqrt(i)) - fast_inverse_sqrt(i):.5f}")