| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Алгоритмы > Обратное быстрое преобразование Фурье... |
| Автор: Proger10 17.7.2010, 18:13 | ||
| В википедии есть код http://ru.wikipedia.org/wiki/%D0%91%D1%8B%D1%81%D1%82%D1%80%D0%BE%D0%B5_%D0%BF%D1%80%D0%B5%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%A4%D1%83%D1%80%D1%8C%D0%B5#.D0.9E.D0.B1.D1.80.D0.B0.D1.82.D0.BD.D0.BE.D0.B5_.D0.BF.D1.80.D0.B5.D0.BE.D0.B1.D1.80.D0.B0.D0.B7.D0.BE.D0.B2.D0.B0.D0.BD.D0.B8.D0.B5_.D0.A4.D1.83.D1.80.D1.8C.D0.B5 на С++. Насколько понимаю, они программировали эту формулу: http://upload.wikimedia.org/math/f/6/9/f69747fba84996b2d75638608c59a2bb.png Постоянно запутываюсь в этом коде) может кто-то сможет отследить как из этого прямого сделать обратное преобразование Фурье. По теории, чтобы это сделать нужно экспоненту возвести в степень -1 (не ошибаюсь я?). Т.е. остаётся найти где они считают "exp", ну и сделать: "1/exp(...)". Только вот в этом поиске и заключается проблема.. Вот рабочий код прямого преобразования Фурье:
|
| Автор: maxdiver 27.7.2010, 00:29 | ||
| Да, реализация не самая лучшая (с точки зрения понятности; слишком она наоптимизированная, чтобы такую в вики пихать)... В их обозначения переменных я не углублялся, но кажется, что здесь может быть единственный вариант:
здесь всё умножить на -1 (или у isign, который может быть для этого и предназначен, изменить значение на противоположное). И вообще, чтобы из прямого БПФ получить обратное, надо не только заменить экспоненту на противоположную, но и разделить потом каждый элемент результата на n. |
| Автор: Proger10 11.8.2010, 19:07 |
| Опробовал, но не прокатило :( В конце кода ФФТ, есть такая штука: dOut[ i ] = sqrt( .... ), случаем не может ли быть из-за неё? У меня получаются вот какие графики: http://s001.radikal.ru/i196/1008/f5/65fd8b141fac.png Тут видите, абсолютно какие-то другие числа получаются. Такое впечатление, что это кепстр исходного получается))) Алгоритм такой: ффтМассив = ФФТ( исходные_данные, 1024-окно ); ффтОбратноеМассив = рФФТ( ффтМассив, 1024 ); // рФФТ - обратное ффт, в котором заменён isign = -1 на +1. И чего-то ерунда какая-то получается. Может у кого есть прямое и обратное FFT на C++? |
| Автор: Pavia 11.8.2010, 19:22 |
| Proger10, // http://psi-logic.shadanakar.org/fft/fftf.htm /// http://student.kuleuven.be/~m0216922/CG/fourier.html#introduction |
| Автор: Proger10 11.8.2010, 23:32 | ||
| А покороче ничего нет? Я вот нашёл некоторый код, короткий (он был комплексный, я им пользуюсь как не комплексным):
Он преобразование для 1024 точек считает секунд 20 на двуядерном 2.24GHz, что неприемлемо для меня (мне в рил-тайме обрабатывать надо сигнал). Вышеприведённый код считает меньше, чем за пол секунды. Если я начну реализовывать самостоятельно, он, скорее всего, получится у меня таким же тормозом.. а почему же первый работает так быстро? Накрутили его нехило, зато, чёрт, очень работоспособный.. И то на половину. Обратное сделать в нём не получается. |
| Автор: Pavia 12.8.2010, 08:34 |
| Proger10, 2 код тормазит из-за vector. Используй указатель. Хочешь скорость используй fftw http://www.fftw.org/ |
| Автор: Proger10 12.8.2010, 10:24 |
| Вряд ли из-за vector он тормозит. Покуда прошлый код у меня тоже работает на vector. (я поменял с указателя на vector). Видимых отличий в скорости не оказалось, а работать удобнее, поэтому и оставил. Спасибо за совет. Попробую. Я как-то смотрел уже те мануалы.. первое впечатление - чёрт ногу сломит. Посмотрим ещё раз. |
| Автор: maxdiver 13.8.2010, 23:50 | ||
У меня на http://e-maxx.ru/algo/fft_multiply есть вполне короткий и адекватно быстрый код:
Для ста тысяч элементов отрабатывать должен где-то за секунду. |
| Автор: Proger10 16.8.2010, 20:40 | ||
| maxdiver А не в комплексном случае, а вещественном, инициироваться wn должна каким значением? Инициировал косинусом от ang - получилось что-то не очень походящее на спектр Фурье Код у меня сейчас вот так модифицирован:
В первом коде вычислялся ещё квадрат суммы для каждого выходного коэффициента, тут тоже надо сделать так же? Вообще спектр, чуток похож на спектр.. но как-то как будто у него малая точность коэффициентов. Коэффициенты почему-то все почти равные друг другу, а кодом первого сообщения они сильно выделяются.. Добавлено Квадраты суммы высчитал - стало уже получше, но всё равно очень уж много шума.. совсем непонять какие там частоты наиболее активны. Сигнал разный, а они практически одинаковые везде |
| Автор: Proger10 16.8.2010, 21:30 |
| Чтобы было более понятно о какой такой точности двух кодов я говорю, вот картинка: http://i064.radikal.ru/1008/c7/63134840417c.gif левая колонка - верхний код этой темы, а правая - последний код (аналогичный сигнал). Вот о чём я и говорю.. блин, код хороший, короткий, но какой-то не очень точный |
| Автор: maxdiver 16.8.2010, 22:16 |
| В БПФ числа всегда комплексные. Внутри функции ничего менять не надо. Входные параметры (а они вещественные - например, vector<double>) надо перевести в комплексные, для чего просто сделать вектор комплексных чисел и присвоить ему вектор вещественных (конвертация пройзойдет автоматически). Результат потом обратно надо перевести в действительные, для чего можно взять только действительную часть каждого комплексного числа (ну мнимая часть как бы = 0 в теории), или можно, как в коде в первом посте, взять модули всех чисел. В коде, приведённом в первом посте, комплексные числа тоже есть, просто они хранятся не в виде отдельной структуры, а как два соседних дабла (опять же, ничего не скажешь, "удобно" для человека, пытающегося разобраться в БПФ и видящего перед собой этот код). |
| Автор: Proger10 16.8.2010, 23:08 | ||
а где там модули берутся? не могу пока найти... Квадраты суммы квадратов, имеете ввиду?) Опробовал с комплексными - это уже намного интереснее!! |
| Автор: maxdiver 18.8.2010, 22:41 | ||
Вот где там брался модуль:
А не можете описать в паре слов, как ДПФ у вас применяется для анализа сигналов? Просто времени нет изучать литературу, а вопрос очень интересный. (я БПФ всегда использовал только для быстрого перемножения двух длинных чисел или для других смежных задач) |
| Автор: Proger10 19.8.2010, 17:43 |
| А я тоже пока только БПФ использую |