Skip to content

Commit

Permalink
First commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
barreiroleo committed Aug 25, 2021
0 parents commit 5665fd7
Show file tree
Hide file tree
Showing 5 changed files with 464 additions and 0 deletions.
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# Environments
/env
76 changes: 76 additions & 0 deletions bisection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import numpy as np
from functions import *


class bisector:
xinf, xsup = 0, 0
xmed, xmed_old = 0, 0
err_rel, err_obj = float('inf'), 0
iter_n, max_iter = 0, 500

def __init__(self, function, xinf, xsup, err_obj=1e-4, max_iter=500, bias=0, verbose=False, *args, **kwargs):
self.xinf , self.xsup = xinf, xsup
self.err_obj , self.max_iter = err_obj, max_iter
self.function, self.bias = function, bias
self.args , self.kwargs = args, kwargs
self.verbose = verbose

def next_iter(self):
self.iter_n += 1
self.xmed_old = self.xmed
self.xmed = (self.xinf + self.xsup) / 2
self.calc_error()

self.yinf = self.function(self.xinf, *self.args, **self.kwargs) - self.bias
self.ymed = self.function(self.xmed, *self.args, **self.kwargs) - self.bias
self.logs('iter')

if self.ymed == 0:
self.err_rel = 0
return
elif self.yinf * self.ymed < 0:
self.xsup = self.xmed
elif self.yinf * self.ymed > 0:
self.xinf = self.xmed
else:
raise Exception('Fail iter_xmed')

def calc_error(self):
self.err_rel = 100 * (self.xmed - self.xmed_old) / self.xmed
self.err_rel = abs(self.err_rel)

def run(self):
self.logs('header')
while((self.err_rel > self.err_obj) and (self.iter_n < self.max_iter)):
self.next_iter()

if self.err_rel == 0: self.logs('exact')
else: self.logs('results')
return(self.xmed)

def logs(self, item):
if self.verbose is True:
if item == 'header':
print("Iter | xinf{0:4} | xsup{0:4} | xmed{0:4} | eps{0:5} | y(xmed)".format(''))
print("{:=>60}".format(''))
if item == 'iter':
print("{:>4} | {:^8.4f} | {:^8.4f} | {:^8.4f} | {:_>8.4f} | {:^8.4f}".
format(self.iter_n, self.xinf, self.xsup, self.xmed, self.err_rel, self.ymed))
if item == 'results':
if not (self.err_rel > self.err_obj): print("Finish by eps: {:.4e}".format(self.err_rel))
if not (self.iter_n < self.max_iter): print("Finish by iter: {}".format(self.iter_n))
print("Xroot: {0}".format(self.xmed))
if item == 'exact':
print ("Exact root found: {}".format(self.xmed))


def function(tInt_perc):
frec, ampl = 1, 1
rms_unit = (np.sqrt(2) / 2) * ampl
rms_dimmer = fun_rms_simbolic(tInt_perc, frec=frec, amp=ampl) / rms_unit
return rms_dimmer


solver = bisector(function, xinf=0, xsup=100, bias=0.1, err_obj=1e-5, verbose=False)
sol = solver.run()
print("rms({:.4f}) = {:.4f}".format(sol, function(sol)))
51 changes: 51 additions & 0 deletions functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import numpy as np


def fun_Sine(t, f=1, a=1):
w = 2 * np.pi * f
return a * np.sin(w * t)


def fun_Dimmer(t, tInt_perc, f=1, a=1):
periode = 1 / f
tInt = 0.5 * periode * (tInt_perc / 100)
vt = fun_Sine(t, f, a)
vd = 0
if (0 <= t and t < tInt):
vd = 0
elif (tInt <= t and t < 0.5 * periode):
vd = vt
elif (0.5*periode <= t and t < 0.5*periode + tInt):
vd = 0
elif (0.5*periode + tInt <= t and t < periode):
vd = vt
return vd


def fun_rms_numeric(data_y):
sum_y = 0
for i in data_y:
sum_y = sum_y + i**2
rms = np.sqrt(sum_y / len(data_y))
return rms


def fun_rms_simbolic(tInt_perc, frec=1, amp=1):
periode = 1 / frec
tInt = 0.5 * periode * (tInt_perc / 100)
T1, T2 = 0, periode

def sine_integrate(t):
w = 2 * np.pi * frec
int_a = amp ** 2
int_b = t / 2
int_c = (np.sin(2*t*w) / (4*w))
sine_int = int_a * (int_b - int_c)
return sine_int

rms_a = 1 / (T2 - T1)
rms_b1 = sine_integrate(T2 / 2)
rms_b2 = sine_integrate(tInt)
rms_b = (rms_b1 - rms_b2) * 2
rms = np.sqrt(rms_a * rms_b)
return rms
117 changes: 117 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button
from scipy.optimize import bisect

from functions import *


def main():
for i in range(100+1):
print("duty([per/2] * {:>14.10f}%)= {:>6.2f}%".format(solve_tInt(i), i))

init_plot()


def gen_data(tInt_perc=50, frec=1, amp=1):
samples = 100
periode = 1 / frec
t = np.linspace(0, periode, samples)
v_dimmer = [fun_Dimmer(ti, tInt_perc, frec, amp) for ti in t]
rms_dimmer = fun_rms_simbolic(tInt_perc, frec, amp) * np.ones(samples)
return [t, v_dimmer, rms_dimmer]


def init_plot():
global fig, ax1, l1, l2
t_series, vt_series, rms_series = gen_data()
plt.ion()

fig, ax1 = plt.subplots(figsize=(6, 6))
plt.subplots_adjust(bottom=0.35, top=0.95, right=0.89, wspace=0, hspace=0)

l1, = plt.plot(t_series, vt_series)
l2, = plt.plot(t_series, rms_series)

plt.grid(True)
update_plot()
setting_sliders()
ax1.set_ylabel(r'Amplitud [v]')
secax_y = ax1.secondary_yaxis(
'right', functions=(rms_to_duty, duty_to_rms))
secax_y.set_ylabel(r'Duty [%]')
plt.show(block=True)


def update_plot(tInt_perc=50, frec=1, ampl=1):
global fig, ax1, l1, l2
t_series, vt_series, rms_series = gen_data(tInt_perc, frec, ampl)
# Plot data
l1.set_xdata(t_series), l2.set_xdata(t_series)
l1.set_ydata(vt_series), l2.set_ydata(rms_series)
# Update legend
sine_str = r'$v(t) = \mathcal{A} \mathrm{sin}(2 \omega t)$'
rms_str = "RMS: {:.5f}".format(rms_series[0])
ax1.legend([sine_str, rms_str])
# Update limits
ax1.set_xlim(np.min(0), np.max(1 / frec))
ax1.set_ylim(-ampl, ampl)


def setting_sliders():
def update_sliders(val):
update_plot(slide_tInt.val, slide_frec.val, slide_amp.val)
frec, ampl, tInt_perc = slide_frec.val, slide_amp.val, slide_tInt.val
rms_unit = (np.sqrt(2) / 2) * ampl
rms_value = fun_rms_simbolic(tInt_perc, frec=frec, amp=ampl) / rms_unit
slide_duty.set_val(rms_value * 100)

def update_slider_duty(val):
tint = solve_tInt(slide_duty.val, slide_frec.val, slide_amp.val)
slide_tInt.set_val(tint)

global ax_frec, ax_amp, ax_tInt, ax_duty, ax_solve
global slide_frec, slide_amp, slide_tInt, slide_duty, btn_solve
ax_frec = plt.axes([0.1, 0.10, 0.80, 0.03])
ax_amp = plt.axes([0.1, 0.15, 0.80, 0.03])
ax_tInt = plt.axes([0.1, 0.20, 0.80, 0.03])
ax_duty = plt.axes([0.1, 0.25, 0.6, 0.03])
ax_solve = plt.axes([0.8, 0.25, 0.1, 0.03])
slide_frec = Slider(ax_frec, 'Frec', 1.0, 50, valinit=1, valstep=1)
slide_amp = Slider(ax_amp, 'Amp', 1.0, 311, valinit=1, valstep=1)
slide_tInt = Slider(ax_tInt, '%Int', 0.0, 100, valinit=50, valstep=1)
slide_duty = Slider(ax_duty, '%Duty', 0.0, 100, valinit=50, valstep=1)
btn_solve = Button(ax_solve, 'Solve')
slide_frec.on_changed(update_sliders)
slide_amp.on_changed(update_sliders)
slide_tInt.on_changed(update_sliders)
# slide_duty.on_changed(solve_tInt)
btn_solve.on_clicked(update_slider_duty)


def rms_to_duty(x):
vrms = x
# vrms = fun_rms_simbolic(slide_tInt.val, slide_frec.val, slide_amp.val)
vrms_max = np.sqrt(2) * 0.5 * slide_amp.val
vrms_duty = 100 * vrms / vrms_max
return vrms_duty


def duty_to_rms(x):
vrms_duty = x
vrms_max = np.sqrt(2) * 0.5 * slide_amp.val
vrms = vrms_duty * vrms_max / 100
return vrms


def solve_tInt(duty, frec=1, amp=1):
def function(tInt_perc, bias=0):
rms_unit = (np.sqrt(2) / 2) * amp
rms_value = fun_rms_simbolic(tInt_perc, frec=frec, amp=amp) / rms_unit
return rms_value - bias
root = bisect(function, 0, 100, args=(duty / 100))
return root


if __name__ == "__main__":
main()
206 changes: 206 additions & 0 deletions rms_vs_tinterrupt.ipynb

Large diffs are not rendered by default.

0 comments on commit 5665fd7

Please sign in to comment.