How to plot discrete signals (delta equation)? - matlab

Plot 2 discrete signals:
x[n] = delta[n] - delta[n-1] + delta[n+4]
y[n] = 0.5^n*u[n]
Also plot the convolution.
I don't know what the delta is supposed to be and how to approach these kind of signals. If I have a simple signal, I know how to do it.
n = 0:7;
x1 = cos(pi*n);
subplot(1,2,1)
stem(n,x1)

Using the dirac (delta) function in matlab will not work for discrete functions as the outcome is Inf at n=0. Instead use the value 1 at the right locations. Furthermore, u[n] is the step function or in matlab the heaviside function. It is zero for negative x and 1 for positive x, making a step at exactly x = 0.
The following code will plot all your functions:
n = -5:5
x = [0 1 0 0 0 1 1 0 0 0 0]; %x[n] from n =-5 to n=5
%y = 0.5.^n .* heaviside(n); %[y[n] from n =-5 to n=5
y = 0.5.^n .* [0 0 0 0 0 1 1 1 1 1 1]; %stepfunction from n =-5 to n=5
z = conv(x,y); %z[n] from n = -10 to n=10
subplot(3,1,1);stem(n,y1)
subplot(3,1,2);stem(n,y2)
subplot(3,1,3);stem(-10:10,y3)

It appears to the be the Dirac delta function. Which has a function in Matlab.
x = dirac(n)
Also, the convolution of two functions has a function.
w = conv(u,v)
Not knowing the interval you have for these, I can't say. I could generate some code. Also the function u is unknown.

Related

Octave Coding - I need help coding coefficients of polynomial

This question fairly easy doing it manually however, I am struggling to have this written in code.
There is a quartic polynomial:
P(x)=ax^4+bx^3+cx^2+dx+e
There is also a given matrix M:
5 0 -1 2 9
-2 -1 0 1 2
Which the first row gives P(x) and the second row gives the value of x.
Using the information in matrix M, find the coefficients:
a, b, c, d, e
I would know how to work this manually, subbing each column and solve simultaneously with the other columns to obtain a value for each coefficient or put it in a matrix.
I have an idea of what to do, but I don't know how to code it.
I do believe the last line would be linearsolve(M(,1),M(,2)) and thus be able to obtain each coefficient but I have no idea how to get to that line.
Welcome J Cheong
% Values of y and x (note: in your post you had 2 values at x = 1, I assumed that was an accident)
M = [5 0 -1 2 9 ; -2 -1 0 1 2];
% Separate for clarity
y = M(1,:);
x = M(2,:);
% Fit to highest order polynomial model
f = fit(x',y',['poly', num2str(length(y)-1)])
% Extract coefficients
coeff = coeffvalues(f);
% Plotting
X = linspace(min(x)-1, max(x) + 1, 1000) ;
plot(x,y,'.',X,f(X))
Edit
Sorry, I'm using Matlab. Looking at the Octave documentation. You should be able to get the coefficients using
p = polyfit(x,y,length(y)-1)';
Then to display the coefficients the way you specified try this
strcat(cellstr(char(96+(1:length(p))')), { ' = ' } , cellstr(num2str(p)))
y=[5 0 -1 2 9];
x=[-2 -1 0 1 2];
P=polyfit(x,y,2)
gives
P =
2.0000 1.0000 -1.0000
these are your coefficients for c,d,e the others are zero. You can check the result:
polyval(P, x)
ans =
5.0000e+00 2.2204e-16 -1.0000e+00 2.0000e+00 9.0000e+00
which gives you y
Btw, you can solve this very fast just inside your head without calculator because the function values for x=0 and x=+/-1 are very easy to calculate.

How to convert a rotation matrix to axis angle form?

theta=acos((trace(R)-1)/2);
if trace(R)==3
vec = [0 0 0];
axang=[0 0 0 0];
vec(1)=R(3,2)-R(2,3);
vec(2)=R(1,3)-R(3,1);
vec(3)=R(2,1)-R(1,2);
vec=(1/(2*sin(theta)))*vec;
axang = [vec, theta];
elseif trace(R)==-1
vec=[0 0 0;0 0 0];
axang=[0 0 0 0;0 0 0 0];
X=[0 0];
Y=[0 0];
Z=[0 0];
Y(1)=sqrt((R(2,2)+1)/2);
Y(2)=-Y(1);
X(1)=R(2,1)/(2*Y(1));
X(2)=R(2,1)/(2*Y(2));
Z(1)=R(2,3)/(2*Y(1));
Z(2)=R(2,3)/(2*Y(2));
vec(1,:)=[X(1) Y(1) Z(1)];
vec(2,:)=[X(2) Y(2) Z(2)];
axang(1,:)=[vec(1,:), theta];
axang(2,:)=[vec(2,:), theta];
else
vec = [0 0 0];
axang=[0 0 0 0];
vec(1)=R(3,2)-R(2,3);
vec(2)=R(1,3)-R(3,1);
vec(3)=R(2,1)-R(1,2);
vec=(1/(2*sin(theta)))*vec;
axang = [vec, theta];
end
So this was my code but it didn't work when the rotation matrix is
R = [-1 0 0;
0 -1 0;
0 0 1]
What is wrong with the code ? axang is a vector that stores axis in the first three positions and the angle in the last position.
It seems to me that you are looking for a conversion of a rotation matrix to quaternions, which is a built-in feature of Matlab if you installed the Robotics System Toolbox, i.e. rotm2quat:
axang = rotm2quat(R)
Note that the output format is slightly different as documented by Matlab:
Unit quaternion, returned as an n-by-4 matrix containing n
quaternions. Each quaternion, one per row, is of the form q = [w x y
z], with w as the scalar number.
Therefore you may need to swap the columns as follows:
axang = axang(:, [2 3 4 1]);
In a similar vein to the above answer you may wish to look into the use of the MatLab tool Translation1 = se2(StructuringElement, TranslationOffset).
The variable TranslationOffset can be applied as an angle in the form of 60*pi/180 for example.
In case of trace(R)==-1, the sign of axis term may be flipped. To get rid of it, following steps compute the axis angle vector.
find X(1) = sqrt((R(1,1)+1)/2);
if it is not zero, compute Y(1) = R(1,2)/(2*X(1)) and Y(2) = R(1,2)/(2*X(2)) and Z(1) = R(1,3)/(2*X(1)) Z(2) = R(1,3)/(2*X(2));
If X(1) = 0, then find Y(1) = sqrt((R(2,2)+1)/2)
if Y(1) is not zero then find the other terms from Y(1)
else find Z(1) and find the other terms from Z(1)

Matlab, Getting rid of for loop using one liner

Lets assume we have some code. In Matlab editor:
x = zeros(1,10);
x(1,1) = 2;
for k = 1: 9
x(k+1) = 10 * x(k);
end
Is it possible to write the equation without the for loop?
Try this:
x = 2 * 10.^(0:9);
Hope that helps.
Check out the logspace function:
x=2*logspace(0,9,10)
You have an error because it is contrary to the rules of matrix multiplication.
My solution below, I used the free analogue of Matlab - Octave, which has a similar syntax:
X=randint(2) % Matrix of size 2 by 2
X =
1 0
0 0
Y=2 * 10.^X(:)
Y =
20
2
2
2
You have a right to multiply the matrix only this type:
M x N on N x P
The result is a matrix of the following dimensions:
M x P
See also:
Element-wise multiplication
Element-wise power
I hope this helped

Solve function for real part = 0 instead of imaginary in MATLAB

I have a function which outputs a vector of complex eigenvalues. It takes a single argument, rho. I need to find a rho for which the complex eigenvalues lie on the imaginary axis. In other words, the real parts have to be 0.
When I run fzero() it throws the following error
Operands to the || and && operators must be convertible to logical scalar values.
Whereas fsolve() simply solves for the imaginary part = 0, which is exactly the oposite of what I want.
This is the function I wrote
function lambda = eigLorenz(rho)
beta = 8/3;
sigma = 10;
eta = sqrt(beta*(rho-1));
A = [ -beta 0 eta;0 -sigma sigma;-eta rho -1];
y = [rho-1; eta; eta];
% Calculate eigenvalues of jacobian
J = A + [0 y(3) 0; 0 0 0; 0 -y(1) 0]
lambda = eig(J)
It outputs 3 eigenvalues, 2 complex conjugates and 1 real eigenvalue (with complex part = 0).
I need to find rho for which the complex eigenvalues lie on the imaginary axis so that the real parts are 0.
Two problems:
fzero is only suited for scalar-valued functions (f: ℝ → ℝ)
complex numbers are single numbers, treated as signle entities by almost all functions. You'll have to force MATLAB to split up the complex number into its imaginary and real parts
So, one possible workaround is to take the real part of the first complex eigenvalue:
function [output, lambda] = eigLorenz(rho)
% Constants
beta = 8/3;
sigma = 10;
eta = sqrt(beta*(rho-1));
A = [-beta 0 eta
0 -sigma sigma
-eta rho -1];
y = [rho-1
eta
eta];
% Calculate eigenvalues of jacobian
J = A + [0 y(3) 0
0 0 0
0 -y(1) 0];
lambda = eig(J);
% Make it all work for all rho with FZERO(). Check whether:
% - the complex eigenvalues are indeed each other's conjugates
% - there are exactly 2 eigenvalues with nonzero imaginary part
complex = lambda(imag(lambda) ~= 0);
if numel(complex) == 2 && ...
( abs(complex(1) - conj(complex(2))) < sqrt(eps) )
output = real(complex(1));
else
% Help FZERO() get out of this hopeless valley
output = -norm(lambda);
end
end
Call like this:
rho = fzero(#eigLorenz, 0);
[~, lambda] = eigLorenz(rho);

How to zero pad a matlab array?

What is the easiest way to (zero) pad a matlab array?
i.e. given [1,2,3,4] and length 6 return [1,2,3,4,0,0]
Background
I have a data array which I would like to apply a windowing function to before running fft on the data.
I use to pass data directly to fft which would zero pad to the next power of 2, but now I need it zero padding before the fft so I can multiply by the window function.
fs = 100; % Sample frequency (Hz)
t = 0:1/fs:10-1/fs; % 10 sec sample
x = (1.3)*sin(2*pi*15*t) ... % 15 Hz component
+ (1.7)*sin(2*pi*40*(t-2)) ... % 40 Hz component
+ (2.5)*randn(size(t)); % Gaussian noise;
m = length(x); % Window length
n = pow2(nextpow2(m)); % Transform length
w = barthannwin( n ); % FFT Window
y = fft(data, n); % DFT
windowed_data = x*w ; % Dimensions do not match as x not padded
y = fft(windowed_data, n); % DFT
I am aware of padarray as part of the Image Processing Toolbox, which I do not have.
EDIT
This method is probably even better for vectors as it does not break when they are transposed, note that it will change the original vector which may not be desirable:
myVec = 1:7;
myVec(end+3)=0
Alternately you can just concatenate zeros and the vector that you have and create a new variable with it.
myVec = 1:7;
requiredpadding = 10-7;
myVecPadded=[myVec zeros(1,requiredpadding)]
There is no built in function to do padding, but here is a little function to pad vector x given a minimum length n.
function y = pad(x, n)
y = x;
if length(x) < n
y(n) = 0;
end
this should pad it with zeros to the nearest power of 2 for an array a:
a(2^ceil(log2(length(a))))=0;
The image-processing toolbox of Matlab has a built-in function to pad arrays padarray(A,dim,value
For your example:
A = [1, 2, 3, 4];
dimension = [0 1]; % pad with extra columns
size = 2; % how much to pad
B = padarray(A,size*dimension,'post') % 'post' says to pad at the end
% just for demonstration, let's pre-pad the first dimension (rows)
dimension = [1 0];
C = padarray(A,dimension,'pre') % just as an example
% or pad in both directions
dimension = [1 2];
D = padarray(A,dimension) % by default, it will pad both pre and post
returns
B =
1 2 3 4 0 0
C =
0 0 0 0
1 2 3 4
D =
0 0 0 0 0 0 0 0
0 0 1 2 3 4 0 0
0 0 0 0 0 0 0 0
You can also use this for multi-dimensional arrays, the dimension vector just needs to be extended correspondingly, i.e. dimension = [0 0 1] will extend in the 3rd dimension.