4.2 Rssi vs distancia. Linealiza – función Python

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