Para el procesamiento de los datos se incorpora una función a girni_lora_libreria para realizar la linealización por mínimos cuadrados.
linealiza_lstsq(xi,yi,digitos = 3)
La función se encarga de convertir el eje x en log10(x), asi como construir las ecuaciones en la forma numérica lambda, latex y un diccionario con los parámetros de la ecuación.
Datos de ingreso
Los datos de ingreso son xi y yi para cada eje, la variable dígitos establece los decimales a usar en la expresión en formato latex.
Datos de Salida
El resultado es un diccionario con los intervalos de los valores obtenidos para cada eje, la pendiente de la recta, el |error| promedio, la desviación estándar error_std, la ecuación en formato latex.
unaecuacion = {'alpha' : alpha, 'beta' : beta, 'eq_latex': fdtxt0, 'intervalox' : [np.min(xi),np.max(xi)], 'error_medio': dyi0mean, 'error_std' : dyi0std, 'eqg_latex' : grtxt0, 'intervaloy' : [np.min(yi),np.max(yi)], 'errorx_medio': dxi0mean, 'errorx_std' : dxi0std, }
El resultado se puede escribir en un archivo en formato json. La ecuación se recupera desde el archivo con lo que se puede volver a construir la función en la lambda para evaluación numérica.
Procedimiento
Se desarrolla principalmente usando la función numpy.linalg.lstsq.
La relación rssi vs distancia usa log10(xi), por lo que se incluye esta operación antes de aplicar mínimos cuadrados.
Obtenidos los parámetros, se da el formato de la expresión acorde al modelo básico de pérdidas en espacio libre en latex para mostrar como etiqueta en las gráficas.
RSSI(d) = -10 \alpha \log_{10} (d) + P_{0}La función se usa para cada baliza, y en varios segmentos, para observar los posibles resultados, también se incorporan los valores de errores,
Algoritmo en Python
def linealiza_lstsq(xi,yi,digitos = 3): ''' usa minimos cuadrados para entregar la ecuacion digitos: usados en expresion latex ''' unaecuacion = {} # Eje x en log10() xilog = np.log10(xi) n = len(xi) # mínimos cuadrados (least square), # distancia vs medida A = np.vstack([xilog, np.ones(n)]).T [m0, b0] = np.linalg.lstsq(A, yi, rcond=None)[0] alpha = -m0/10 beta = b0 # ecuaciones expresion rssi(d) fdist0 = lambda d: -10*alpha*(np.log10(d))+beta fdtxt0 = r'$ rssi = -10(' + str(np.round(alpha,digitos)) fdtxt0 = fdtxt0 + ')log_{10}(d)+(' fdtxt0 = fdtxt0 + str(np.round(beta,digitos))+') $' # Errores respecto a rssi(d) yi0 = fdist0(xi) dyi0 = yi - yi0 dyi0mean = np.mean(np.abs(dyi0)) dyi0std = np.std(dyi0, dtype=np.float64) # ecuaciones expresion d(rssi) grssi0 = lambda rssi: 10**((beta-rssi)/(10*alpha)) grtxt0 = r"$ d = 10^{(" + str(np.round(beta,digitos)) + ' - ' grtxt0 = grtxt0 + 'rssi)/' + '(10('+str(np.round(alpha,digitos))+'))} $' # Errores respecto a rssi(d) xi0 = grssi0(yi) dxi0 = xi - xi0 dxi0mean = np.mean(np.abs(dxi0)) dxi0std = np.std(dxi0, dtype=np.float64) unaecuacion = {'alpha' : alpha, 'beta' : beta, 'eq_latex': fdtxt0, 'intervalox' : [np.min(xi),np.max(xi)], 'error_medio': dyi0mean, 'error_std' : dyi0std, 'eqg_latex' : grtxt0, 'intervaloy' : [np.min(yi),np.max(yi)], 'errorx_medio': dxi0mean, 'errorx_std' : dxi0std, } return(unaecuacion)
Referencias:
Burden R, Faires J, Burden A, Análisis numérico, Décima Edición 8.1 p370.
Chapra C, Canale R. Métodos numéricos para ingenieros, Quinta edición 17.1.2 p469.
Numpy org. Least Square function. numpy.linalg.lstsq
Mínimos cuadrados. https://es.wikipedia.org/wiki/M%C3%ADnimos_cuadrados