Mathcad to Matlab - тестирование белого шума, fft и NPS

Я пытаюсь написать простую функцию в Matlab для расчета и построения спектра мощности шума (NPS). Прежде всего, я хотел проверить, подходит ли алгоритм, который я получил от моего учителя, и все такое. Вот оно (сделано в mathcad)

введите описание изображения здесь

Поэтому я попытался скопировать и вставить его в скрипт Matlab и в итоге получил этот код:

clear all;
clc;


N=1000;
O=1024;
mn=zeros(N,O);
n0=1500;
s=sqrt(n0);
W=zeros(N,O/2);
W1=zeros(N,O);

for k=1:N
    for l=1:O
        mn(k,l)=n0+round(sin(randn)*s);
    end
end

for k=1:N
    for l=1:O
        mn(k,l)=mn(k,l)-n0;
    end
end

for k=1:N
    W1(k,:)=fft(mn(k,:));
end

for k=1:N
   for l=1:O/2
       W(k,l)=W1(k,l);
   end
end

NPS1=(abs(W)).^2;
NPS2=sum(NPS1);
NPS=(1/N)*NPS2;

plot(NPS);

Я не использую распределение Пуассона, и я переключил индексы строка-столбец, но это не имеет значения (верно?). Проблема в том, что значения на моем графике в 400 раз больше, чем ожидалось.

Вот как это должно выглядеть:

Я пытался найти, что я сделал не так, но после некоторого времени тестирования некоторых изменений я вернулся в исходное положение ... Единственное, что меня беспокоит, это то, что, возможно, функция Matlab fft работает иначе, чем та, которая использовалась в Mathcad (не могу сказать, что полностью понимаю). Любая добрая душа может сказать мне, если дело в функции fft? Или я просто слепой болван, который не видит совершенную им глупую ошибку? Приветствую и извините за мой плохой английский.

[РЕДАКТИРОВАТЬ]

Через некоторое время мой учитель попросил меня проверить, работает ли этот метод с коррелированным (своего рода) шумом, поскольку он работает (снова) в mathcad. После корреляции его NPS должен «падать» на более высоких частотах. Проблема в том, что это не так. Код, который я использую для проверки, выглядит так:

clear all;
clc;

N=1000;

mn = poissrnd(N, N, N);
dataw=zeros(N);

for k=1:N ## loop used for my teacher's correlation method
    for l=1:N
        if l>1 && l<N
            dataw(k,l)=dataw(k,l)+mn(k,l)*0.5+mn(k,l-1)*0.25+mn(k,l+1)*0.25;
        elseif l==1
            dataw(k,l)=dataw(k,l)+mn(k,l)*0.75+mn(k,l+1)*0.25;
        else
            dataw(k,l)=dataw(k,l)+mn(k,l)*0.75+mn(k,l-1)*0.25;
        end
    end
end

dataw = dataw - mean(dataw(:));
W1 = (1/sqrt(N))*fft(dataw, [], 1);

NPS1=(abs(W1)).^2;
NPS2=sum(NPS1);
NPS=(1/N)*NPS2;

plot(NPS);

Единственные изменения, которые я внес в код, исправленный Rayryeng, - это квадрат матрицы шума (1000x1000), а также среднее значение 1000 и использование всего преобразованного вектора W1 вместо его «половины». Я знаю, что это сработало для моего учителя, но это не для меня ... Есть ли что-то еще в Matlab fft, которое я упустил, или это «метод корреляции», который я использовал?

Добавление того, как это выглядит в Mathcad после нескольких быстрых изменений (несколько незначительных отличий, но в целом это показывает эффект, который я должен получить). Это прервало начало сканирования, но оно точно такое же, как я указал в начале этого поста.

[РЕДАКТИРОВАТЬ2]

Nvm, это была проблема размера в функции fft. После изменения на fft (dataw, [], 2) он выглядит лучше.


person Warner    schedule 12.12.2014    source источник
comment
Я написал ответ. Причина, по которой это не сработало, довольно тонкая. Я также включил несколько советов о том, как ускорить работу вашего кода. Удачи!   -  person rayryeng    schedule 12.12.2014


Ответы (1)


Основная причина, по которой это не работает, связана с коэффициентом масштабирования БПФ между MathCad и MATLAB. В MathCad имеется дополнительный коэффициент масштабирования 1/sqrt(N), тогда как MATLAB не включает этот коэффициент масштабирования. Таким образом, вам необходимо умножить результаты БПФ на этот коэффициент масштабирования, если вы хотите имитировать результаты, которые вы видите с помощью MathCad.

Кроме того, у меня есть несколько предложений по вашему коду:

  1. Мы можем полностью векторизовать это без каких-либо циклов.
  2. Такие функции, как fft и randn, могут работать с матрицами, и вы можете специально применить функцию к одному конкретному измерению.

Обратите внимание, что я заменил ваше случайное распределение шума на случайный шум Пуассона (из _4 _), чтобы я мог воспроизвести результаты, полученные с вашим учителем.


По сути, ваш код можно заменить на:

clear all;
clc;

N=1000;
O=1024;
n0=1500;
s=sqrt(n0);

%mn = round(sin(randn(N,O)*s));
mn = poissrnd(n0, N, O); %// CHANGE
mn = mn - mean(mn(:)); %// Remove mean
W1 = (1/sqrt(N))*fft(mn, [], 1); %// CHANGE FROM ABOVE
W = W1(:,1:O/2);

NPS1=(abs(W)).^2;
NPS2=sum(NPS1);
NPS=(1/N)*NPS2;

plot(NPS);

Обратите внимание, что вы добавили среднее значение 1500 при генерации случайных данных ... только для того, чтобы снова вычесть из него 1500 без какой-либо обработки данных смещения. Я просто удалил это из вашего кода для случайного шума синусоидального округления. Я оставил этот код закомментированным, потому что в любом случае я его сейчас не использую. Также обратите внимание, что randn может принимать количество строк и столбцов, поэтому вы можете сгенерировать случайную матрицу значений. Кроме того, fft может работать со строками или столбцами и рассматривать каждый сигнал в этом измерении как одномерный сигнал. В этом случае вы хотите работать с каждым столбцом и обрабатывать строки, поэтому мы указываем параметр 1 в качестве третьего параметра.

Вот что мы получаем, когда запускаю приведенный выше код:

введите описание изображения здесь


Вы видите, что оно колеблется в районе среднего значения 1500, чего мы и ожидали, исходя из случайного распределения Пуассона с lambda=1500. Если вы действительно хотите, чтобы график выглядел как график вашего учителя, измените пределы оси Y с 0 на 2000 следующим образом:

ylim([0 2000]);

Таким образом получаем:

введите описание изображения здесь

person rayryeng    schedule 12.12.2014
comment
БОЛЬШОЕ СПАСИБО, МУЖЧИНА! На самом деле (я имею в виду ДЕЙСТВИТЕЛЬНО) ценю глубокий анализ и советы, которые вы предоставили. Я искренне благодарен! - person Warner; 12.12.2014
comment
@Warner - С удовольствием :) Обработкой сигналов я занимаюсь каждый день. На этот вопрос я не удержался от ответа! Удачи! - person rayryeng; 12.12.2014
comment
еще раз спасибо за помощь! Смог продвинуть весь проект дальше, но снова вернулся к проблеме NPS. : \ Было бы для вас проблемой заглянуть в раздел Изменить основного сообщения? Кажется, простая проблема, но у меня нет идей. : \ - person Warner; 23.12.2014
comment
@Warner - Можете ли вы опубликовать код MathCad, а также то, как выглядит ожидаемый спектр? Мне трудно понять, что вы делаете для корреляции шума. - person rayryeng; 23.12.2014
comment
Хорошо, я их получил. Добавил их в основной пост. - person Warner; 27.12.2014
comment
Вам придется немного подождать. В отпуске. К сожалению, это не является для меня приоритетом. Извините! - person rayryeng; 28.12.2014
comment
Конечно. Тем не менее, спасибо, что нашли время. Хорошего праздника - person Warner; 28.12.2014
comment
Просто хочу сказать, что существует по крайней мере четыре различных способа применения коэффициентов масштабирования к fft, в зависимости от цели более широкого алгоритма. Вариант Matlab (без нормализации) предназначен просто для уменьшения количества вычислений и является обычным при обработке сигналов. Это отличное упражнение, чтобы узнать о различных факторах и их назначении. - person Philip Oakley; 16.05.2015