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

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Спектральный анализ Фурье, Разрыв в оцифровке. Что делать?
Navstar
сообщение Sep 13 2013, 15:21
Сообщение #16


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 29-11-09
Пользователь №: 53 951



Требуется помощь!

Согласно ТЗ мне нужно сделать дискретное преобразование Фурье массива выборок.
С прямым, все отлично - получаем амплитудный и фазовый спектр, и непосредственно зеркальный спектр. а вот с обратным преобразованием не получается - результатом ОДПФ, согласно формуле появляются 2 массива состовляющих "Мнимые" и "реальные". Как из них получить результирующий массив(Например делая ДПФ и ОДПФ получить исходный массив)? Есть наброска на джаве:

Задаем массив signal

Прямое ДПФ
Код
private static void DFT(double[] signal, double[] phase)
  {
     double[] Re = new double[1024];
     double[] Im = new double[1024];
     for(int k = 0; k < 1024; k++)
     {
        for(int n = 0; n < 1024; n++){  
     Re[k]=Re[k]+signal[n]*Math.cos(-2*Math.PI*k*n/1024);
     Im[k]=Im[k]+signal[n]*Math.sin(-2*Math.PI*k*n/1024);}
     }
        
        for(int k = 0; k < 1024; k++)
     {
        signal[k]=Math.sqrt(Re[k]*Re[k]+Im[k]*Im[k]);
        phase[k]=Math.atan(Im[k]/Re[k]);        
     }


Обратное ДПФ
Код
private static void IDFT(double[] signal, double[] phase)
  {
     double[] Re = new double[1024];
     double[] Im = new double[1024];
    for(int n = 0; n < 1024; n++)
     {

        
        for(int k = 0; k < 1024; k++)  
        {  
            
     Re[n]=Re[n]+signal[k]*Math.cos(2*Math.PI*k*n/1024+phase[n]);
     Im[n]=Im[n]+signal[k]*Math.sin(2*Math.PI*k*n/1024+phase[n]);
                
        }
       Re[n]=Re[n]/1024;
       Im[n]=Im[n]/1024;
      
     }

  }


Как теперь получить исходя из этих массивов опратно массив signal выполнив подряд процедуры прямого и обратного преобразования
Go to the top of the page
 
+Quote Post
Alex11
сообщение Sep 15 2013, 06:51
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 2 106
Регистрация: 23-10-04
Из: С-Петербург
Пользователь №: 965



Из результата первой функции Вы не восстановите исходный сигнал, т.к. уже потеряли часть информации о нем, взяв квадратный корень. На вход обратного преобразования нужно подавать массивы Re и Im из прямой функции перед взятием корня и арктангенса. Тогда получите исходны сигнал в Re и нули в Im на выходе обратного преобразования. Разумеется, с точностью до ошибок счета.
Go to the top of the page
 
+Quote Post
ivan219
сообщение Sep 15 2013, 07:54
Сообщение #18


Местный
***

Группа: Участник
Сообщений: 350
Регистрация: 16-11-08
Пользователь №: 41 680



Цитата(Alex11 @ Sep 15 2013, 10:51) *
Из результата первой функции Вы не восстановите исходный сигнал, т.к. уже потеряли часть информации о нем, взяв квадратный корень.

Ни куда эта информация не делась. Она только претерпела изменение. И восстановить исходный сигнал по имеющимся значениям амплитуды и фазы можно.

А не работает скорей всего из за ошибки со знаками где то + с - перепутали. Где именно и как нужно смотреть формулы.

Сообщение отредактировал ivan219 - Sep 15 2013, 07:56
Go to the top of the page
 
+Quote Post
Navstar
сообщение Sep 18 2013, 11:49
Сообщение #19


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 29-11-09
Пользователь №: 53 951



Проблема была в том что нужно было использовать функции аргумента, а не арктангенса, а так же фильтровать спектр от зеркальной составляющей, занулив ее и удвоив исходный спектр
Может кому пригодится исходный код на java. Все это будет интегрироваться в Embedded систему с linux ядром.
Код

private static void DFT(double[] signal, double[] phase)
  {
     double[] Re = new double[1024];
     double[] Im = new double[1024];
     for(int k = 0; k < 1024; k++)
     {
        for(int n = 0; n < 1024; n++)
        {  
     Re[k]=Re[k]+signal[n]*Math.cos(-2*Math.PI*k*n/1024 );
     Im[k]=Im[k]+signal[n]*Math.sin(-2*Math.PI*k*n/1024 );
        }
     }
        
       for(int k = 0; k < 1024; k++)
     {
        signal[k]=2*Math.sqrt(Re[k]*Re[k]+Im[k]*Im[k]);
        phase[k]=Math.atan2(Im[k],Re[k]);
     }  
                
            
       for(int n = 512; n < 1024; n++)
             {
                       signal[n]=0;
                       phase[n]=0;  
             }
      
  }
  
  
  private static void ODFT(double[] signal, double[] phase)
  {
     double[] Re = new double[1024];
     double[] Im = new double[1024];
    for(int n = 0; n < 1024; n++)
     {
            Re[n]=signal[n]*Math.cos(phase[n]);
            Im[n]=signal[n]*Math.sin(phase[n]);      
         }
    
    for(int n = 0; n < 1024; n++)
     {        
       signal[n]=0;
       phase[n]=0;
        for(int k = 0; k < 1024; k++)  
        {
             signal[n]=signal[n]+Re[k]*Math.cos(2*Math.PI*k*n/1024)-Im[k]*Math.sin(2*Math.PI*k*n/1024);
        }
      
     }
    for(int n = 0; n < 1024; n++)
     {
         signal[n]=signal[n]/1024;
        }
  }


Сообщение отредактировал Navstar - Sep 18 2013, 11:49
Go to the top of the page
 
+Quote Post

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

 


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


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