Skip to content

Instantly share code, notes, and snippets.

@FelixLuciano
Last active December 10, 2021 20:03
Show Gist options
  • Save FelixLuciano/db9ec4235b71b92b3064a4cae54d6fdc to your computer and use it in GitHub Desktop.
Save FelixLuciano/db9ec4235b71b92b3064a4cae54d6fdc to your computer and use it in GitHub Desktop.
Aproxima valores da variável de uma equação dada condições de existência e uma igualdade dentro
import numpy as np
from scipy.optimize import root
class Aproximador:
def __init__(self, f, sigma=1E-3):
"""Aproxima valores da variável de uma equação dada condições de existência e uma igualdade dentro.
Args:
f (function): Função matemática para encontrar variáveis;
sigma (float): Margem de tolerância para operações decimais.
"""
self.f = f
self.sigma = sigma
self.decimais = int(np.log10(1 / sigma))
self.restricoes = []
def add_restricao(self, f, y):
"""Adiciona uma condição de existência á função onde `f(x) != y`
Args:
f (function): Expressão matemática de existência da função principal;
y (float): Valor de não igualdade da expressão matemática.
"""
self.restricoes.append({
"f": f,
"y": y
})
def restringe(self, x_list):
"""Filta os valores de `x` de acordo com as condições de existência.
Args:
x_list (float[]): Valores de `x` os quais serão filtradas a partr das condições de existência.
Returns:
float[]: Lista de valores de `x` que são são restringidos pelas condições de existência.
"""
if len(self.restricoes) == 0:
return x_list
else:
return np.array([x for x in x_list if not any(np.isclose(r["f"](x), r["y"], 0, self.sigma) for r in self.restricoes)])
def __get_root(self, y):
return lambda x: self.f(x) - y
def minimiza(self, y, x0, xf):
"""Obtém os valores de `x` dentro de um intervalo para os quais a função é o mais próxima de `y`.
Args:
y (float): Valor de `y` o qual deseja-se os valores de `c`;
x0 (float): Valor inicial de `x`;
xf (float): Valor final de `x`.
Returns:
float[]: Lista de valores de `x` em que `f(x)` são aproximados de `y`.
"""
x_range = np.arange(x0, xf + self.sigma, self.sigma / 10)
x_close = x_range[np.isclose(self.f(x_range), y, 0, self.sigma)]
x_roots = root(self.__get_root(y), x_close).x
x_list = x_roots[np.unique(x_roots.round(self.decimais), return_index=True)[1]]
return x_list
def calcula(self, y, x0, xf):
"""Obtém os valores de `x` dentro de um intervalo para os quais a função é o mais próxima de `y` de acordo com as condições de existência.
Args:
y (float): Valor de `y` o qual deseja-se os valores de `c`;
x0 (float): Valor inicial de `x`;
xf (float): Valor final de `x`.
Returns:
float[]: Lista de valores de `x` em que `f(x)` são aproximados de `y` de acordo com as condições de existência.
"""
return self.restringe(self.minimiza(y, x0, xf))
aprox = Aproximador(lambda B: 5 * np.sin(B / 2) - 6 * np.sin(B * 5 / 6), 1E-3)
aprox.add_restricao(lambda B: np.sin(B / 2), 0)
aprox.add_restricao(lambda B: np.sin(B * 5 / 6), 0)
aprox.calcula(0, 0, 6 * np.pi)
// [2.64208, 7.12358, 11.72597, 16.20748]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment