spectral structure of sinusoidal model - matlab

let us consider following code
function [ x ] = generate1(N,m,A3)
f1 = 100;
f2 = 200;
T = 1./f1;
t = (0:(N*T/m):(N*T))'; %'
wn = randn(length(t),1); %zero mean variance 1
x = 20.*sin(2.*pi.*f1.*t) + 30.*cos(2.*pi.*f2.*t) + A3.*wn;
%[pks,locs] = findpeaks(x);
%plot(x);
end
as i know peaks in Fourier domain represent at this frequency,which are present in signal,for example let us take plot of Fourier transform of this signal
let us run this signal
y=generate1(3,500,1);
and plot
plot(abs(fft(y)))
but clearly it does not shows me peaks at frequency given in signal,what is problem?please help me,generally it is stationary signal,that why this graph should show me exact picture but it does not do,why?
EDITED :
y1=generate1(3,500,0);

function [ x, fs ] = generate1(N,m,A3)
f1 = 100;
f2 = 200;
T = 1./f1;
t = (0:(N*T/m):(N*T))'; %'
wn = randn(length(t),1); %zero mean variance 1
x = 20.*sin(2.*pi.*f1.*t) + 30.*cos(2.*pi.*f2.*t) + A3.*wn;
%[pks,locs] = findpeaks(x);
%plot(x);
fs = 1/(t(2)-t(1));
end
and see
absfft = abs(fft(y));
plot(fs/2*linspace(0,1,length(absfft)/2+1),2*absfft(1:end/2+1))
or
plot(linspace(-fs/2,fs/2,length(absfft)),fftshift(absfft))
the x-axis in your plot is from 0 to fs/2 and then from -fs/2 to 0

Related

Triangle Pulse with fourier transformation

I have a basic exercise for telecommunications with matlab, and i must plot a triangle pulse with (-c,0) to (c,0) with c = 6 and Amplitude = 1 in a for loop for M pulses and approach the periodic pulse using N Fourier series terms. I can't find something on the internet that can help me so far.
A similar code for rect pulse that I made and works is this:
a = 1;
b = 3;
N = 1000;
t = linspace(a-2*a,b+2*b,N);
A = 1;
y = rect_pulse(A,a,b,t);
plot(t,y);
grid on
axis([a-2*a b+2*b 0 2*A]);
M = 5;
T=7;
t_new = linspace(a-2*a,b+(M-1)*T+2*b,N);
y_new = zeros(1,N);
for index = 1:1:M
temp_y = rect_pulse(A,a+(index-1)*T,b+(index-1)*T,t_new);
y_new = y_new + temp_y;
end
figure;
plot(t_new,y_new);
grid on;
axis([a-2*a b+(M-1)*T+2*b 0 2*A]);
Where rect_pulse is this:
function y = rect_pulse (A,a,b,t)
N=length(t);
y = zeros(1,N);
for index = 1:1:N
if(t(1,index)>=a) && (t(1,index)<=b)
y(1,index) = A;
end
end
And fourier series is this:
function y_fourier = fourier_series_rect_pulse(a,b,To,N,t)
y_fourier = 0;
wo = (2*pi)/To;
for n = -N:1:N
f_real = #(x) cos(n*wo*x);
f_imag = #(x) sin(n*wo*x);
cn = (1/To)*(quad(f_real,a,b)) - j*quad(f_imag,a,b));
y_fourier = y_fourier + cn*exp(j*n*wo*t);
end
y_fourier = real(y_fourier);
Any ideas how to make this in to triangle pulse?
This probably deviates significantly from your approach but if you're curious here is a script I came up with to generate a triangular pulse train that can be adjusted. This method, unfortunately, uses the fft() function which may or may not be off-limits in your case. Most of the script uses indexing and manipulating vectors. Additional spectral components may be seen due to the DC offset of the alternating triangular wave and the limited number of cycles available in the vector representation of the triangular wave.
Triangular Pulses and Fourier Transforms:
Triangular Pulse with Duty-Off Period:
Higher frequency spectral components present due to the abrupt corners that occur at the transition states of the triangle pulse and duty-off period.
%******************************************************%
%PROPERTIES THAT CAN BE CHANGED%
%******************************************************%
Plotting_Interval = 0.01; %0.01 seconds%
Pulse_Width = 1/20; %6 seconds%
Period = 1/20; %10 seconds (should be at least the pulse width)%
Start_Time = 0;
End_Time = Pulse_Width*1000; %(1000 pulses)%
%******************************************************%
if(Period < Pulse_Width)
Period = Pulse_Width;
end
Time_Vector = (Start_Time: Plotting_Interval: End_Time);
Points_Per_Unit_Time = 1/Plotting_Interval;
Half_Pulse = Pulse_Width/2;
Number_Of_Points = Pulse_Width/Plotting_Interval;
Rising_Slope = linspace(0,1,floor(Number_Of_Points/2) + 1);
Falling_Slope = 1 - Rising_Slope;
Triangular_Pulse = [Rising_Slope Falling_Slope(2:end)];
t = (0: Plotting_Interval: Pulse_Width);
Periodic_Triangular_Pulse = zeros(1,length(Time_Vector));
for Cycle = 1: +Period/Plotting_Interval: End_Time/Plotting_Interval
Periodic_Triangular_Pulse(1,Cycle:Cycle+length(Triangular_Pulse)-1) = Triangular_Pulse(1,1:end);
end
Periodic_Triangular_Pulse = Periodic_Triangular_Pulse(1,1:length(Time_Vector));
subplot(1,2,1); plot(Time_Vector,Periodic_Triangular_Pulse);
Triangle_Frequency = 1/Period;
title("Triangular Pulse Train " + num2str(Triangle_Frequency) + "Hz (first 10 cycles)");
axis([0 Period*10 0 1]);
xlabel("Time (s)"); ylabel("Amplitude");
Signal_Length = length(Periodic_Triangular_Pulse);
Fourier_Transform = fft(Periodic_Triangular_Pulse);
Fs = 1/Plotting_Interval;
P2 = abs(Fourier_Transform/Signal_Length);
P1 = P2(1:floor(Signal_Length/2)+1);
P1(2:end-1) = 2*P1(2:end-1);
f = Fs*(0:(Signal_Length/2))/Signal_Length;
subplot(1,2,2); plot(f,P1)
title("Single-Sided Fourier Transform");
xlabel("Frequency (Hz)"); ylabel("Magnitude");
Ran using MATLAB R2019b

Matlab: Confusion in Discrete time filter design

I have the following code in matlab:
L = 10000;
PN_30dB = -100; % dBc per Hz at 10k
f_offset = 5e6;
f_offset2 = 10e5;
F0 = 2.5e9;
A = 10^0.5;
Fs = 25e6;
fc1 = 100;
fc2 = 1e3;
fc3 = 10e3;
fc4 = 100e3;
fc5 = 1e6;
a1 = 2*pi*fc1/Fs;
a2 = 2*pi*fc2/Fs;
a3 = 2*pi*fc3/Fs;
a4 = 2*pi*fc4/Fs;
a5 = 2*pi*fc5/Fs;
sigma3 = (f_offset2/F0)*sqrt(2*10^(PN_30dB/10)/F0);
y1 = zeros(1,L);
y2 = zeros(1,L);
y3 = zeros(1,L);
y4 = zeros(1,L);
y5 = zeros(1,L);
y = zeros(1,L);
x = zeros(1,L);
for i = 2:L,
x(i) = sigma3*randn(1);
y1(i) = (1-a1)*y1(i-1) + a1*x(i);
y2(i) = (1-a2)*y2(i-1) + a2*x(i)/A;
y3(i) = (1-a3)*y3(i-1) + a3*x(i)/A^2;
y4(i) = (1-a4)*y4(i-1) + a4*x(i)/A^3;
y5(i) = (1-a5)*y5(i-1) + a5*x(i)/A^4;
y(i) = y1(i) + y2(i) + y3(i) + y4(i) + y5(i);
end
fft1 = fft(y);
fft1 = fft1(1:length(y)/2+1);
psd1 = (1/(F0*length(y)))*abs(fft1).^2;
psd1(2:end-1) = 2*psd1(2:end-1);
freq = 0:F0/length(y):F0/2;
figure(3);
semilogx(freq,10*log10(psd1))
grid on
acc = 0;
actual_timestamps_3 = zeros(1,L);
flicker = zeros(1,L);
for i = 1:L,
acc = acc + y(i);
actual_timestamps_3(i) = i/F0 + acc;
flicker(i) = acc;
end
fft1 = fft(2*pi*F0*flicker);
fft1 = fft1(1:length(flicker)/2+1);
psd1 = (1/(F0*length(flicker)))*abs(fft1).^2;
psd1(2:end-1) = 2*psd1(2:end-1);
freq = 0:F0/length(flicker):F0/2;
figure(4);
semilogx(freq,10*log10(psd1))
grid on
In this code, I am trying to create an output signal called flicker which should have a 30dB/dec roll-off of its power spectral density.
For that I am accumulating a signal called y(i) (in the second for loop) which has a 10dB/dec roll-off as can be seen in figure 3 inside the code. Since accumulation should add another 20db/dec, I am expecting the flicker signal to have a 30dB/dec roll off.
Signal y(i) is the output of a discrete time filter implemented in first for loop.
But I am not seeing the expected roll-off (30dB/dec) for the flicker signal (in figure 4). The plot shows only 20dB/dec for the flicker signal. Could someone please explain what I am doing wrong?
EDIT
Figure 4 in the code is shown below:
As you estimate the power spectral density with the FFT, you are looking at the data (flicker) which is effectively multiplied by a long rectangular window. This window introduces some spectral leakage, and unfortunately the decay of this spectral leakage for rectangular windows is less than 20dB/decade. The leakage from the stronger frequency components is thus masking the decay you are trying to observe.
To avoid this, you should multiply your signal by a different window function. There are plenty to experiment with (which offer different tradeoffs), but for illustration purposes you could use a blackman window with:
fft1 = fft(2*pi*F0*flicker .* blackman(length(flicker))');

Finding instantaneous frequency

I want to find instantaneous frequency over a window of a signal. I am taking a small part of the signal and trying to find the instantaneous frequency in that window. But that frequency is not matching with the actual frequency of the signal. Below is my code.
close all; clear all; clc
fs = 25000;
T = 0.5;
t = 0:1/fs:T;
n = length(t);
m = floor(n/4);
f1 = 100;
z1 = cos(2*pi*f1*t(1:m));
f1 = 200;
z2 = cos(2*pi*f1*t(1:m));
f1 = 300;
z3 = cos(2*pi*f1*t(1:m));
f1 = 400;
z4 = cos(2*pi*f1*t(1:(n-3*m)));
z = [z1 z2 z3 z4];
window = 100;
wStart = 1;
wEnd = wStart + window;
freqs = [];
while wEnd < length(z)
x = z(wStart:wEnd);
y = t(wStart:wEnd);
h=hilbert(x);
unrolled_phase = unwrap(angle(h));
dx = diff(unrolled_phase);
dy = diff(y);
p = dx./dy;
inst_freq = p/(2*pi) + 2*pi;
freqs = [freqs inst_freq];
wStart = wEnd;
wEnd = wStart + window;
end
The plot of 'freqs' is this:
I think there is something wrong with the way I am calculating the frequencies but I am not sure. Can anyone please help? I need to get the frequencies only as 100,200,300 and 400 as evident from the code. All I want to do is find the beginning point(time) of each frequency
The first, theoretical answer, is that a signal is really a combination of several frequencies. Also, if you are decomposing a signal into ranges of 100 Hz with bins of 100Hz, 200Hz, 300Hz, etc. then you will NOT be able to recreate the signal into exactly the same signal that was transformed. That is, an inverse transform can only use 4 freqs, and will combine in a way such that the input signal and recovered signal do NOT sound the same!

Working on Separable Gabor filters in matlab

A filter g is called separable if it can be expressed as the multiplication of two vectors grow and gcol . Employing one dimensional filters decreases the two dimensional filter's computational complexity from O(M^2 N^2) to O(2M N^2) where M and N are the width (and height) of the filter mask and the image respectively.
In this stackoverflow link, I wrote the equation of a Gabor filter in the spatial domain, then I wrote a matlab code which serves to create 64 gabor features.
According to the definition of separable filters, the Gabor filters are parallel to the image axes - theta = k*pi/2 where k=0,1,2,etc.. So if theta=pi/2 ==> the equation in this stackoverflow link can be rewritten as:
The equation above is extracted from this article.
Note: theta can be extented to be equal k*pi/4. By comparing to the equation in this stackoverflow link, we can consider that f= 1 / lambda.
By changing my previous code in this stackoverflow link, I wrote a matlab code to make the Gabor filters separable by using the equation above, but I am sure that my code below is not correct especially when I initialized the gbp and glp equations. That is why I need your help. I will appreciate your help very much.
Let's show now my code:
function [fSiz,filters1,filters2,c1OL,numSimpleFilters] = init_gabor(rot, RF_siz)
image=imread('xxx.jpg');
image_gray=rgb2gray(image);
image_gray=imresize(image_gray, [100 100]);
image_double=double(image_gray);
rot = [0 45 90 135]; % we have four orientations
RF_siz = [7:2:37]; %we get 16 scales (7x7 to 37x37 in steps of two pixels)
minFS = 7; % the minimum receptive field
maxFS = 37; % the maximum receptive field
sigma = 0.0036*RF_siz.^2 + 0.35*RF_siz + 0.18; %define the equation of effective width
lambda = sigma/0.8; % it the equation of wavelength (lambda)
G = 0.3; % spatial aspect ratio: 0.23 < gamma < 0.92
numFilterSizes = length(RF_siz); % we get 16
numSimpleFilters = length(rot); % we get 4
numFilters = numFilterSizes*numSimpleFilters; % we get 16x4 = 64 filters
fSiz = zeros(numFilters,1); % It is a vector of size numFilters where each cell contains the size of the filter (7,7,7,7,9,9,9,9,11,11,11,11,......,37,37,37,37)
filters1 = zeros(max(RF_siz),numFilters);
filters2 = zeros(numFilters,max(RF_siz));
for k = 1:numFilterSizes
for r = 1:numSimpleFilters
theta = rot(r)*pi/180;
filtSize = RF_siz(k);
center = ceil(filtSize/2);
filtSizeL = center-1;
filtSizeR = filtSize-filtSizeL-1;
sigmaq = sigma(k)^2;
for x = -filtSizeL:filtSizeR
fx = exp(-(x^2)/(2*sigmaq))*cos(2*pi*x/lambda(k));
f1(x+center,1) = fx;
end
for y = -filtSizeL:filtSizeR
gy = exp(-(y^2)/(2*sigmaq));
f2(1,y+center) = gy;
end
f1 = f1 - mean(mean(f1));
f1 = f1 ./ sqrt(sum(sum(f1.^2)));
f2 = f2 - mean(mean(f2));
f2 = f2 ./ sqrt(sum(sum(f2.^2)));
p = numSimpleFilters*(k-1) + r;
filters1(1:filtSize,p)=f1;
filters2(p,1:filtSize)=f2;
convv1=imfilter(image_double, filters1(1:filtSize,p),'conv');
convv2=imfilter(double(convv1), filters2(p,1:filtSize),'conv');
figure
imagesc(convv2);
colormap(gray);
end
end
I think the code is correct provided your previous version of Gabor filter code is correct too. The only thing is that if theta = k * pi/4;, your formula here should be separated to:
fx = exp(-(x^2)/(2*sigmaq))*cos(2*pi*x/lambda(k));
gy = exp(-(G^2 * y^2)/(2*sigmaq));
To be consistent, you may use
f1(1,x+center) = fx;
f2(y+center,1) = gy;
or keep f1 and f2 as it is but transpose your filters1 and filters2 thereafter.
Everything else looks good to me.
EDIT
My answer above works for theta = k * pi/4;, with other angles, based on your paper,
x = i*cos(theta) - j*sin(theta);
y = i*sin(theta) + j*cos(theta);
fx = exp(-(x^2)/(2*sigmaq))*exp(sqrt(-1)*x*cos(theta));
gy = exp(-(G^2 * y^2)/(2*sigmaq))*exp(sqrt(-1)*y*sin(theta));
The final code will be:
function [fSiz,filters1,filters2,c1OL,numSimpleFilters] = init_gabor(rot, RF_siz)
image=imread('xxx.jpg');
image_gray=rgb2gray(image);
image_gray=imresize(image_gray, [100 100]);
image_double=double(image_gray);
rot = [0 45 90 135];
RF_siz = [7:2:37];
minFS = 7;
maxFS = 37;
sigma = 0.0036*RF_siz.^2 + 0.35*RF_siz + 0.18;
lambda = sigma/0.8;
G = 0.3;
numFilterSizes = length(RF_siz);
numSimpleFilters = length(rot);
numFilters = numFilterSizes*numSimpleFilters;
fSiz = zeros(numFilters,1);
filters1 = zeros(max(RF_siz),numFilters);
filters2 = zeros(numFilters,max(RF_siz));
for k = 1:numFilterSizes
for r = 1:numSimpleFilters
theta = rot(r)*pi/180;
filtSize = RF_siz(k);
center = ceil(filtSize/2);
filtSizeL = center-1;
filtSizeR = filtSize-filtSizeL-1;
sigmaq = sigma(k)^2;
for x = -filtSizeL:filtSizeR
fx = exp(-(x^2)/(2*sigmaq))*exp(sqrt(-1)*x*cos(theta));
f1(1, x+center) = fx;
end
for y = -filtSizeL:filtSizeR
gy=exp(-(y^2)/(2*sigmaq))*exp(sqrt(-1)*y*sin(theta));
f2(y+center,1) = gy;
end
f1 = f1 - mean(mean(f1));
f1 = f1 ./ sqrt(sum(sum(f1.^2)));
f2 = f2 - mean(mean(f2));
f2 = f2 ./ sqrt(sum(sum(f2.^2)));
p = numSimpleFilters*(k-1) + r;
filters1(1:filtSize,p)=f1;
filters2(p,1:filtSize)=f2;
convv1=imfilter(image_double, filters1(1:filtSize,p),'conv');
convv2=imfilter(double(convv1), filters2(p,1:filtSize),'conv');
figure
imagesc(imag(convv2));
colormap(gray);
end
end

does white noise without mean zero do some changes?

again my question is related to white noise ,but with different meaning.let us compare following two code.first
function [ x ] = generate(N,m,A3)
f1 = 100;
f2 = 200;
T = 1./f1;
t = (0:(N*T/m):(N*T))'; %'
wn = rand(length(t),1).*2 - 1;
x = 20.*sin(2.*pi.*f1.*t) + 30.*cos(2.*pi.*f2.*t) + A3.*wn;
%[pks,locs] = findpeaks(x);
plot(x)
end
using generate(3,500,10)
graph of this code is following
but let us change our code so that it makes zero mean with white noise
function [ x ] = generate1(N,m,A3)
f1 = 100;
f2 = 200;
T = 1./f1;
t = (0:(N*T/m):(N*T))'; %'
wn = rand(length(t),1).*2 - 1;
mn=wn-mean(wn);
x = 20.*sin(2.*pi.*f1.*t) + 30.*cos(2.*pi.*f2.*t) + A3.*mn;
%[pks,locs] = findpeaks(x);
plot(x)
end
and graph is following
if we compare these two picture,we could say that it is almost same,just some changes,so does matter if we make zero mean or not?for real analysis,like for finding
peaks and so on.thanks very much
UPDATED:
there is updated code
function [ x ] = generate1(N,m,A3)
f1 = 100;
f2 = 200;
T = 1./f1;
t = (0:(N*T/m):(N*T))'; %'
wn = randn(length(t),1); %zero mean variance 1
x = 20.*sin(2.*pi.*f1.*t) + 30.*cos(2.*pi.*f2.*t) + A3.*wn;
%[pks,locs] = findpeaks(x);
plot(x)
end
and it's picture
Your initial noise is uniformly distributed between -1 & +1
Your second noise is also uniformly disributed between -1 & +1, because mean is already zero, subtracting it is meaningless
in order to obtain white noise you can use randn() function:
wn = randn(length(t),1); %zero mean variance 1
You may not observe any much difference again if your noise coefficient A3 has a much lower value compared to 20 & 30 which are the coefficients of your signal.
In order to find peaks, adding noise may not serve any purpose because noise tends to decrease the information content of signals
What is the value of mean(wm)? If it is close to zero, then no, it does not matter.
Technically, white noise has zero mean by definition.