Compare commits

...

5 Commits

Author SHA1 Message Date
Syed Shoaib Abbas
c9e1546870
Merge 451ac39ef8 into 9a572dec2b 2024-10-05 09:55:19 +03:00
ARNAV RAJ
9a572dec2b
feat: Implemented Matrix Exponentiation Method (#11747)
* feat: add Matrix Exponentiation method
docs: updated the header documentation and added new documentation for
the new function.

* feat: added new function matrix exponetiation method

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

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

* feat: This function uses the tail-recursive form of the Euclidean algorithm to calculate

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

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

* reduced the number of characters per line in the comments

* removed unwanted code

* feat: Implemented a new function to swaap numbers without dummy variable

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

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

* removed previos code

* Done with the required changes

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

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

* Done with the required changes

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

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

* Done with the required changes

* Done with the required changes

* Done with the required changes

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

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

* Update maths/fibonacci.py

Co-authored-by: Tianyi Zheng <tianyizheng02@gmail.com>

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

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

* Done with the required changes

* Done with the required changes

* Done with the required changes

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

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

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Tianyi Zheng <tianyizheng02@gmail.com>
2024-10-04 09:29:39 -07:00
Syed Shoaib Abbas
451ac39ef8 run overcommit and refactor code 2024-10-04 11:04:37 +05:00
Syed Shoaib Abbas
d09163121d refactor code 2024-10-04 10:42:59 +05:00
Syed Shoaib Abbas
7e6e6420b8 power factor calculator 2024-10-03 18:12:41 +05:00
2 changed files with 178 additions and 0 deletions

View File

@ -0,0 +1,90 @@
import math
def calculate_apparent_power(voltage, current):
"""Calculate the apparent power (S) in volt-amperes (VA)."""
try:
return voltage * current
except TypeError:
error_msg = "Invalid input types for voltage or current. Both must be numbers."
raise ValueError(error_msg)
def calculate_power_factor(real_power, apparent_power):
"""Calculate the power factor (PF)."""
try:
if apparent_power == 0:
raise ValueError("Apparent power cannot be zero.")
return real_power / apparent_power
except TypeError:
error_msg = (
"Invalid input types for real power or apparent power. "
"Both must be numbers."
)
raise ValueError(error_msg)
def calculate_reactive_power(real_power, apparent_power):
"""Calculate the reactive power (Q) in volt-amperes reactive (VAR)."""
try:
if apparent_power < real_power:
raise ValueError(
"Apparent power must be greater than or equal to real power."
)
return math.sqrt(apparent_power**2 - real_power**2)
except TypeError:
error_msg = (
"Invalid input types for real power or apparent power. "
"Both must be numbers."
)
raise ValueError(error_msg)
except ValueError as ve:
error_msg = f"Calculation error: {ve}"
raise ValueError(error_msg)
def calculate_correction_capacitance(reactive_power, voltage, frequency=60):
"""Calculate the size of the correction capacitor in microfarads (µF)."""
try:
if voltage == 0:
raise ValueError("Voltage cannot be zero.")
capacitance = (reactive_power * 1_000_000) / (
2 * math.pi * frequency * voltage**2
)
return capacitance
except TypeError:
error_msg = (
"Invalid input types for reactive power, voltage, or "
"frequency. They must be numbers."
)
raise ValueError(error_msg)
except ValueError as ve:
error_msg = f"Calculation error: {ve}"
raise ValueError(error_msg)
def main():
try:
real_power = float(input("Enter real power in watts: "))
current = float(input("Enter current in amps: "))
voltage = float(input("Enter voltage in volts: "))
apparent_power = calculate_apparent_power(voltage, current)
power_factor = calculate_power_factor(real_power, apparent_power)
reactive_power = calculate_reactive_power(real_power, apparent_power)
correction_capacitance = calculate_correction_capacitance(
reactive_power, voltage
)
print("\nResults:")
print(f"Power Factor: {power_factor:.4f}")
print(f"Apparent Power: {apparent_power:.0f} VA")
print(f"Reactive Power: {reactive_power:.0f} VAR")
print(f"Correction Capacitance: {correction_capacitance:.3f} µF")
except ValueError as e:
print(f"Error: {e}")
if __name__ == "__main__":
main()

View File

@ -7,6 +7,8 @@ the Binet's formula function because the Binet formula function uses floats
NOTE 2: the Binet's formula function is much more limited in the size of inputs
that it can handle due to the size limitations of Python floats
NOTE 3: the matrix function is the fastest and most memory efficient for large n
See benchmark numbers in __main__ for performance comparisons/
https://en.wikipedia.org/wiki/Fibonacci_number for more information
@ -17,6 +19,9 @@ from collections.abc import Iterator
from math import sqrt
from time import time
import numpy as np
from numpy import ndarray
def time_func(func, *args, **kwargs):
"""
@ -230,6 +235,88 @@ def fib_binet(n: int) -> list[int]:
return [round(phi**i / sqrt_5) for i in range(n + 1)]
def matrix_pow_np(m: ndarray, power: int) -> ndarray:
"""
Raises a matrix to the power of 'power' using binary exponentiation.
Args:
m: Matrix as a numpy array.
power: The power to which the matrix is to be raised.
Returns:
The matrix raised to the power.
Raises:
ValueError: If power is negative.
>>> m = np.array([[1, 1], [1, 0]], dtype=int)
>>> matrix_pow_np(m, 0) # Identity matrix when raised to the power of 0
array([[1, 0],
[0, 1]])
>>> matrix_pow_np(m, 1) # Same matrix when raised to the power of 1
array([[1, 1],
[1, 0]])
>>> matrix_pow_np(m, 5)
array([[8, 5],
[5, 3]])
>>> matrix_pow_np(m, -1)
Traceback (most recent call last):
...
ValueError: power is negative
"""
result = np.array([[1, 0], [0, 1]], dtype=int) # Identity Matrix
base = m
if power < 0: # Negative power is not allowed
raise ValueError("power is negative")
while power:
if power % 2 == 1:
result = np.dot(result, base)
base = np.dot(base, base)
power //= 2
return result
def fib_matrix_np(n: int) -> int:
"""
Calculates the n-th Fibonacci number using matrix exponentiation.
https://www.nayuki.io/page/fast-fibonacci-algorithms#:~:text=
Summary:%20The%20two%20fast%20Fibonacci%20algorithms%20are%20matrix
Args:
n: Fibonacci sequence index
Returns:
The n-th Fibonacci number.
Raises:
ValueError: If n is negative.
>>> fib_matrix_np(0)
0
>>> fib_matrix_np(1)
1
>>> fib_matrix_np(5)
5
>>> fib_matrix_np(10)
55
>>> fib_matrix_np(-1)
Traceback (most recent call last):
...
ValueError: n is negative
"""
if n < 0:
raise ValueError("n is negative")
if n == 0:
return 0
m = np.array([[1, 1], [1, 0]], dtype=int)
result = matrix_pow_np(m, n - 1)
return int(result[0, 0])
if __name__ == "__main__":
from doctest import testmod
@ -242,3 +329,4 @@ if __name__ == "__main__":
time_func(fib_memoization, num) # 0.0100 ms
time_func(fib_recursive_cached, num) # 0.0153 ms
time_func(fib_recursive, num) # 257.0910 ms
time_func(fib_matrix_np, num) # 0.0000 ms