2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки


Правила форума


Посмотреть правила форума



Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3  След.
 
 Re: Преобразование Фурье
Сообщение25.09.2018, 23:30 
Аватара пользователя


05/10/12
198
разделы "%Вот здесь я пытаюсь изменить вектор времени." и "% Вот здесь я дополнительно избегаю зеркального эффекта." отличаются использованием в трансформации F1 вместо F.
F - это непосредственно коэфиценты после трансформации, F1 - это исправленные коэфиценты:
Код:
F = fft(S);                                                        % Это фурье образ, здесь всё в порядке. F - это коэфиценты разложения.
F2 = abs(F/size(S,2));                                      %Нормированный модуль коэфицентов (делёный на количество значений в сигнале (длина вектора S))
F1 = F2(1:size(S,2)/2+1);                               % Берём половину от нормированного результата трансформации (полученого строчкой выше)
F1(2:end-1) = 2*F1(2:end-1);                         % Из этой половины все, за исключением первого значения, удваиваем.


-- 26.09.2018, 00:42 --

"Signal after transformation" - это результат обратной трансформации в которой я использовал те же самые значения времени, что и при прямой трансформации. В этом случае даже было не обязательно коректировать значения прямой трансформации и бороться с зеркальным эффектом (я сипользовал значения F, а не F1) и всё нормально сложилось в первоначальный сигнал.

 Профиль  
                  
 
 Re: Преобразование Фурье
Сообщение26.09.2018, 07:27 
Аватара пользователя


31/10/08
1244
_20_ в сообщении #1341232 писал(а):
temp3(n) = temp3(n) + abs(F(k)) * exp(1i * angle(F(k))) * exp((2 * pi * 1i * (n - 1) * (k - 1))/(size(t3,2)));

Здесь надо делить не на размер массива, а на частоту дескритизации. Она в 1.5 раза меньше.

Плюс у вас растекание спектра.
Поэтому перед fft(S) надо убрать постоянную составляющую.
S = S - mean(S)

 Профиль  
                  
 
 Re: Преобразование Фурье
Сообщение26.09.2018, 13:56 
Аватара пользователя


05/10/12
198
Pavia

Я Ваших рекомендаций не понял, но всё - таки им последовал:

Код:
S = 0.7*sin(2*pi*3*t) + sin(2*pi*6*t);
S = S - mean(S);


Код:
temp3(n) = temp3(n) + abs(F1(k)) * exp(1i * angle(F1(k))) * exp((2 * pi * 1i * (n - 1) * (k - 1))/(size(t3,2)/1.5));


Не помогло:

Изображение

 Профиль  
                  
 
 Re: Преобразование Фурье
Сообщение26.09.2018, 15:06 
Заслуженный участник


27/04/09
28128
Кстати, зачем делать вот это: abs(F1(k)) * exp(1i * angle(F1(k)))? Это же F1(k) и есть.

-- Ср сен 26, 2018 17:14:51 --

Вообще когда у вас есть комплекснозначный фурье-образ, ничего не нужно нигде вырезать, нужно только иметь в виду, что вторая половина частот в выдаваемом обычно массиве — отрицательные (а для получастоты дискретизации не важно, отрицательная она или нет).

О Диэдр, теорию никто не изучает и справку никто не читает.

 Профиль  
                  
 
 Re: Преобразование Фурье
Сообщение26.09.2018, 15:38 


05/09/16
11565
_20_
Я попробовал пофурьерить сам :D
Подозреваю, что проблема вот тут
abs(F1(k)) * exp(1i * angle(F1(k))) * exp((2 * pi * 1i * (n - 1) * (k - 1))/(size(t3,2)/1.5));
Я делал "вещественное ДПФ" с вашим сигналом S = 0.7*sin(2*pi*3*t) + sin(2*pi*6*t);
Прямое ДПФ
$ReF(k)=\sum \limits_{i=0}^{N-1}S_i\cos(2\pi ki/N)$
$ImF(k)=-\sum \limits_{i=0}^{N-1}S_i\sin(2\pi ki/N)$
Тут соответственно $N=150;S_i=S(i\cdot \Delta t); \Delta t = 0.01$
Нормализация:
$ReF(1)=2\cdot ReF(1);ReF(N/2)=2\cdot ReF(N/2)$
$ImF(1)=2\cdot ImF(1);ImF(N/2)=2\cdot ImF(N/2)$
Обратное ДПФ (т.е. -- разложение в ряд):
$f(t)=\dfrac{1}{N}\left(\sum \limits_{i=0}^{N/2}ReF(i)\cdot \cos(2\pi i \dfrac{t}{\Delta t N})-\sum \limits_{i=0}^{N/2}ReF(i)\cdot \sin (2\pi i \dfrac{t}{\Delta t N})\right)$
Это то что вы хотели -- $f$ это функция от непрерывного времени $t$

$S(t), t \in [0;1]$:
Изображение
$f(t), t \in [0;1]$:
Изображение
$S(t)-f(t),  t \in [0;1]$
Изображение
Там мелковато, размах ошибки: $(-0.06;-0.02)$

 Профиль  
                  
 
 Re: Преобразование Фурье
Сообщение26.09.2018, 15:42 
Заслуженный участник


27/04/09
28128
У ТС там вроде проблема в том, что если отрезать вторую половину списка амплитуд, будет не то, и если её не отрезать, но не трактовать по-правильному как амплитуды отрицательных частот — тоже будет не то (хотя на отсчётах значения, конечно, совпадут — и то, и то понятно почему). Советы Pavia я вообще не понял, особенно множитель 1,5. У всех операций есть смысл, их нельзя делать как попало. :|

 Профиль  
                  
 
 Re: Преобразование Фурье
Сообщение26.09.2018, 16:03 


05/09/16
11565
arseniiv в сообщении #1341650 писал(а):
Советы Pavia я вообще не понял, особенно множитель 1,5.

Ну интервал $1,5$ секунды, отсчеты берем через $0,01$ секунд, частота дискретизации $100$ герц, всего $150$ отсчетов. Для перехода от отсчетов к непрерывному времени надо время поделить на полтора ($\Delta t \cdot N=0,01 \cdot 150 = 1,5$)

 Профиль  
                  
 
 Re: Преобразование Фурье
Сообщение26.09.2018, 16:14 
Заслуженный участник


27/04/09
28128
Ладно, снимаю возражение как вызванное трудностями в прочтении постов.

 Профиль  
                  
 
 Re: Преобразование Фурье
Сообщение26.09.2018, 17:05 


05/09/16
11565
wrest в сообщении #1341646 писал(а):
Обратное ДПФ (т.е. -- разложение в ряд):
$f(t)=\dfrac{1}{N}\left(\sum \limits_{i=0}^{N/2}ReF(i)\cdot \cos(2\pi i \dfrac{t}{\Delta t N})-\sum \limits_{i=0}^{N/2}ReF(i)\cdot \sin (2\pi i \dfrac{t}{\Delta t N})\right)$
Это то что вы хотели -- $f$ это функция от непрерывного времени $t$

Читать так:
Обратное ДПФ (т.е. -- разложение в ряд):
$f(t)=\dfrac{1}{N}\left(\sum \limits_{i=0}^{N/2}ReF(i)\cdot \cos(2\pi i \dfrac{t}{\Delta t N})-\sum \limits_{i=0}^{N/2}\color{blue}Im\color{black} F(i)\cdot \sin (2\pi i \dfrac{t}{\Delta t N})\right)$
Это то что вы хотели -- $f$ это функция от непрерывного времени $t$
Да, кстати. Здесь $i$ это индекс, а не мнимая единица, есличо :)

 !  Красный цвет зарезервирован под модераторскую правку. Исправлено на синий. // Lia

 Профиль  
                  
 
 Re: Преобразование Фурье
Сообщение30.09.2018, 09:04 
Аватара пользователя


05/10/12
198
Здравствуйте снова.
Я взял не большую паузу, но никак не могу понять, в чём ошибка. Вроде делаю всё правильно, проверьте?
Не получается обратное фурье преобразование даже на том же самом отрезке времени:

Код:
step = 0.01; %in seconds
SignalLength = 1.5; %in seconds
t = (0:step:SignalLength-step);
S = 0.7*sin(2*pi*3*t) + sin(2*pi*6*t);
a = zeros(1,size(t,2));
b = a;
F = complex(a,0);
for w = 1:size(t,2)
    for j = 1:size(t,2)
        a(w) = a(w) + S(j) * cos(2*pi*(w-1)*(j-1)/size(t,2));
        b(w) = b(w) - S(j) * sin(2*pi*(w-1)*(j-1)/size(t,2));
        F(w) = a(w) + 1i * b(w);
    end
end
F(1) =  2*F(1);
F(size(t,2)/2) = 2 * F(size(t,2)/2);
f = zeros(size(S,2));
for k = 1:size(t,2)
    for w = 1:size(t,2)/2   
        f(k) = f(k) + 1/size(t,2) * (real(F(w)) * cos(2*pi*(w-1)*(k-1)/size(t,2)/step)...
            - imag(F(w)) * sin(2*pi*(w-1)*(k-1)/size(t,2)/step));
    end
end

 Профиль  
                  
 
 Re: Преобразование Фурье
Сообщение01.10.2018, 19:39 
Заслуженный участник


27/04/09
28128
Вы бы имена в коде подробнее документировали, что ли, или хотя бы сказали, что с чем не сходится, ну и проверили соответствие формулам. И например для не разбирающихся в матлабе что делает S(j)? Если понимаю код правильно, проблема могла бы быть во множителях внутри синуса и косинуса.

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

Ещё строку F(w) = a(w) + 1i * b(w); следует вынести во внешний цикл for w, потому что лишние присвоения во внутреннем не дают никакого эффекта.

 Профиль  
                  
 
 Re: Преобразование Фурье
Сообщение01.10.2018, 22:45 


05/09/16
11565
_20_ в сообщении #1342535 писал(а):
Вроде делаю всё правильно, проверьте?

Я не понимаю матлаб :oops:
Тоже не понял как работает S(j)
Что такое size(t,2)? Это целое, N? Ну и назвади бы тогда N=size(t,2)...
Как работает конструкция с двумя делениями подряд 2*pi*(w-1)*(k-1)/size(t,2)/step ? И зачем оно там, если вы вычисляете $f_k$ а не $f(t)$ -- похоже тут и ошибка.
Вы делаете циклы от 1, но внутри от индекса отнимаете единицу. Матлаб не поддержтвает индексы от нуля?
Замените real(F(w)) и imag(F(w)) на a(w) и b(w) соотвественно, у вас же это вычисляется ранее. И следите за индексами (или делайте от нуля или не забывайте отнимать единицу).
То есть: сделайте точно по формулам вещественного Фурье что я вам написал. Потом будете дорабатывать и анализировать почему комплексное Фурье не получается.

 Профиль  
                  
 
 Re: Преобразование Фурье
Сообщение02.10.2018, 11:15 
Аватара пользователя


05/10/12
198
Спасибо, что не бросаете тему, я сейчас исправлюсь.
wrest Вроде делаю всё именно по тем формулам, что Вы написали, но, видимо, делаю что - то неправильно и не могу понять, что именно.
Да, в матлабе принята индексация масивов от еденицы, как в фортране.
Конструкция с двумя делениями работает так же, как конструкция с двумя умножениями, сначало выполняется деление на первое число, а потом результат делится на второе число.

Перевод с матлаба на человеческий:

step = 0.01; %in seconds
Это я принимаю шаг приращения времени для вычисления входящего сигнала, наверное правильно назвать дискретизация. Оно в секундах, мне так будет удобнее.

SignalLength = 1.5; %in seconds
Это длинна входящего сигнала, тоже в секундах.

t = (0:step:SignalLength-step);
Это создание значений времени. Является одномерным масивом, в матлабе такое принято называть вектором, но я постараюсь здесь называть именно одномерный массив.

S = 0.7*sin(2*pi*3*t) + sin(2*pi*6*t);
Это создание массива интенсивности входящего сигнала. Тоже одномерный массив.

a = zeros(1,size(t,2));
Создание пустого одномерного массива длинной в количество точек входящего сигнала. Будет использоваться для содержания действительной части фурье образа.

b = a;
Создание пустого одномерного массива длинной в количество точек входящего сигнала. Будет использоваться для содержания мнимой части фурье образа.

F = complex(a,0);
Создание пустого одномерного массива комплексных чисел длинной в количество точек входящего сигнала. Будет использоваться для содержания всего фурье образа.

for w = 1:size(t,2)
Цикл. w будет пробегать все значения от одного до количества пунктов одномерного массива времени.

for j = 1:size(t,2)
Цикл. j будет пробегать все значения от одного до количества пунктов одномерного массива времени.

a(w) = a(w) + S(j) * cos(2*pi*(w-1)*(j-1)/size(t,2));
Вычисление действительной части фурье образа. S(j) - это j-ый элемент одномерного массива S, входящего сигнала.

b(w) = b(w) - S(j) * sin(2*pi*(w-1)*(j-1)/size(t,2));
Вычисление мнимой части фурье образа. S(j) - это j-ый элемент одномерного массива S, входящего сигнала.

F(w) = a(w) + 1i * b(w);
Вычисление фурье образа.

end
Конец внутреннего цикла.

end
Конец внешнего цикла.

F(1) = 2*F(1);
Удвоение первого элемента фурье образа.

F(size(t,2)/2) = 2 * F(size(t,2)/2);
Удвоение среднего элемента фурье образа (то есть того элемента, который находится по середине одномерного массива фурье образа).

f = zeros(size(S,2));
Создание пустого одномерного массива длинной в количество точек входящего сигнала. Будет использоваться для содержания сигнала, полученного обратной трансформацией.

for k = 1:size(t,2)
Цикл. k будет пробегать все значения от одного до количества пунктов одномерного массива времени.

for w = 1:size(t,2)/2
Цикл. w будет пробегать все значения от одного до половины от количества пунктов одномерного массива времени.

f(k) = f(k) + 1/size(t,2) * (real(F(w)) * cos(2*pi*(w-1)*(k-1)/size(t,2)/step)...
- imag(F(w)) * sin(2*pi*(w-1)*(k-1)/size(t,2)/step));
Вычисление обратной трансформации фурье. k - это типа время, w - частота. То есть для каждого момента времени я складываю по всем частотам с их коэфицентами.

end
Конец внутреннего цикла.

end
Конец внешнего цикла.

 Профиль  
                  
 
 Re: Преобразование Фурье
Сообщение02.10.2018, 12:21 


05/09/16
11565
_20_ в сообщении #1343192 писал(а):
a = zeros(1,size(t,2));
Создание пустого одномерного массива длинной в количество точек входящего сигнала.

Что значит "2" в size(t,2)?
_20_ в сообщении #1343192 писал(а):
f(k) = f(k) + 1/size(t,2) * (real(F(w)) * cos(2*pi*(w-1)*(k-1)/size(t,2)/step)...
- imag(F(w)) * sin(2*pi*(w-1)*(k-1)/size(t,2)/step));
Вычисление обратной трансформации фурье. k - это типа время, w - частота.

Что значит "типа время"?
Вот же формулы для непрерывного времени:
wrest в сообщении #1341684 писал(а):
Обратное ДПФ (т.е. -- разложение в ряд):
$f(t)=\dfrac{1}{N}\left(\sum \limits_{i=0}^{N/2}ReF(i)\cdot \cos(2\pi i \dfrac{t}{\Delta t N})-\sum \limits_{i=0}^{N/2}\color{blue}Im\color{black} F(i)\cdot \sin (2\pi i \dfrac{t}{\Delta t N})\right)$
Это то что вы хотели -- $f$ это функция от непрерывного времени $t$

Где вы там видите внешний цикл? Аргумент у синусов\косинусов или
$2\pi i \cdot \dfrac{t}{\Delta t} \cdot \dfrac{1}{N}$ - если вы хотите считать для любого $t$
Или $2\pi i \cdot k \cdot \dfrac{1}{N}$ - если вы восстанавливаете ваши 0-й, 1-й, ... 149-й отсчет и уходите от времени... То есть $k$-й отсчет соответствует моменту времени $t=k \Delta t$
Вы хотели восстанавливать значения функции которые попали между отсчетами при дискретизации, например между 1 и 2 отсчетом, тогда у вас получается отсчет за номером 1,5 к примеру, вот для этого вы в аргументы синусов\косинусов и подставляете вместо номера отсчета $k$ значение времени $t$, в виде $k=\dfrac{t}{\Delta t}$

 Профиль  
                  
 
 Re: Преобразование Фурье
Сообщение09.10.2018, 13:37 
Аватара пользователя


05/10/12
198
Спасибо за ответы. У меня возникли некоторые сложности, но, вроде я сам разобрался. Осталась пара вопросов.

wrest
По Вашим формулам обратное ДПФ даёт амплитуду сигнала в два раза меньше. Надо или на два умножать, ну или делить не на N, а на N/2.

Метод хорошо работает не для всех длинн входящего сигнала. Вот пример:
https://ibb.co/nwtvEU
Верхний ряд - время t проходин от 0 до 1,

Код:
SignalLength = 1;
t = (0:step:SignalLength-step);
S = 0.7*sin(2*pi*3*t) + sin(2*pi*6*t);


нижний ряд - время проходит от 0 до 1,1

Код:
SignalLength = 1.1;
t = (0:step:SignalLength-step);
S = 0.7*sin(2*pi*3*t) + sin(2*pi*6*t);


Как видно, появляются постоянные составляющие сигнала. Отчего это может быть и как от них избавиться?

Второй вопрос, что делать, если длина сигнала нечётная?

Вы, при нормализации, удваиваете:

$ ReF(N/2) = 2 ReF(N/2)$

Что делать, если N/2 не является целым числом?

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 31 ]  На страницу Пред.  1, 2, 3  След.

Модераторы: Модераторы Математики, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: Shadow


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group