ylabel xlabel tag matlab

matlab - xlabel - Devolver Elemento Único con una Tolerancia



xlabel latex matlab (7)

Con R2015a, esta pregunta finalmente tiene una respuesta simple (vea mi otra respuesta a esta pregunta para más detalles). Para las versiones anteriores a R2015a, existe una función integrada (no documentada): _mergesimpts . Una conjetura segura sobre la composición del nombre es "fusionar puntos similares".

La función se llama con la siguiente sintaxis:

xMerged = builtin(''_mergesimpts'',x,tol,[type])

La matriz de datos x es N-by-D , donde N es el número de puntos y D es el número de dimensiones. Las tolerancias para cada dimensión se especifican mediante un vector de fila de elemento D , tol . El type argumento de entrada opcional es una cadena ( ''first'' (predeterminado) o ''average'' ) que indica cómo combinar elementos similares.

La salida xMerged será M-by-D , donde M<=N Está ordenado .

Ejemplos, datos 1D :

>> x = [1; 1.1; 1.05]; % elements need not be sorted >> builtin(''_mergesimpts'',x,eps) % but the output is sorted ans = 1.0000 1.0500 1.1000

Tipos de fusión:

>> builtin(''_mergesimpts'',x,0.1,''first'') ans = 1.0000 % first of [1, 1.05] since abs(1 - 1.05) < 0.1 1.1000 >> builtin(''_mergesimpts'',x,0.1,''average'') ans = 1.0250 % average of [1, 1.05] 1.1000 >> builtin(''_mergesimpts'',x,0.2,''average'') ans = 1.0500 % average of [1, 1.1, 1.05]

Ejemplos, datos 2D :

>> x = [1 2; 1.06 2; 1.1 2; 1.1 2.03] x = 1.0000 2.0000 1.0600 2.0000 1.1000 2.0000 1.1000 2.0300

Todos los puntos 2D exclusivos de la precisión de la máquina:

>> xMerged = builtin(''_mergesimpts'',x,[eps eps],''first'') xMerged = 1.0000 2.0000 1.0600 2.0000 1.1000 2.0000 1.1000 2.0300

Fusión basada en la tolerancia de la segunda dimensión:

>> xMerged = builtin(''_mergesimpts'',x,[eps 0.1],''first'') xMerged = 1.0000 2.0000 1.0600 2.0000 1.1000 2.0000 % first of rows 3 and 4 >> xMerged = builtin(''_mergesimpts'',x,[eps 0.1],''average'') xMerged = 1.0000 2.0000 1.0600 2.0000 1.1000 2.0150 % average of rows 3 and 4

Fusión basada en la tolerancia de primera dimensión:

>> xMerged = builtin(''_mergesimpts'',x,[0.2 eps],''average'') xMerged = 1.0533 2.0000 % average of rows 1 to 3 1.1000 2.0300 >> xMerged = builtin(''_mergesimpts'',x,[0.05 eps],''average'') xMerged = 1.0000 2.0000 1.0800 2.0000 % average of rows 2 and 3 1.1000 2.0300 % row 4 not merged because of second dimension

Fusión basada en ambas dimensiones:

>> xMerged = builtin(''_mergesimpts'',x,[0.05 .1],''average'') xMerged = 1.0000 2.0000 1.0867 2.0100 % average of rows 2 to 4

En Matlab, existe este comando unique que devuelve las filas únicas en una matriz. Este es un comando muy útil.

Pero el problema es que no puedo asignarle tolerancia: con doble precisión, siempre tenemos que comparar dos elementos con una precisión. ¿Hay un comando incorporado que devuelve elementos únicos, dentro de una cierta tolerancia?


Este es un problema dificil. Incluso diría que es imposible de resolver en general, debido a lo que llamaría el problema de la transitividad. Supongamos que tenemos tres elementos en un conjunto, {A, B, C}. Definiré que una función simple es SimilarTo, de modo que isMilarTo (A, B) devolverá un resultado verdadero si las dos entradas están dentro de una tolerancia específica entre sí. (Tenga en cuenta que todo lo que diré aquí es significativo tanto en una dimensión como en múltiples dimensiones). Por lo tanto, si se sabe que dos números son "similares" entre sí, elegiremos agruparlos.

Entonces, supongamos que tenemos valores {A, B, C} de modo que isSimilarTo (A, B) sea verdadero, y que sea símilarTo (B, C) también sea verdadero. ¿Deberíamos decidir agrupar a los tres juntos, a pesar de que es similar a (A, C) es falso?

Peor aún, pasar a dos dimensiones. Comience con k puntos igualmente espaciados alrededor del perímetro de un círculo. Suponga que la tolerancia se elige de tal manera que cualquier punto se encuentre dentro de la tolerancia especificada de sus vecinos inmediatos, pero no a ningún otro punto. ¿Cómo elegiría resolver qué puntos son "únicos" en el entorno?

Afirmaré que este problema de intransitividad hace que el problema de agrupación no sea posible resolver, al menos no perfectamente, y ciertamente no de manera eficiente. Tal vez uno podría intentar un enfoque basado en un estilo de agregación k-medias. Pero esto también será bastante ineficiente, por lo general, este enfoque debe saber de antemano el número de grupos que hay que buscar.

Dicho esto, seguiría ofreciendo un compromiso, algo que a veces puede funcionar dentro de límites. El truco se encuentra en Consolidator , tal como se encuentra en el intercambio de archivos de Matlab Central. Mi enfoque fue redondear efectivamente las entradas dentro de la tolerancia especificada. Una vez hecho esto, una combinación de exclusivo y acumulación permite que la agregación se realice de manera eficiente, incluso para grandes conjuntos de datos en una o varias dimensiones.

Este es un enfoque razonable cuando la tolerancia es lo suficientemente grande como para que cuando varios datos se agrupan, se redondearán al mismo valor, con errores ocasionales cometidos por el paso de redondeo.


Esto es difícil de definir bien, suponga que tiene una tolerancia de 1. Entonces, ¿cuál sería el resultado de [1; 2; 3; 4] [1; 2; 3; 4] [1; 2; 3; 4] ?

Cuando tienes varias columnas, una definición podría ser aún más desafiante.

Sin embargo, si está más preocupado por los problemas de redondeo, puede resolver la mayoría de ellos mediante uno de estos dos enfoques:

  1. Redondea todos los números (considerando tu tolerancia) y luego usa un unique
  2. Comience con la fila superior como su conjunto único, use ismemberf para determinar si cada nueva fila es única y, de ser así, agréguela a su conjunto único.

El primer enfoque tiene la debilidad de que 0.499999999 y 0.500000000 pueden no verse como duplicados. Mientras que el segundo enfoque tiene la debilidad de que el orden de su entrada importa.


Me he encontrado con este problema antes. El truco es primero ordenar los datos y luego usar la función diff para encontrar la diferencia entre cada elemento. Luego compara cuando esa diferencia es menor que tu tolerancia. Este es el código que uso:

tol = 0.001 [Y I] = sort(items(:)); uni_mask = diff([0; Y]) > tol; %if you just want the unique items: uni_items = Y(uni_mask); %in sorted order uni_items = items(I(uni_mask)); % in the original order

Esto no se ocupa de la "deriva" ... así que algo como 0: 0.00001: 100 en realidad devolvería un valor único.

Si desea algo que pueda manejar el "desvío", entonces usaría histc, pero necesita hacer algún tipo de estimación aproximada sobre cuántos artículos está dispuesto a tener.

NUM = round(numel(items) / 10); % a rough guess bins = linspace(min(items), max(items), NUM); counts = histc(items, bins); unit_items = bins(counts > 0);

Por cierto: escribí esto en un editor de texto alejado de matlab, por lo que puede haber algunos errores tipográficos estúpidos o por uno de error.

Espero que ayude


Me quedé atascado el otro día con un MatLab 2010 , así que, sin ronda (X, n), no _mergesimpts (al menos no pude hacer que funcionara), así que, una solución simple que funciona (al menos para mis datos):

Usando la tolerancia predeterminada de rat :

unique(cellstr(rat(x)))

Otra tolerancia:

unique(cellstr(rat(x,tol)))


No hay tal función que yo sepa. Un aspecto delicado es que si su tolerancia es, por ejemplo, 1e-10, y tiene un vector con valores espaciados igualmente en 9e-11, la primera y la tercera entrada no son las mismas, pero la primera es la misma que el segundo, y el segundo es el mismo que el tercero, entonces, ¿cuántos "únicos" hay?

Una forma de resolver el problema es redondear sus valores a la precisión deseada y luego ejecutarlos de forma única. Puede hacerlo usando round2 ( http://www.mathworks.com/matlabcentral/fileexchange/4261-round2 ), o usando la siguiente forma simple:

r = rand(100,1); % some random data roundedData = round(r*1e6)/1e6; % round to 1e-6 uniqueValues = unique(roundedData);

También puede hacerlo usando el comando hist, siempre que la precisión no sea demasiado alta:

r = rand(100,1); % create 100 random values between 0 and 1 grid = 0:0.001:1; % creates a vector of uniquely spaced values counts = hist(r,grid); % now you know for each element in ''grid'' how many values there are uniqueValues = grid(counts>0); % and these are the uniques


A partir de R2015a , finalmente hay una función para hacer esto, uniquetol ( antes de R2015a , vea mi otra respuesta ):

uniquetol Conjunto único dentro de una tolerancia.

uniquetol es similar a unique . Mientras que unique realiza comparaciones exactas, uniquetol realiza comparaciones utilizando una tolerancia.

La sintaxis es sencilla:

C = uniquetol(A,TOL) devuelve los valores únicos en A usando la tolerancia TOL .

Como son las semánticas:

Cada valor de C está dentro de la tolerancia de un valor de A , pero no hay dos elementos en C estén dentro de la tolerancia de uno a otro. C se ordena en orden ascendente. Dos valores u y v están dentro de la tolerancia si:
abs(uv) <= TOL*max(A(:),[],1)

También puede operar " ByRows ", y la tolerancia se puede escalar mediante una entrada " DataScale " en lugar de por el valor máximo en los datos de entrada.

Pero hay una nota importante sobre la singularidad de las soluciones:

Puede haber múltiples salidas de C válidas que cumplan la condición, "no hay dos elementos en C estén dentro de la tolerancia de cada uno". Por ejemplo, el intercambio de columnas en A puede dar como resultado que se devuelva una solución diferente, ya que las entradas ordenan lexicográficamente las entradas. Otro resultado es que uniquetol(-A,TOL) puede no dar los mismos resultados que -uniquetol(A,TOL) .

También hay una nueva función que ismembertol se relaciona con ismember de la misma manera que antes.