реклама на сайте
подробности

 
 
> вычисление медианы массива (или произвольной моды), stm32f4 + STL
klen
сообщение Jul 28 2013, 16:50
Сообщение #1


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



Здравствуйте.
Пришлось пововырятся данным сабжем, решил поделится результатом чтоб в случае необходимости ув. коллеги могли рассмотреть решение задачи предлагаемым способом.

1. Итак, была проблема со съемом сигнала с потенциометра "крутилка рукой"- заказчик не захотел энкодеры ;( . в силу независящих от меня причин оказалось на резистеоре определенное количество шума в виде импульсных выбросов. попросили их "вырезать". проц - STM32F405RGT 168MHz
2. После анализа хар-к помехи пришла мысль выдернуть ее медианным фильтром.
3. дока по быстрому вычислению мод масивом прилагается http://klen.org/Files/Dosc/math/median.pdf
4. Как всегда захотелось решить задачу в общем виде. поэтому был пременен код STL в реализации GCC 4.9.0.
был нарисован шаблонный класс который реализует фифо и вычисляет текущую медиану, оформлено в виде заголовка С++:

CODE
/*
* moda.h
*
* Created on: 24 июля 2013 г.
* Author: klen
* URL: klen.org
*/

#ifndef __MODA_H__
#define __MODA_H__


#include <vector>
#include <algorithm>

//---------------------------------------------------------------------------------------------
template <typename T> class TModaFilterContainer
{
private:
protected:
public:

std::vector<T> vals; // входная последовательность
std::vector<T> gist; // копия входной последовательности для сортировки и поиска моды

TModaFilterContainer () {};
TModaFilterContainer (size_t size) { vals.resize(size); };
~TModaFilterContainer() {};
void Add(T val) {vals.push_front(val); }
void Remove () {vals.pop_back(); }
void Clear() { vals.clear(); }
void Resize(size_t size) {vals.resize(size); }
void Update(T val) { vals.pop_back(); vals.insert(vals.begin(), val); }
};

//---------------------------------------------------------------------------
template <typename T> class TMedianFilterSort : public TModaFilterContainer<T>
{
public:
TMedianFilterSort():TModaFilterContainer<T>() {};
TMedianFilterSort(size_t size):TModaFilterContainer<T>(size) {};
~TMedianFilterSort() {};

T Find()
{
this->gist = this->vals;
div_t divresult;
divresult = div( this->gist.size() , 2 );
size_t n = divresult.quot;
sort(this->gist.begin(), this->gist.end());
if ( divresult.rem )
return this->vals[n];
else
return (this->vals[n-1] + this->vals[n]) / static_cast<T>(2);
}

};
//--------------------------------------------------------------------------
template <typename T> class TMedianFilterNth : public TModaFilterContainer<T>
{
public:
TMedianFilterNth():TModaFilterContainer<T>() {};
TMedianFilterNth(size_t size):TModaFilterContainer<T>(size) {};
~TMedianFilterNth() {};

T Find()
{
this->gist = this->vals;
size_t n = this->gist.size() / 2;
nth_element(this->gist.begin(), this->gist.begin() + n, this->gist.end());
return this->gist[n];
}
};

// EXAMPLE
#if 0

#include "median.h"

typedef TMedianFilterNth<int16_t> median_t;
volatile int16_t mediana;


median_t m(8);

mediana = m.Find();

m.Update(8);
mediana = m.Find();
m.Update(9);
mediana = m.Find();
m.Update(10);
mediana = m.Find();
m.Update(8);
mediana = m.Find();
m.Update(10);
mediana = m.Find();
m.Update(11);
mediana = m.Find();
m.Update(0);
mediana = m.Find();
m.Update(1);
mediana = m.Find();
m.Update(2);
mediana = m.Find();
m.Clear();

// результат работы:

0 0 0 0 0 0 0 0
mediana:0
8 0 0 0 0 0 0 0
mediana:0
9 8 0 0 0 0 0 0
mediana:0
10 9 8 0 0 0 0 0
mediana:0
8 10 9 8 0 0 0 0
mediana:8
10 8 10 9 8 0 0 0
mediana:8
11 10 8 10 9 8 0 0
mediana:9
0 11 10 8 10 9 8 0
mediana:9
1 0 11 10 8 10 9 8
mediana:9
2 1 0 11 10 8 10 9
mediana:9

#endif


#endif /* __MODA_H__ */



результаты по быстродействию при спецификации шаблона типом uint16_t на STM32F405RGT 168MHz :
Код
размер буфера                                    добавления элемента в фифо+ вычисление медианы(максимальное значение)
4                                                                                             4,2мкс
16                                                                                             10мкс
32                                                                                            16мкс
128                                                                                           56мкс

размер кода потянутого шаблонами и алгоритмами ( класс vector + алгоритм thh ) ~1100 байт

5. можно вектор заменить на двухсвязанную очередь deque - по идее должно работать быстрее при добавлении елемента. можно ручками чтоб ваще быстро было - но это время разработки!
6. компилял компиллером из своей сборки http://electronix.ru/forum/index.php?showt...0&start=870
7. это должно работать на любом вменяемом С++ компиллере и наличии стандартной библиотеки шаблонов STL

надюсь с пользой запостил.

Сообщение отредактировал IgorKossak - Aug 1 2013, 06:36
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
KRS
сообщение Jul 31 2013, 11:22
Сообщение #2


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



А ведь если фильтр скользящий, на этапе добавление очередного измерения, уже есть отсортированный массив.
Но из него удаляется один элемент, при этом он остается отсортированным, надо просто вставить новый на нужное место. Ту сортировка вставками будет самой быстрой.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jul 31 2013, 14:10
Сообщение #3


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(KRS @ Jul 31 2013, 15:22) *
А ведь если фильтр скользящий, на этапе добавление очередного измерения, уже есть отсортированный массив.
Но из него удаляется один элемент, при этом он остается отсортированным, надо просто вставить новый на нужное место. Ту сортировка вставками будет самой быстрой.
Это понятно, но вы посмотрите на размер кода такого алгоритма 'Ekstrom'.
Я это тоже изобретал, но отверг по причинам невпихуемости результирующей прошивки.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- klen   вычисление медианы массива (или произвольной моды)   Jul 28 2013, 16:50
- - Xenia   Плохой алгоритм - через полную сортировку медиану ...   Jul 28 2013, 18:33
|- - klen   Цитата(Xenia @ Jul 28 2013, 22:33) Плохой...   Jul 28 2013, 21:12
||- - Xenia   Цитата(klen @ Jul 29 2013, 01:12) я сог...   Jul 28 2013, 21:36
||- - klen   Цитата(Xenia @ Jul 29 2013, 01:36) Было б...   Jul 28 2013, 22:09
||- - demiurg_spb   А вот мой боевой вариант для uint16_t данных. Кодs...   Jul 29 2013, 06:58
|- - neiver   Цитата(Xenia @ Jul 28 2013, 22:33) Плохой...   Jul 30 2013, 13:15
|- - AlexandrY   Цитата(Xenia @ Jul 28 2013, 21:33) P.P.S....   Jul 30 2013, 16:03
|- - Xenia   Цитата(AlexandrY @ Jul 30 2013, 20:03) Вы...   Jul 30 2013, 16:35
|- - demiurg_spb   Цитата(Xenia @ Jul 30 2013, 20:35) Обычно...   Jul 31 2013, 07:25
|- - Tanya   Цитата(demiurg_spb @ Jul 31 2013, 11:25) ...   Jul 31 2013, 08:41
||- - demiurg_spb   Цитата(Tanya @ Jul 31 2013, 12:41) Кроме ...   Jul 31 2013, 10:07
||- - Tanya   Цитата(demiurg_spb @ Jul 31 2013, 14:07) ...   Jul 31 2013, 10:59
||- - demiurg_spb   Цитата(Tanya @ Jul 31 2013, 14:59) Не все...   Jul 31 2013, 11:06
||- - Tanya   Цитата(demiurg_spb @ Jul 31 2013, 15:06) ...   Jul 31 2013, 12:06
||- - Axel   Цитата(Tanya @ Jul 31 2013, 15:06) Недост...   Jul 31 2013, 12:30
|- - Xenia   Цитата(demiurg_spb @ Jul 31 2013, 11:25) ...   Jul 31 2013, 11:50
- - AlexandrY   Цитата(klen @ Jul 28 2013, 19:50) результ...   Jul 28 2013, 19:01
- - Forger   Я для таких целей использую фильтр - скользящее ср...   Jul 28 2013, 19:49
|- - AlexandrY   Цитата(Forger @ Jul 28 2013, 22:49) Я для...   Jul 28 2013, 20:29
- - Golikov A.   а как насчет экспоненциального фильтра? Быстрый, б...   Jul 29 2013, 13:29
- - RabidRabbit   По моему личному представлению всяческие скользящи...   Jul 29 2013, 14:18
- - neiver   Ура мерение длинной скоростью кода!!! ...   Jul 30 2013, 07:02
- - Altemir   Добавлю свои 5 копеек. Со времён LPC2132 использую...   Jul 30 2013, 11:43
- - Axel   Мне тоже стало интересно... Попробовал фильтр Ekst...   Jul 31 2013, 05:02
- - AlexandrY   Ну что, пришло время подвести некоторые итоги. ...   Jul 31 2013, 13:14
|- - KRS   Цитата(AlexandrY @ Jul 31 2013, 17:14) Ка...   Jul 31 2013, 14:19
|- - demiurg_spb   Цитата(KRS @ Jul 31 2013, 18:19) Но как в...   Jul 31 2013, 14:28
|- - Tanya   Цитата(KRS @ Jul 31 2013, 18:19) Но как в...   Jul 31 2013, 16:04
|- - AlexandrY   Цитата(Tanya @ Jul 31 2013, 19:04) ...   Aug 1 2013, 07:45
|- - Tanya   Цитата(AlexandrY @ Aug 1 2013, 11:45) Гов...   Aug 1 2013, 08:13
|- - AlexandrY   Цитата(Tanya @ Aug 1 2013, 11:13) Какой и...   Aug 1 2013, 09:09
|- - demiurg_spb   Ещё можно попробовать сортировать пузырём, но не в...   Aug 1 2013, 09:17
|- - Tanya   Цитата(AlexandrY @ Aug 1 2013, 13:09) Мы ...   Aug 1 2013, 09:44
||- - AlexandrY   Цитата(Tanya @ Aug 1 2013, 12:44) Может.....   Aug 1 2013, 10:23
|- - neiver   Цитата(AlexandrY @ Aug 1 2013, 13:09) Алг...   Aug 1 2013, 10:20
||- - AlexandrY   Цитата(neiver @ Aug 1 2013, 13:20) Кстати...   Aug 1 2013, 10:54
||- - Altemir   Цитата(AlexandrY @ Aug 1 2013, 14:54) Да,...   Aug 1 2013, 11:09
||- - AlexandrY   Цитата(Altemir @ Aug 1 2013, 14:09) Упс. ...   Aug 1 2013, 11:22
|- - Altemir   AlexandrY Могу скромно попросить на той же платфор...   Aug 1 2013, 10:36
- - Altemir   AlexandrY "Number of samplles" - это дли...   Jul 31 2013, 14:03
|- - AlexandrY   Цитата(Altemir @ Jul 31 2013, 17:03) Alex...   Jul 31 2013, 14:10
- - KRS   Для определенных измерений его еще можно улучшить,...   Jul 31 2013, 14:37
- - Altemir   AlexandrY Огромное спасибо! Как и ожидал - у м...   Aug 1 2013, 11:24
- - VAI   Я опоздал, все результаты посчитаны, да и алгоритм...   Aug 1 2013, 18:45
|- - AlexandrY   Цитата(VAI @ Aug 1 2013, 21:45) ... и выл...   Aug 5 2013, 08:18
- - VAI   Херовый у меня алгоритм.. :-(   Aug 5 2013, 11:59
- - p_v   Тема старая, но очень годная. Спасибо за тесты, оч...   Aug 1 2018, 16:07
- - p_v   https://pastebin.com/xpLbyWN6 - двухпроходный вари...   Aug 3 2018, 15:16


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 29th July 2025 - 22:55
Рейтинг@Mail.ru


Страница сгенерированна за 0.01457 секунд с 7
ELECTRONIX ©2004-2016