226 lines
5.0 KiB
Python
226 lines
5.0 KiB
Python
import math
|
|
|
|
"""
|
|
Energy - General functions
|
|
"""
|
|
multipliers = {
|
|
'Y': 1e24,
|
|
'Z': 1e21,
|
|
'E': 1e18,
|
|
'P': 1e15,
|
|
'T': 1e12,
|
|
'G': 1e9,
|
|
'M': 1e6,
|
|
'K': 1e3,
|
|
'x': 1.0,
|
|
'm': 1e-3,
|
|
'u': 1e-6,
|
|
'n': 1e-9,
|
|
'p': 1e-12,
|
|
'f': 1e-15,
|
|
'a': 1e-18,
|
|
'z': 1e-21,
|
|
'y': 1e-24,
|
|
}
|
|
|
|
mult_pow = {
|
|
24: 'Y',
|
|
21: 'Z',
|
|
18: 'E',
|
|
15: 'P',
|
|
12: 'T',
|
|
9: 'G',
|
|
6: 'M',
|
|
3: 'K',
|
|
0: '',
|
|
-3: 'm',
|
|
-6: 'u',
|
|
-9: 'n',
|
|
-12: 'p',
|
|
-15: 'f',
|
|
-18: 'a',
|
|
-21: 'z',
|
|
-24: 'y',
|
|
}
|
|
|
|
def float_to_str(value, round_val=None, omit_dot_zero=False):
|
|
sign = ''
|
|
|
|
if value < 0:
|
|
sign = '-'
|
|
value = -1 * value
|
|
|
|
target_mult = 0
|
|
|
|
if value == 0:
|
|
return "0"
|
|
|
|
elif value < 1:
|
|
while value < 1:
|
|
target_mult -= 3
|
|
value = value * 1000.0
|
|
else:
|
|
while value >= 1000:
|
|
target_mult += 3
|
|
value = value / 1000.0
|
|
|
|
if round_val is not None:
|
|
value = round(value, round_val)
|
|
|
|
if omit_dot_zero and value.is_integer():
|
|
value = int(value)
|
|
|
|
return f"{sign}{value}{mult_pow[target_mult]}"
|
|
|
|
def str_to_float(value):
|
|
"""
|
|
Converts a string to a float, accounting for unit multipliers such as M/k/m/u
|
|
"""
|
|
multiplier = str(value)[-1]
|
|
|
|
# account for multiplier
|
|
if multiplier in multipliers:
|
|
number = float(value[:-1])
|
|
multiplier = float(multipliers[multiplier])
|
|
value = number * multiplier
|
|
|
|
return float(value)
|
|
|
|
def str_to_int(value):
|
|
"""
|
|
Converts a string to an int, accounting for unit multipliers such as M/k/m/u
|
|
"""
|
|
float_value = str_to_float(value)
|
|
|
|
return int(float_value)
|
|
|
|
def str_add_vals(val1, val2):
|
|
"""
|
|
Adds two values in str representation
|
|
:param val1: first value (with unit multipliers)
|
|
:param val2: second value (with unit multipliers)
|
|
:return: the sum in textual representation (with unit multipliers)
|
|
"""
|
|
mul1 = str(val1[-1])
|
|
mul2 = str(val2[-1])
|
|
|
|
if mul1 not in multipliers:
|
|
val1 = f"{val1}x"
|
|
mul1 = "x"
|
|
|
|
if mul2 not in multipliers:
|
|
val2 = f"{val2}x"
|
|
mul2 = "x"
|
|
|
|
# equal multiplier -> sum vals
|
|
if mul1 == mul2:
|
|
number = float(val1[:-1]) + float(val2[:-1])
|
|
|
|
else:
|
|
# Invert numbers so that mul1 < mul2
|
|
if multipliers[mul1] > multipliers[mul2]:
|
|
mul1, mul2 = mul2, mul1
|
|
val1, val2 = val2, val1
|
|
|
|
# mul1 < mul2 -> calculate multiplication ratio
|
|
ratio = multipliers[mul2]/multipliers[mul1]
|
|
number = float(val1[:-1]) + float(val2[:-1]) * ratio
|
|
|
|
if '.' not in str(val1) and '.' not in str(val2):
|
|
number = int(number)
|
|
|
|
return f"{number}{mul1 if mul1 != 'x' else ''}"
|
|
|
|
|
|
def energy_from_I_t(V, I, t):
|
|
"""
|
|
Calculates the energy consumption in the time interval t
|
|
:param V: voltage
|
|
:param I: current draw
|
|
:param t: time interval
|
|
"""
|
|
return float(V) * float(I) * float(t)
|
|
|
|
def energy_from_R_t(V, R, t):
|
|
"""
|
|
Calculates the energy consumption in the time interval t
|
|
:param V: voltage
|
|
:param R: resistance
|
|
:param t: time interval
|
|
"""
|
|
return float(V) * (float(V) / float(R)) * float(t)
|
|
|
|
def energy_from_I_f(V, I, f):
|
|
"""
|
|
Calculates the energy consumption of a clock cycle with frequency f
|
|
:param V: voltage
|
|
:param I: current draw
|
|
:param f: clock frequency
|
|
"""
|
|
return float(V) * float(I) / float(f)
|
|
|
|
def energy_from_R_f(V, R, f):
|
|
"""
|
|
Calculates the energy consumption of a clock cycle with frequency f
|
|
:param V: voltage
|
|
:param R: resistance
|
|
:param f: clock frequency
|
|
"""
|
|
return float(V) * (float(V) / float(R) ) / float(f)
|
|
|
|
def equivalent_resistance(V, I):
|
|
"""
|
|
Calculates the equivalent resistance of a given voltage and current draw
|
|
:param V: Voltage (V)
|
|
:param I: Current Draw (A)
|
|
"""
|
|
i = str_to_float(I)
|
|
v = str_to_float(V)
|
|
r = v / i
|
|
|
|
return r
|
|
|
|
def R_from_energy_t(V, e, t):
|
|
"""
|
|
Calculates the instantaneous equivalent resistance given the energy consumption in an instant t under the voltage V
|
|
:param V: Voltage (V)
|
|
:param e: energy consumed in t
|
|
:param t: time interval
|
|
:return: the equivalent resistance
|
|
"""
|
|
# e = V * I * t -> I = e / (V * t)
|
|
# V = R * I -> R = V / I
|
|
# R = V / (e / (V * t)) = V * V * t / e
|
|
if e == 0.0:
|
|
return float('inf')
|
|
|
|
r = (V * V * t) / e
|
|
return r
|
|
|
|
def R_from_parallel_r(R1, R2):
|
|
"""
|
|
Calculates the equivalent resistance of two parallel resistors
|
|
:param R1: resistor 1
|
|
:param R2: resistor 2
|
|
:return: the equivalent resistance
|
|
"""
|
|
if R1 == 0.0:
|
|
return R2
|
|
elif R2 == 0.0:
|
|
return R1
|
|
|
|
return 1.0 / (1.0 / R1 + 1.0 / R2)
|
|
|
|
def P_R_to_V(P, R):
|
|
"""
|
|
Calculates the voltage from instantaneous power and equivalent resistance
|
|
:param P: power
|
|
:param R: resistance
|
|
"""
|
|
# P = I * V
|
|
# V = R * I; I = V / R;
|
|
# P = (V * V) / R
|
|
# V = SQRT(P * R)
|
|
|
|
return math.sqrt(P*R)
|