FFT in Octave/Matlab, Plot cos(x) and approximate with - matlab

I have to plot in a exercise cos(x) in Octave and interpolate it by
I plotted cos(x) with
fplot("[cos(x)]", [0, 2*pi])
n are equidistant supporting points on [0, 2*pi] that I calculate by
x = zeros(n,1);
for i=1:n
x(i,1)= (-1) + (i-1/2)*(2/n);
end
How do I plot the term to approximate it?

I am also confused about what is the question actually. I guess you want to plot that formula.
Have a row vector k = 0:(n/2 - 1) (suppose n even).
Then you need your d coefficients as a row vector of the same length. (I don't know from where you get them though)
Then define your column vector x (column vector is made from a row vector by transposing, e.g. x = x.')
Left term of the function is then
leftterm = sum(d .* exp(i * x * k), 2)
Right term:
rightterm = sum( fliplr(d) .* exp(- i * x * (k.+1)), 2)
Alltogether they give:
f = sum(d .* exp(i * x * k) + fliplr(d) .* exp(- i * x * (k .+ 1)), 2)
and you plot it with:
plot(x,f)

Related

How to compute CDF from a given PMF in Matlab

For a given PMF p=f(\theta) for \theta between 0 and 2\pi, i computed the CDF in Matlab as
theta=0:2*pi/n:2*pi
for i=1:n
cdf(i)=trapz(theta(1:i),p(1:i));
end
and the result is verified.
I tried to do the same with cumsum as cdf=cumsum(p)*(2*pi)/n but the result is wrong. why?
How can i compute the CDF if the given PMF is in 2D asp=f(\theta,\phi) ? Can i do it without going into detail as explained here ?
In 1D case you can use cumsum to get the vectorized version of loop (assuming that both theta and p are column vectors):
n = 10;
theta = linspace(0, 2*pi, n).';
p = rand(n,1);
cdf = [0; 0.5 * cumsum((p(1:n-1) + p(2:n)) .* diff(theta(1:n)))];
In 2D case the function cumsum will be applied two times, in vertical and horizontal directions:
nthet = 10;
nphi = 10;
theta = linspace(0, 2*pi, nthet).'; % as column vector
phi = linspace(0, pi, nphi); % as row vector
p = rand(nthet, nphi);
cdf1 = 0.5 * cumsum((p(1:end-1, :) + p(2:end, :)) .* diff(theta), 1);
cdf2 = 0.5 * cumsum((cdf1(:, 1:end-1) + cdf1(:, 2:end)) .* diff(phi), 2);
cdf = zeros(nthet, nphi);
cdf(2:end, 2:end) = cdf2;

Coordinate from 2 vectors

All,
Suppose I have two vectors U and V with 2 units and 1 unit length, respectively as shown in the sketch. The vector U is rotated by angle theta.
There are, at least two possible cases whereby vector U can go "up" or "down" as shown in the sketch.
My question is, having the above dataset is it possible to have a generic formula that can be transferred into Matlab to get the coordinate of point M?
the length of the vector U and V and angle theta are arbitrary.
Thank you!
There is a more efficient solution.
The coordinates of the endpoints of U are given by:
(U * cos(theta), U * sin(theta))
For any vector (x, y) the clockwise perpendicular direction (i.e. the second diagram "down") is (y, -x), and those of the anti-clockwise direction are minus these. Therefore the coordinates of M are given by:
Anti-clockwise ("up"): (U * cos(theta) - M * sin(theta), U * sin(theta) + M * cos(theta))
Clockwise ("down"): (U * cos(theta) + M * sin(theta), U * sin(theta) - M * cos(theta))
No need for calls to arctan or sqrt which are both very costly. Also you can compute sin/cos just once and use the results for both components.
From Pythogoras we know that
M = sqrt(U^2 + V^2)
angle between M and U is
alpha = arctan(V/U)
So then you know that the x- and y-coordinates for M are:
the "up" case:
M = (sqrt(U^2 + V^2)*cos(theta + sign(cosd(theta))*arctan(V/U)), sqrt(U^2 + V^2)*sin(theta + sign(cosd(theta))*arctan(V/U)))
the "down" case:
M = (sqrt(U^2 + V^2)*cos(theta - sign(cosd(theta))*arctan(V/U)), sqrt(U^2 + V^2)*sin(theta - sign(cosd(theta))*arctan(V/U)))
A second way to calculate this is to look add the length of U and V in the x and y direction, and sum them.
The coordinates of U are:
(Ucos(theta), Usin(theta))
To this coordinates we must add/substract the x-and y-coordinates of V. The length of V along x and y is:
(abs(sin(theta)), abs(cos(theta))
Whether one should add or substract these from U is dependent on theta. In general we can write Vup and Vdown as
Vup = (V*sign(-cos(theta))sin(theta), Vsign(cos(theta))*cos(theta))
Vdown = (V*sign(cos(theta))sin(theta), Vsign(-cos(theta))*cos(theta))
then we can alway add U to Vup and Vdown. Finally
Mup = U + Vup
Mdown = U + Vdown
Just another compact solution
theta = 30;
L = 2; % norm of U vector
U = L*[cosd(theta) ; sind(theta)];
Vup = [-U(2) ; U(1)] / L; % Normal vectors, unit length
Vdown = [U(2) ; -U(1)] / L;
Mup = U + Vup; % Two possible values of M
Mdown = U + Vdown;
% Bonus plot
figure
plot([0 U(1)] , [0 U(2)] , 'k-')
hold on; axis equal;
plot([0 Vup(1)]+U(1) , [0 Vup(2)]+U(2) , 'r-')
plot([0 Vdown(1)]+U(1) , [0 Vdown(2)]+U(2) , 'r-')
text(Mup(1),Mup(2),'M_u_p')
text(Mdown(1),Mdown(2),'M_d_o_w_n')
You can exploit the properties of the cross product of Uinit and Urot. The sign of the product will inform you on the orientation of the resulting vector.
Supposing that the origin is O(0,0), your initial vector is Uinit(x1,y1) and your final vector is Urot(x2,y2). Also M(x,y) can be calculated easily.
If you want to filter the rotated vectors Urot that ended up 'above' or 'below' M compared to the previous orientation of your triangle, you can take the following cross products:
M cross Uinit and M cross Urot.
If their sign is the same then the resulting rotated vector didn't cross the line OM and the opposite if the sign is different.

How plot a two-dimensional function in three-dimensional space with MATLAB?

I want to plot a two-dimensional function of the polar coordinates r and theta in three-dimensional cartesian coordinates. I have that (sorry about bad maths formatting, LaTeX not compatible, it seems)
f(r,theta) = r/2 * (cos(theta - pi/4) + sqrt(1 + 1/2 * cos(2*theta)))
Converting r and theta to cartesian coordinates
x = r * cos(theta), y = r * sin(theta)
Further, the domain is -1<r<1 and 0<theta<2 * pi, which I define by
r = -1:2/50:1;
and
theta = 0:2*pi/50:2*pi;
giving me two vectors of the same dimensions.
I can define the x and y values used for plotting as row vectors by
x = r. * cos(theta);
and
y = r. * sin(theta);
So now I need to define the z values, which will depend on the values of x and y. I thought I should make a 101x101 where each matrix element contains a data point of the final surface. But how should I do this? I thought about using a double for loop:
for i=1:numel(r)
for j=1:numel(theta)
z(i,j) = r(i)/2 .* cos(theta(j) - pi/4) + r(i).*sqrt(1 + 1/2 * cos(2.*theta(j)));
end
end
Then simply surf(z)
While this definitely gives me a surface, it gives me the incorrect surface! I don't know what is happening here. The incorrect surface is given in Figure 1, while the correct one is given in Figure 2. Can anyone help me out? For reference, the correct surface was plotted with GeoGebra, using
A = Function[<expression 1>, <Expresison 2>, <Expression 3>, <var 1>, <start>, <stop>, <var 2>, <start>, <stop>]
Figure 1. Incorrect surface.
Figure 2. Correct surface.
As others have said, you can use meshgrid to make this work.
Here's your example using gridded r and theta and an anonymous function to replace the double loop:
r = -1:2/50:1;
theta = 0:2*pi/50:2*pi;
% define anonymous function f(r,theta)
f = #(r,theta) r/2 .* (cos(theta - pi/4) + sqrt(1 + 1/2 .* cos(2.*theta)));
% generate grids for r and theta
[r, theta] = meshgrid(r,theta);
% calculate z from gridded r and theta
z = f(r,theta);
% convert r,theta to x,y and plot with surf
x = r.*cos(theta);
y = r.*sin(theta);
surf(x,y,z);
You need to use meshgrid to get matrix coordinates if you want to use surf. Taking your x and y (lower case), call
[X,Y] = meshgrid(x,y);
Then X and Y (upper case) will have the same values as you gave it, but laid out in the two-dimensional array as expected by surf. Loop over the indices here and compute your Z, which should have all(size(Z) == size(X)).
https://www.mathworks.com/help/matlab/ref/meshgrid.html

Matlab: Calculate intersection point of vector and analytical surface

I would like to compute the intersection point in R^3 of a vector given by
p + alpha * n where x is a spatial vector, n is another vector and alpha is a scalar to be determined.
the surface is given in analytical form by the formulation
f(x,y) = [x, y, z(x,y)] where z(x,y) can be an arbitrary nonlinear surface description
I set up a linearization:
[n1 n2 n3 ] (d_alpha)= [p1 + alpha*n1 - x]
[-1 0 -dz(x,y)/dx] (d_x) = [p2 + alpha*n2 - y]
[ 0 -1 -dz(x,y)/dx] (d_y) = [p3 + alpha*n3 - z(x,y)]
and search to iterate with starting values for alpha, x and y
However, I cant seem to converge here. Any idea where my mistake is?
Thanks in advance
You can write your equations as
x_line(a) = p1 + a * n1
y_line(a) = p2 + a * n2
z_line(a) = p3 + a * n3
z_plane(x, y) = fun(x, y)
Assuming that your problem has a unique solution, the height along the z-direction dz of the line above the plane, as a function of a is then
dz(a) = z_line(a) - fun(x_line(a), y_line(a))
= p3 + a * n3 - fun(p1 + a * n1, p2 + a * n2)
To find the intersection of the line with the plane, you simply have to find the value of a for which dz is zero. This can be done in Matlab using an anonymous function and fzero like so:
dz = #(a) = p3 + a * n3 - fun(p1 + a * n1, p2 + a * n2);
a_intersect = fzero(dz, a0);
where a0 is some (arbitrary) starting guess for a.
You might want read a bit about optical ray-tracing, I guess you might find some introductory university notes online. This is a pretty standard problem for finding e.g. the intersection of an optical ray and a curved lens or a parabolic mirror.

How to use summation in MATLAB?

I have a randomly generated vector, say A of length M.
Say:
A = rand(M,1)
And I also have a function, X(k) = sin(2*pi*k).
How would I find Y(k) which is summation of A(l)*X(k-l) as l goes from 0 to M?
Assume any value of k... But the answer should be summation of all M+1 terms.
Given M and k, this is how you can perform your summation:
A = rand(M+1,1); %# Create M+1 random values
Y = sin(2*pi*(k-(0:M)))*A; %# Use a matrix multiply to perform the summation
EDIT: You could even create a function for Y that takes k and A as arguments:
Y = #(k,A) sin(2*pi*(k+1-(1:numel(A))))*A; %# An anonymous function
result = Y(k,A); %# Call the function Y
A = rand(1, M + 1);
X = sin(2 * pi * (k - (0 : M)));
total = sum(A .* X);
You may be looking for the convolution of the vectors A and X:
Y = conv(A, X);
If you're trying to do a fourier transform, you should also look at fft.