Название: Аппроксимация Отправлено: Igors от Ноябрь 25, 2012, 17:35 Добрый день
Дано: на вход поступают точки одна за одной (напр QPointF). Гарантируется что x каждой новой точки больше предыдущей (напр x - время). Нужно: используя заданный пользователем параметр "точность", либо добавить новую точку в выходной контейнер, либо откорректировать предыдущую сохраненную. Цель: аппроксимировать исходный график небольшим числом отрезков с заданной точностью Спасибо Название: Re: Аппроксимация Отправлено: Akon от Ноябрь 25, 2012, 20:22 А в чем конкретно (формула) выражается точность аппроксимации?
Название: Re: Аппроксимация Отправлено: ssoft от Ноябрь 26, 2012, 08:43 Не все условия задачи указаны.
Как конкретно нужно аппроксимировать. - линейно - кусочно-линейно - сплайнами - полиномами - и т.д. - др. Можно брать любой базис и использовать метод минимизации среднеквадратичного отклонения. Можно использовать методы фильтрации, раскладывать в ряд и отсекать лишние члены ряда. Очень много различных способов, поэтому нужно начать с полной постановки задачи. Название: Re: Аппроксимация Отправлено: Disa от Ноябрь 26, 2012, 09:53 Доброе утро.
Цитировать А в чем конкретно (формула) выражается точность аппроксимации? Если для нахождения минимума этой функции использовать метод градиентного спуска, то это не так важно. (итоговая формулуа, что для МНК с полиномом, что для сигмоиды (например) одинаковая) y = h(x), h - гипотеза (например, h = t0 + t1x + t2x^2 + .... tnx^n) минимизируем J(t) = 1/m СУММ(1..m)(g(h(x), y)), где g(h) - функция точности (cost function), m - число точек. Берем метод градиентного спуска: repeat { t0 = t0 - alpha dJ(t) / d(t0) t1 = t1 - alpha dJ(t) / d(t1) ... tn = tn - ... } (dJ(t) / d(tn) - частная производная J(t) по tn, alpha - параметр метода) Дальше в зависимости от вида гипотезы и функции цены (точности) можно делать различные оптимизации и изменять или заменять метод градиентного спуска, чем-то другим (решая СЛАУ, просто перемножаю матрицы по формулам, в лоб пересчитывать производные и прочее) Название: Re: Аппроксимация Отправлено: ssoft от Ноябрь 26, 2012, 10:29 Я, наверное, понял, что имелось ввиду.
Скорее всего нужна не аппроксимация, а загрубление. В этом случае могу предложить маршевый геометрический алгоритм загрубления данных. К сожалению не могу найти код, но суть простая. Управление "точностью" несколькими параметрами - угол, отклонение и длина. 1. Берем точку p0. Строим векторы к следующей p1 и последующей p2. 2. Если дистанция от точки (p0, p1) больше заданной, помечаем точку p1, как используемую, делаем ее текущей (заменяем p0 на p1, p1 на p2, p2 на p3) и переходим к 1. 3. Если угол между векторами (p0, p2) (p0, p1) больше заданного, помечаем точку p1, как используемую, делаем ее текущей и переходим к пункту 1. 4. Если отклонение точки p1 до линии (p0,p2) больше заданной, помечаем точку p1, как используемую, делаем ее текущей и переходим к 1. 5 ... любые другие критерии, аналогично предыдущим трем пунктам. 6. Игнорируем точку p1, заменяем p1 на p2, p2 на p3. Переходим к 1. До тех пор пока не кончатся точки. Название: Re: Аппроксимация Отправлено: Igors от Ноябрь 26, 2012, 13:56 А в чем конкретно (формула) выражается точность аппроксимации? Было бы конечно прекрасно если бы кто-то давал формулы, и наше дело сводилось к их реализации. Но увы, этого почему-то не происходит :)Я, наверное, понял, что имелось ввиду. А "загрубление" это уже не аппроксимация? :) Ладно, бог с ними, терминами, по сути совершенно верно. Скорость здесь слишком критична, нет возможности даже накопить все исходные, не говоря уже о градиенте, гипотезе, МНК и.т.п. Чем меньше выходной контейнер - тем лучше т.к. он сохраняется, грубо говоря, для каждого пикселя Скорее всего нужна не аппроксимация, а загрубление. В этом случае могу предложить маршевый геометрический алгоритм загрубления данных. Это первое что приходит в голову. но эта схема не ловит плавный переход. Допустим на каждом шаге угол меньше критического и ф-ция монотонно убывает (или возрастает). Тогда вектор (p0, p1) будет "разворачивться" по направлению роста. Напр на шаге 100 мы получим вектор (p0. p100), 98 точек выброшено - гуд. Но угол между (p0, p100) и (p0, p2) может быть ого-го. Залатать это "длиной" - неясно как. К сожалению не могу найти код, но суть простая. Управление "точностью" несколькими параметрами - угол, отклонение и длина. 1. Берем точку p0. Строим векторы к следующей p1 и последующей p2. 2. Если дистанция от точки (p0, p1) больше заданной, помечаем точку p1, как используемую, делаем ее текущей (заменяем p0 на p1, p1 на p2, p2 на p3) и переходим к 1. 3. Если угол между векторами (p0, p2) (p0, p1) больше заданного, помечаем точку p1, как используемую, делаем ее текущей и переходим к пункту 1. 4. Если отклонение точки p1 до линии (p0,p2) больше заданной, помечаем точку p1, как используемую, делаем ее текущей и переходим к 1. 5 ... любые другие критерии, аналогично предыдущим трем пунктам. 6. Игнорируем точку p1, заменяем p1 на p2, p2 на p3. Переходим к 1. До тех пор пока не кончатся точки. Название: Re: Аппроксимация Отправлено: ssoft от Ноябрь 26, 2012, 14:23 Цитировать Это первое что приходит в голову. но эта схема не ловит плавный переход. Допустим на каждом шаге угол меньше критического и ф-ция монотонно убывает (или возрастает). Тогда вектор (p0, p1) будет "разворачивться" по направлению роста. Напр на шаге 100 мы получим вектор (p0. p100), 98 точек выброшено - гуд. Но угол между (p0, p100) и (p0, p2) может быть ого-го. Залатать это "длиной" - неясно как. Да и правда, потомучто я наврал, не специально, конечно. ;D Сначала смотрим отклонение p1 относительно линии (p0, p2). Если p1 можно проигнорировать, то смотрим до какой точки, т.е. p2 и последующие анализируем относительно линии (p0, p1). Там достаточно все просто, нужно порисовать чуть-чуть. Алгоритм очень быстро работает, причем является однопроходным, я использую его для загрубления графики. Нашел свой код ;), выкладываю без изменений, с типами думаю разберетесь. По заданному массиву точек и заданной точности здесь расчитывается массив индексов для точек, которые следует использовать. Код: #ifndef QEX_GRAPHICS_TOLLERANCE_H Код: #ifndef QEX_GRAPHICS_CURVE_FILTER_H Код: #include "QexGraphicsCurveFilter.h" Возможно, критерии загрубления немного другие. Название: Re: Аппроксимация Отправлено: Igors от Ноябрь 26, 2012, 15:52 Код: diviation = QexVector3Df::abs( vector ) * sin( QexVector3Df::angle( vector, vector_next ) ); Код
Возможно, критерии загрубления немного другие. Да. У Вас все норм, но требуется разумный ref_dist. У меня возможна (и желательна) ситуевина когда аппроксимируется 2-3 отрезками и даже одним, независимо от длины. В любом случае спасибо за код Название: Re: Аппроксимация Отправлено: Igors от Ноябрь 27, 2012, 10:10 Вот нашел сильный алгоритм (аттач)
Название: Re: Аппроксимация Отправлено: _Vitaliy_ от Ноябрь 27, 2012, 13:41 Сейчас тоже работаю с похожей тематикой. Рекомендую посмотреть в сторону МНК или если можно интерполировать, то сплайн Акимы или кубический сплайн.
Название: Re: Аппроксимация Отправлено: Igors от Ноябрь 27, 2012, 13:54 Рекомендую посмотреть в сторону МНК или если можно интерполировать, то сплайн Акимы или кубический сплайн. Все-таки лучше прочитать тему, а потом (может быть) "рекомендовать" :)Скорость здесь слишком критична, нет возможности даже накопить все исходные, не говоря уже о градиенте, гипотезе, МНК и.т.п. Название: Re: Аппроксимация Отправлено: Disa от Ноябрь 28, 2012, 00:44 А что за книга из которой рисунок?
Название: Re: Аппроксимация Отправлено: Igors от Ноябрь 28, 2012, 14:54 А что за книга из которой рисунок? Это статья 2000 года (Locovic, Veach) - видимо "первоисточник" придумал скромный Локович. Потом десятки перепечаток в которых почему-то график вверх ногами (наверное не заметили). Как всегда возня вокруг GPU и.т.п.Название: Re: Аппроксимация Отправлено: Disa от Ноябрь 28, 2012, 15:26 Спасибо!)
|