FIR filter length is the intercept included as a coefficient?-- Matlab - matlab

I have some confusion about the terminologies and simulation of an FIR system. I shall appreciate help in rectifying my mistakes and informing what is correct.
Assuming a FIR filter with coefficient array A=[1,c2,c3,c4]. The number of elements are L so the length of the filter L but the order is L-1.
Confusion1: Is the intercept 1 considered as a coefficient? Is it always 1?
Confusion2: Is my understanding correct that for the given example the length L= 4 and order=3?
Confusion3: Mathematically, I can write it as:
where u is the input data and l starts from zero. Then to simulate the above equation I have done the following convolution. Is it correct?:
N =100; %number of data
A = [1, 0.1, -0.5, 0.62];
u = rand(1,N);
x(1) = 0.0;
x(2) = 0.0;
x(3) = 0.0;
x(4) = 0.0;
for n = 5:N
x(n) = A(1)*u(n) + A(2)*u(n-1)+ A(3)*u(n-3)+ A(4)*u(n-4);
end

Confusion1: Is the intercept 1 considered as a coefficient? Is it always 1?
Yes it is considered a coefficient, and no it isn't always 1. It is very common to include a global scaling factor in the coefficient array by multiplying all the coefficients (i.e. scaling the input or output of a filter with coefficients [1,c1,c2,c2] by K is equivalent to using a filter with coefficients [K,K*c1,K*c2,K*c3]). Also note that many FIR filter design techniques generate coefficients whose amplitude peaks near the middle of the coefficient array and taper off at the start and end.
Confusion2: Is my understanding correct that for the given example the length L= 4 and order = 3?
Yes, that is correct
Confusion3: [...] Then to simulate the above equation I have done the following convolution. Is it correct? [...]
Almost, but not quite. Here are the few things that you need to fix.
In the main for loop, applying the formula you would increment the index of A and decrement the index of u by 1 for each term, so you would actually get x(n) = A(1)*u(n) + A(2)*u(n-1)+ A(3)*u(n-2)+ A(4)*u(n-3)
You can actually start this loop at n=4
The first few outputs should still be using the formula, but dropping the terms u(n-k) for which n-k would be less than 1. So, for x(3) you'd be dropping 1 term, for x(2) you'd be dropping 2 terms and for x(1) you'd be dropping 3 terms.
The modified code would look like the following:
x(1)=A(1)*u(1);
x(2)=A(1)*u(2) + A(2)*u(1);
x(3)=A(1)*u(3) + A(2)*u(2) + A(3)*u(1);
for n = 4:N
x(n) = A(1)*u(n) + A(2)*u(n-1)+ A(3)*u(n-2)+ A(4)*u(n-3);
end

Related

Implementing a Function using for-loops and matrix multiplication in matlab

My goal is to implement a function which performs fourier synthesis in matlab, as part of learning the language. The function implements the following expression:
y = sum(ak*exp((i*2*pi*k*t)/T)
where k is the index, ak is a vector of fourier coefficients, t is a time vector of sampled times, and T is the period of the signal.
I have tried something like this:
for counter = -N:1:N
k = y+N+1;
y(k) = ak(k)*exp((i*2*pi*k*t)/T);
% y is a vector of length 2N+1
end
However, this gives me an error that the sides do not have equal numbers of items within them. This makes sense to me, since t is a vector of arbitrary length, and thus I am trying to make y(k) equal to numerous things rather than one thing. Instead, I suspect I need to try something like:
for counter = -N:1:N
k=y+N+1;
for t = 0:1/fs:1
%sum over t elements for exponential operation
end
%sum over k elements to generate y(k)
end
However, I'm supposedly able to implement this using purely matrix multiplication. How could I do this? I've tried to wrap my head around what Matlab is doing, but honestly, it's so far from the other languages I know that I don't really have any sense of what matlab's doing under the hood. Understanding how to change between operations on matrices and operations in for loops would be profoundly helpful.
You can use kron to reach your goal without for loops, i.e., matrix representation:
y = a*exp(1j*2*pi*kron(k.',t)/T);
where a,k and t are all assumed as row-vectors
Example
N = 3;
k = -N:N;
t = 1:0.5:5;
T = 15;
a = 1:2*N+1;
y = a*exp(1j*2*pi*kron(k.',t)/T);
such that
y =
Columns 1 through 6:
19.1335 + 9.4924i 10.4721 + 10.6861i 2.0447 + 8.9911i -4.0000 + 5.1962i -6.4721 + 0.7265i -5.4611 - 2.8856i
Columns 7 through 9:
-2.1893 - 4.5489i 1.5279 - 3.9757i 4.0000 - 1.7321i

summation of exponential distribution with different parameters

I just calculated a summation of two exponential distritbution with different lambda.
It's known that summmation of exponential distributions is Erlang(Gamma) distribution.
However, when lamdbas are different, result is a litte bit different.
Anyway look at the following equations.
Now, problem is (alpha_1 λ_2-alpha_2 λ_1).
(alpha_1 λ_2-alpha_2 λ_1) becomes 0
Thus, last two terms go to infinite....
Is that true??
I make some simple matlab code for verification.
clc;
clear;
mu=[1 2];
a1 = mu(1)/(mu(1)+mu(2));
a2 = mu(2)/(mu(1)+mu(2));
n = 10^6;
x = exprnd(mu(1), [1, n]);
y = exprnd(mu(2), [1, n]);
z = a1*x + a2*y;
figure
histfit(z, 100 ,'gamma')`
The figure is pdf of Z=alpha_1 * X + alpha_2 * Y.
This case is λ_1 = 1, λ_1=2. (The red line is gamma distribution.)
The result of matlab shows random variable Z is not infinite value.
What is the problom in my calculations??
I got the problem in my integral calculation. In the 6th row, e^-(lambda2-alpha2*lambda1/alpha1) = 1, thus, there is no term alpha1/(alpha1*lambda2-alpha2*lambda1) in the 7th row.

Matlab : How to represent a real number as binary

Problem : How do I use a continuous map - The Link1: Bernoulli Shift Map to model binary sequence?
Concept :
The Dyadic map also called as the Bernoulli Shift map is expressed as x(k+1) = 2x(k) mod 1. In Link2: Symbolic Dynamics, explains that the Bernoulli Map is a continuous map and is used as the Shift Map. This is explained further below.
A numeric trajectory can be symbolized by partitioning into appropriate regions and assigning it with a symbol. A symbolic orbit is obtained by writing down the sequence of symbols corresponding to the successive partition elements visited by the point in its orbit. One can learn much about the dynamics of the system by studying its symbolic orbits. This link also says that the Bernoulli Shift Map is used to represent symbolic dynamics.
Question :
How is the Bernoulli Shift Map used to generate the binary sequence? I tried like this, but this is not what the document in Link2 explains. So, I took the numeric output of the Map and converted to symbols by thresholding in the following way:
x = rand();
y = mod(2* x,1) % generate the next value after one iteration
y =
0.3295
if y >= 0.5 then s = 1
else s = 0
where 0.5 is the threshold value, called the critical value of the Bernoulli Map.
I need to represent the real number as fractions as explained here on Page 2 of Link2.
Can somebody please show how I can apply the Bernoulli Shift Map to generate symbolized trajectory (also called time series) ?
Please correct me if my understanding is wrong.
How do I convert a real valued numeric time series into symbolized i.e., how do I use the Bernoulli Map to model binary orbit /time series?
You can certainly compute this in real number space, but you risk hitting precision problems (depending on starting point). If you're interested in studying orbits, you may prefer to work in a rational fraction representation. There are more efficient ways to do this, but the following code illustrates one way to compute a series derived from that map. You'll see the period-n definition on page 2 of your Link 2. You should be able to see from this code how you could easily work in real number space as an alternative (in that case, the matlab function rat will recover a rational approximation from your real number).
[EDIT] Now with binary sequence made explicit!
% start at some point on period-n orbit
period = 6;
num = 3;
den = 2^period-1;
% compute for this many steps of the sequence
num_steps = 20;
% for each step
for n = 1:num_steps
% * 2
num = num * 2;
% mod 1
if num >= den
num = num - den;
end
% simplify rational fraction
g = gcd(num, den);
if g > 1
num = num / g;
den = den / g;
end
% recover 8-bit binary representation
bits = 8;
q = 2^bits;
x = num / den * q;
b = dec2bin(x, bits);
% display
fprintf('%4i / %4i == 0.%s\n', num, den, b);
end
Ach... for completeness, here's the real-valued version. Pure mathematicians should look away now.
% start at some point on period-n orbit
period = 6;
num = 3;
den = 2^period-1;
% use floating point approximation
x = num / den;
% compute for this many steps of the sequence
num_steps = 20;
% for each step
for n = 1:num_steps
% apply map
x = mod(x*2, 1);
% display
[num, den] = rat(x);
fprintf('%i / %i\n', num, den);
end
And, for extra credit, why is this implementation fast but daft? (HINT: try setting num_steps to 50)...
% matlab vectorised version
period = 6;
num = 3;
den = 2^period-1;
x = zeros(1, num_steps);
x(1) = num / den;
y = filter(1, [1 -2], x);
[a, b] = rat(mod(y, 1));
disp([a' b']);
OK, this is supposed to be an answer, not a question, so let's answer my own questions...
It's fast because it uses Matlab's built-in (and highly optimised) filter function to handle the iteration (that is, in practice, the iteration is done in C rather than in M-script). It's always worth remembering filter in Matlab, I'm constantly surprised by how it can be turned to good use for applications that don't look like filtering problems. filter cannot do conditional processing, however, and does not support modulo arithmetic, so how do we get away with it? Simply because this map has the property that whole periods at the input map to whole periods at the output (because the map operation is multiply by an integer).
It's daft because it very quickly hits the aforementioned precision problems. Set num_steps to 50 and watch it start to get wrong answers. What's happening is the number inside the filter operation is getting to be so large (order 10^14) that the bit we actually care about (the fractional part) is no longer representable in the same double-precision variable.
This last bit is something of a diversion, which has more to do with computation than maths - stick to the first implementation if your interest lies in symbol sequences.
If you only want to deal with rational type of output, you'll first have to convert the starting term of your series into a rational number if it is not. You can do that with:
[N,D] = rat(x0) ;
Once you have a numerator N and a denominator D, it is very easy to calculate the series x(k+1)=mod(2*x(k), 1) , and you don't even need a loop.
for the part 2*x(k), it means all the Numerator(k) will be multiplied by successive power of 2, which can be done by matrix multiplication (or bsxfun for the lover of the function):
so 2*x(k) => in Matlab N.*(2.^(0:n-1)) (N is a scalar, the numerator of x0, n is the number of terms you want to calculate).
The Mod1 operation is also easy to translate to rational number: mod(x,1)=mod(Nx,Dx)/Dx (Nx and Dx being the numerator and denominator of x.
If you do not need to simplify the denominator, you could get all the numerators of the series in one single line:
xn = mod( N.*(2.^(0:n-1).'),D) ;
but for visual comfort, it is sometimes better to simplify, so consider the following function:
function y = dyadic_rat(x0,n)
[N,D] = rat(x0) ; %// get Numerator and Denominator of first element
xn = mod( N.*(2.^(0:n-1).'),D) ; %'// calculate all Numerators
G = gcd( xn , D ) ; %// list all "Greatest common divisor"
y = [xn./G D./G].' ; %'// output simplified Numerators and Denominators
If I start with the example given in your wiki link (x0=11/24), I get:
>> y = dyadic_rat(11/24,8)
y =
11 11 5 2 1 2 1 2
24 12 6 3 3 3 3 3
If I start with the example given by Rattus Ex Machina (x0=3/(2^6-1)), I also get the same result:
>> y = dyadic_rat(3/63,8)
y =
1 2 4 8 16 11 1 2
21 21 21 21 21 21 21 21

How can I generate correlated data in MATLAB, with a prespecified SD and mean?

I wish to create one vector of data points with a mean of 50 and a standard deviation of 1. Then, I wish to create a second vector of data points again with a mean of 50 and a standard deviation of 1, and with a correlation of 0.3 with the first vector. The number of data points doesn't really matter but ideally I would have 100.
The method mentioned at Generating two correlated random vectors does not answer my question because (due to random sampling) the SDs and means deviate too much from the desired number.
I worked out a way, though it is ugly. I would still welcome an answer that detailed a more elegant method to get what I want.
z = 0;
while z < 1
mu = 50
sigma = 1
M = mu + sigma*randn(100,2);
R = [1 0.3; 0.3 1];
L = chol(R)
M = M*L;
x = M(:,1);
y = M(:,2);
if (corr(x,y) < 0.301 & corr(x,y) > 0.299) & (std(x) < 1.01 & std(x) > 0.99) & (std(y) < 1.01 & std(y) > 0.99);
z = 1;
end
end
I then calculated how the mean of vector y and calculated how much higher than 50 it was. I then subtracted that number from every element in vector y so that the mean was reduced to 50.
You can create both vectors together... I dont understand the reason you define them separatelly. This is the concept of multivariate distribution (just to be sure that we have the same jargon)...
Anyway, I guess you are almost already there to what I call the simplest way to do that:
Method 1:
Use matlab function mvnrnd [Remember that mvnrnd uses the covariance matrix that can be calculated from the correlation and the variance)
Method 2:
I am not very sure, but I think it is very close to what you are doing (actually my doubt is related to the if (corr(x,y) < 0.301 & corr(x,y) > 0.299) & (std(x) < 1.01 & std(x) > 0.99) & (std(y) < 1.01 & std(y) > 0.99)) I dont understand the reason you have to do that. See the topic "Drawing values from the distribution" in wikipedia Multivariate normal distribution.

Low Pass Filter Matlab

Is there a way in matlab to create a low pass filter, I know i can use the filter function but not sure how to use it, I've been given the following formula for my low pass H(z) = 1 (1 - z^-4)^2 / 16 (1 - z^-1)^2 with a 20Hz cutoff frequency
The filter function allows you to apply a filter to a vector. You still need to provide the filter coefficients. If you look at the documentation for filter, you see that you need to specify two vectors b and a whose elements are coefficients of z in descending powers, where z is the frequency domain variable in a z-transform. Since you have an expression for your filter given as a z-transform, the coefficients are easy to find. First, let's write the numerator of your filter:
(1/16)*(1 - z^-4)^2 = (1/16)*(1 - 2z^-4 + z^-16)
= (1/16)*(1 + 0z^-1 + 0z^-2 + 0z^-3 - 2z^-4 + 0z^5 + 0z^-6 ... + z^-16)
So the b vector is b = (1/16)*[1 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 1]. Similarly, the a vector is a = [1 -2 1]. So now you can filter your data vector x to get a result y by simply doing y = filter(b,a,x);.
Having said all that, the H(z) you specify above is definitely not a low pass filter. It's more like some weird cascade of a comb filter with itself.
If you want to design your own filter, and assuming you have the Signal Processing Toolbox, the absolute simplest thing to do is design a filter using Matlab's fir1 function:
h = fir1(N, 20/(Fs/2)); %# N is filter length, Fs is sampling frequency (Hz)
which you can then use in the filter function:
y = filter(h, 1, x); %# second param is 1 because this is an FIR filter
You will need to pick N yourself. Generally, larger N values make for better filters, where better = rejects more frequencies above 20 Hz. If your N value starts getting so big that it causes weird behavior (computational errors, slow implementations, unacceptable startup/ending transients in the resulting data) you might consider a more complicated filter design. The Mathworks documentation has an overview of the various digital filter design techniques.
The formula you have given: H(z) = 1 (1 - z^-4)^2 / 16 (1 - z^-1)^2 is the filter's Z-transform. It is a rational function, which means your filter is a recursive (IIR) filter.
Matlab has a function called filter(b,a,X). The b are the coefficients of the numerator with decreasing power of z, i.E. in your case: (1*z^-0 + 0*z^-1 + 0*z^-2 + 0*z^-3 + 0*z^-4)^2, you can use conv() for quantity square:
b = [1 0 0 0 -1]
b = conv(b,b)
and the coefficients of the denominator are:
a = [1 -1]
a = 16 * conv(a,a)
Then you call the filter y = filter(b,a,x), where x is your input data.
You can also check your filter's frequency response with freqz(b,a)
Hope that helped.