Как рассчитать статистический режим в Processing / Arduino - PullRequest
3 голосов
/ 26 октября 2011

Я учитель дизайна, пытаюсь помочь студенту в решении задач программирования, поэтому я пишу для удовольствия, но я не эксперт.

Ей нужно найти режим (наиболее частое значение) в наборе данных, построенном с использованием данных от датчиков, подключенных к Arduino, а затем активировать некоторые функции на основе результата.

Мы выяснили большую часть, за исключением того, как рассчитать режим в Arduino. Я нашел сообщение Получить элемент с наибольшим вхождением в массиве , который решает проблему в JavaScript, но я не смог его "портировать".

Ответы [ 2 ]

2 голосов
/ 26 октября 2011

Я использовал HashMap для замены экземпляра динамического объекта js {} и плавающих объектов, но порт @ weberik выглядит более простым.

void setup() {
    int numValues = 10;
    float[] values = new float[numValues]; //Create an empty sample array
    for(int i = 0 ; i < numValues ; i++) values[i] = random(0.0,100.0); //Populate it with random values.
    println("mode: " + mode(values));
}

float mode(float[] source) {
    if (source.length == 0)
        return -1;
    HashMap<Float,Integer> modeMap = new HashMap<Float,Integer>();
    float result = source[0];
    int maxCount = 1;
    for (int i = 0; i < source.length; i++) {
        float el = source[i];
        if (modeMap.get(el) == null)
            modeMap.put(el,1);
        else
            modeMap.put(el,modeMap.get(el)+1);
        if (modeMap.get(el) > maxCount) {
            result = el;
            maxCount = modeMap.get(el);
        }
    }
    return result;
}

Вы упомянули вход датчикаТаким образом, я предполагаю, что данные будут отбираться непрерывно, чтобы значения могли сохраняться с определенным интервалом, а затем отправляться в «Обработка» для режима.Просто дикая догадка, но разве она не хочет немного усреднить / сгладить показания датчика?Если это так, она может кэшировать несколько значений (скажем, 10) в массиве в Arduino и получать среднее значение каждый раз, когда добавляются новые значения:

int vals[10]; //Array to store caches values.

void setup() {
    Serial.begin(9600);
    for (int i=0 ; i < 10 ; i++) 
        vals[i] = 0; //Init with zeroes
}

void loop() {
    delay(100);
    int currentVal = average(analogRead(0));
    //Serial.print(currentVal,BYTE);
    Serial.println(currentVal);
}

int average(int newVal) {
    int total = 0; //Used to store the addition of all currently cached values
    for(int i = 9; i > 0; i--) { //Loop backwards from the one before last to 0
        vals[i] = vals[i-1]; //Overwrite the prev. value with the current(shift values in array by 1)
        total += vals[i]; //Add to total
    }
    vals[0] = newVal; //Add the newest value at the start of the array
    total += vals[0]; //Add that to the total as well
    return total *= .1; //Get the average (for 10 elemnts) same as total /= 10, but multiplication is faster than division.
}
2 голосов
/ 26 октября 2011

Я перенес код из вашего связанного поста в Обработка , но он ограничен int массивами. Я надеюсь, что это помогает.

void setup()
{
    int[] numbers = {1, 2, 3, 2, 1, 1, 1, 3, 4, 5, 2};
    println(mode(numbers));
}


int mode(int[] array) {
    int[] modeMap = new int [array.length];
    int maxEl = array[0];
    int maxCount = 1;

    for (int i = 0; i < array.length; i++) {
        int el = array[i];
        if (modeMap[el] == 0) {
            modeMap[el] = 1;
        }
        else {
            modeMap[el]++;
        }

        if (modeMap[el] > maxCount) {
            maxEl = el;
            maxCount = modeMap[el];
        }
    }
    return maxEl;
}
...