No hago mucho de codificación fuera de Matlab, pero tengo necesidad de exportar el código de Matlab a otro idioma, lo más probable C. Mi código de Matlab incluye una función de histograma, histc(), que pone mis datos de entrada (que es de doble precisión, no entero) en una matriz especificada de los contenedores, para formar un histograma.

Estoy seguro de que se puede juntar un par de bucles anidados para generar un histograma de la función, pero necesito que esta función sea rápido y la memoria de luz, ya que se tendrá acceso repetidamente y con frecuencia.

Para evitar la re-inventar la rueda, alguien sabe si el lenguaje C dispone de ningún existentes función de histograma(s) disponibles para su uso, o si las personas que necesitan una cosa en general, crear ellos mismos?

Alguien conoce un algoritmo eficiente para la creación de un histograma? Pseudo-código está bien.

Gracias de antemano.

InformationsquelleAutor ggkmath | 2010-12-23

3 Comentarios

  1. 20

    El «ideal» histograma algoritmo dependerá de la variedad que desea capturar. En general, cualquier histograma algoritmo tendrá este aspecto:

    const int NSAMPLES = whatever;
    double samples[NSAMPLES] = { 1.0, 3.93, 1e30, ... }; //your data set
    const int NBUCKETS = 10; //or whatever
    int counts[NBUCKETS] = { 0 };
    for (int i = 0; i != NSAMPLES; ++i) {
        counts[TRANSFER(samples[i])]++;
    }

    donde TRANSFER() es alguna función que se asigna a las variables de entrada a un bin (0 o N bin asignación de «fuera de rango» de las aplicables).

    La exacta aplicación de TRANSFER() depende mucho de la distribución esperada de la muestra y donde usted está interesado en los detalles. Algunos enfoques comunes que he visto:

    • distribución uniforme en el intervalo [a,b] (requiere lineal de transformación)
    • distribución logarítmica de los valores enteros sin signo (mejor cuando se combina con algunos poco con los hacks para determinar rápidamente el más cercano de poder de dos o similar).

    Si usted no sabe la distribución por adelantado, entonces usted realmente no puede tener un mecanismo eficiente de reciclaje de manera efectiva: ya sea que usted tiene que adivinar (parciales o de valor informativo de los resultados) o almacenar y clasificar a la final, el agrupamiento en igualdad de tamaño de los cubos (rendimiento pobre).

    • Gracias Tom, es la función de TRANSFERENCIA que es realmente el arte de histograma generación. Mis datos podría tomar en cualquier tipo de distribución, no se conoce de antemano, y el histograma binning tendría que tener linealmente espaciados papeleras. Por lo tanto, creo que voy a necesitar para guardar los datos como viene, y encontrar los max y min al final.
    • poco con los hacks enlace es genial
  2. 12

    He escrito mi propio histograma de código en C, ya que es tan simple que ni siquiera pensé en buscar una biblioteca. Normalmente, usted sólo tiene que crear una matriz para contener el número de contenedores que se desea [num_bins = (int)(val_max - val_min + 1);], y como se encuentra cada una de las muestras se puede dividir por el número de contenedores [bin_idx = (int)((value - val_min) /bin_width);] (donde bin_width = (max-min)/num_bins) para encontrar la que pertenece y a continuación, incrementar el reciclaje de contador. Esta es una forma fácil, rápida y en un solo paso a través de los datos. No reviso mis aritmética anteriormente para los casos extremos.

    El problema puede encontrarse es que el dominio de la entrada podría no ser conocida. Tener el 100 contenedores en toda la gama de double no va a ser de mucho si todos los datos están dentro de sólo una pequeña fracción de eso. La solución es hacer un primer pase los datos para encontrar la min/max de su rango. Realmente no hay una solución rápida a este y la mayoría de las bibliotecas se pide min/max delantera.

    • Supongo que las modificaciones introducidas a un error. Asumir num_bins == 2, max == 10 y min == 0 por ejemplo, esto lleva a bin_width == 5, entonces, para calcular el bin del valor máximo que podría resultar en 10 - 0 / 5 == 2. El índice de 2 conducirá a una matriz fuera de los límites de error. Este es el problema común de la manipulación del último valor. Supongo que para enteros una solución sería el uso de bin_width = (max-min+1)/num_bins. Pero, ¿cómo manejaría usted flota?
    • 10 es en bin índice 2 si las bandejas están definidos como especificado: [0,5[; [5,10[; .... El cálculo para el límite superior del dominio podría ser mejorado para dar cuenta de esto.

Dejar respuesta

Please enter your comment!
Please enter your name here