MATLAB - How to plot recursion values? - matlab

I have a simple function f(x) = 2.5x * (1-x) that I want to plot values for recursively. I succeeded in developing a recursive function but do not know how to extract the recursion values to plot on a graph.
function [y] = orbits(x)
y = 2.5 * x .* (1 - x);
if x == 0
y = 0;
else
y = orbits(y)
end
I would largely appreciate any help as I am new to programming and being able to plot this function would help me a lot.
e.g.
>> orbits(0.1)
x =
0.1000
x =
0.2250
x =
0.4359
x =
0.6147
How do I extract those x's to plot?
Thanks!

You need to aggregate the results over the recursion. I added another parameter epsilon which determines when to stop the recursion:
function [y] = orbits(x,epsilon)
y = 2.5 * x .* (1 - x);
if abs(y-x) < epsilon
y = [];
else
y = [y,orbits(y,epsilon)];
end
end
Demo:
>>values = orbits(0.1,0.00001)
values =
Columns 1 through 10
0.2250 0.4359 0.6147 0.5921 0.6038 0.5981 0.6010 0.5995 0.6002 0.5999
Columns 11 through 15
0.6001 0.6000 0.6000 0.6000 0.6000
>>plot(values)

Related

Find rotation matrix with two vectors

I want to find the rotation matrix between two vectors.
[0;0;1] = R * [0.0023;0.0019;0.9899]
How do I find the 3*3 rotation matrix?
This is a simple rearrangement
% [0;0;1] = R * [0.0023;0.0019;0.9899];
% So ...
% [0;0;1] / [0.0023;0.0019;0.9899] = R
% This is a valid MATLAB command
R = [0;0;1] / [0.0023;0.0019;0.9899];
>> R =
[ 0 0 0
0 0 0
0 0 1.0102 ]
We can validate this result
R * [0.0023;0.0019;0.9899]
>> ans =
[0; 0; 1]
Your problem can be defined as a linear equation, say,
y = mx
where, y and x are matrices. Find m.
Solution:
m = x\y or m = mldivide(x,y)
Notice the backslash. It is not a forward slash / as Wolfie mentioned in his answer. For details see https://www.mathworks.com/help/matlab/ref/mldivide.html
Additional Details:
If x is a singular matrix, use pinv. See https://www.mathworks.com/help/matlab/ref/pinv.html for reference.

Laguerre's method to obtain poly roots

I have to write using Laguerre's method a piece of code to find real and complex roots of poly:
f(x)=a4x4+a3x3+a2x2+a1x+a0 , [a4 a3 a2 a1 a0]=[-2 5 5 2 1]
I got something:
function y = laguerre (x,coef)
tol = 10^(-10);
%polynomial order
n = length(coef);
i = 0;
while (abs(polyval(coef,x)) > tol)
i = i + 1
x
polyval(coef,x)
%second derivative
a=polyval(polyder(polyder(coef)), x);
%first derivative
b=polyval(polyder(coef), x);
%polynomial value
c=polyval(coef, x);
%square root
r = sqrt((n-1)*[(n-1)*b^2-n*a*c]);
d1 = b + r;
d2 = b - r;
%highest abs value denominator chosen
if (abs(d1) > abs(d2))
d = d1;
else
d = d2;
end
%next iteration value obtained
z = n*c/d;
x = x - z;
end
i = i + 1
x
polyval(coef,x)
y = x;
return
end
and I want to draw and/ or obtain my roots:
coef = [-2 5 5 2 1];
fh = #poly;
%diary on
%plot of the function
figure(1);
fplot(fh, [-500 500]);
hold on;
figure(2);
fplot(fh, [-1.5 3]);
hold on;
%roots obtained using MM2
%z1(1) = MM2(-500,coef);
%z1(2) = MM2(500,coef);
%z1(3) = MM2(1 + i, coef);
%z1(4) = MM2(0 - 2i, coef);
%roots obtained using Laguerre's
%z2(1) = laguerre(-500,coef);
z2(2) = laguerre(500,coef);
%z2(3) = laguerre(1 + i, coef);
%z2(4) = laguerre(0 - 2i, coef);
%additional points on plot
p = [z1(1) z2(2)];
plot(p,[0 0],'r*');
legend('function','zeros');
hold off;
figure(1);
plot(p,[0 0],'r*');
plot([-500 500],[0 0], 'b*');
legend('function','zeros','START points');
diary off;
hold off;
As you see, some part of code is commented because I really don't know how to move on. I got many warnings. I got one error in 1st part of the code. I am looking for some tips or direction what to do.
Your code works perfectly well, you should get the roots
x=-500 => x=-0.6694729, p(x)=-8.882D-16 in 9 steps
x= 500 => x=3.3489712, p(x)=1.621D-14 in 8 steps
x=1 + i => x=-0.0897491+i*0.4636332, p(x)=i*8.327D-17 in 4 steps
x=0 - 2i => x=-0.0897491-i*0.4636332, p(x)=i*5.551D-17 in 4 steps
To illustrate the bigger picture, the iteration map for the Laguerre method with initial values in [-4,4]+[-4,4]*i looks like
Every color shade represents one step. There is nothing nefarious in this polynomial preventing convergence of the method.
To compare with, the Halley iteration map is
and the Newton fractal

What is a quick way to compute the euclidean norm of two sets of vectors?

I know that MATLAB works better when most or everything is vectorized. I have two set of vectors X and T. For every vector x in X I want to compute:
this is because I want to compute:
which can be easily expressed as MATLAB linear algebra operations as I wrote above with a dot product. I am hoping that I can speed this up by having those vectors, instead of computing each f(x) with a for loop. Ideally I could have it all vectorized and compute:
I've been think about this for some time now, but it doesn't seem to be a a nice way were a function takes two vectors and computes the norm between each one of them, with out me having to explicitly write the for loop.
i.e. I've implemented the trivial code:
function [ f ] = f_start( x, c, t )
% Computes f^*(x) = sum_i c_i exp( - || x_i - t_i ||^2)
% Inputs:
% x = data point (D x 1)
% c = weights (K x 1)
% t = centers (D x K)
% Outputs:
% f = f^*(x) = sum_k c_k exp( - || x - t_k ||^2)
[~, K] = size(t);
f = 0;
for k=1:K
c_k = c(k);
t_k = t(:, k);
norm_squared = norm(x - t_k, 2)^2;
f = f + c_k * exp( -1 * norm_squared );
end
end
but I was hoping there was a less naive way to do this!
I think you want pdist2 (Statistics Toolbox):
X = [1 2 3;
4 5 6];
T = [1 2 3;
1 2 4;
7 8 9];
result = pdist2(X,T);
gives
result =
0 1.0000 10.3923
5.1962 4.6904 5.1962
Equivalently, if you don't have that toolbox, use bsxfun as follows:
result = squeeze(sqrt(sum(bsxfun(#minus, X, permute(T, [3 2 1])).^2, 2)));
Another method just for kicks
X = [1 2 3;
4 5 6].';
T = [1 2 3;
1 2 4;
7 8 9].';
tT = repmat(T,[1,size(X,2)]);
tX = reshape(repmat(X,[size(T,2),1]),size(tT));
res=reshape(sqrt(sum((tT-tX).^2)).',[size(T,2),size(X,2)]).'

Matlab calculate the product of an expression

I'm basicaly trying to find the product of an expression that goes like this:
(x-(N-1)/2).....(x+(N-1)/2) for even value of N
x is a value that I will set at the beginning that changes too but that is a different problem...
let's say for the sake of argument that for now x is a constant (ex x=1)
example for N=6
(x-5/2)(x-3/2)(x-1/2)(x+1/2)(x+3/2)*(x+5/2)
the idea was to create a row vector every element of which is each individual term (P(1)=x-5/2) (P(2)=x-3/2)...etc and then calculate its product
N=6;
x=1;
P=ones(1,N);
for k=(-N-1)/2:(N-1)/2
for n=1:N
P(n)=(x-k);
end
end
y=prod(P);
instead this creates a vector that takes only the first value of the epxression and then
repeats the same value at each cell.
there is obviously a fundamental problem with my loop but I just can't see it.
So if anyone can help with that OR suggest a better way to calculate the product I would be grateful.
Use vectorized commands
Why use a loop when you can use vectorized commands like prod?
y = prod(2 * x + [-N + 1 : 2 : N - 1]) / 2;
For convenience, you may want to define an anonymous function for it:
f = #(N,x) reshape(prod(bsxfun(#plus, 2 * x(:), -N + 1 : 2 : N - 1) / 2, 2), size(x));
Note that the function is compatible with a (row or column) vector input x.
Tests in MATLAB's Command Window
>> f(6, [2,2]')
ans =
-14.7656
4.9219
-3.5156
4.9219
-14.7656
>> f(6, [2,2])
ans =
-14.7656 4.9219 -3.5156 4.9219 -14.7656
Benchmark
Here is a comparison of rayreng's approach versus mine. The former emerges as the clear winner... :'( ...at least as N increases.
Varying N, fixed x
Fixed N (= 10), vector x of varying length
Fixed N (= 100), vector x of varying length
Benchmark code
function benchmark
% varying N, fixed x
clear all
n = logspace(2,4,20)';
x = rand(1000,1);
tr = zeros(size(n));
tj = tr;
for k = 1 : numel(n)
% rayreng's approach (poly/polyval)
fr = #() rayreng(n(k), x);
tr(k) = timeit(fr);
% Jubobs's approach (prod/reshape/bsxfun)
fj = #() jubobs(n(k), x);
tj(k) = timeit(fj);
end
figure
hold on
plot(n, tr, 'bo')
plot(n, tj, 'ro')
hold off
xlabel('N')
ylabel('time (s)')
legend('rayreng', 'jubobs')
end
function y = jubobs(N,x)
y = reshape(prod(bsxfun(#plus,...
2 * x(:),...
-N + 1 : 2 : N - 1) / 2,...
2),...
size(x));
end
function y = rayreng(N, x)
p = poly(linspace(-(N-1)/2, (N-1)/2, N));
y = polyval(p, x);
end
function benchmark2
% fixed N, varying x
clear all
n = 100;
nx = round(logspace(2,4,20));
tr = zeros(size(n));
tj = tr;
for k = 1 : numel(nx)
disp(k)
x = rand(nx(k), 1);
% rayreng's approach (poly/polyval)
fr = #() rayreng(n, x);
tr(k) = timeit(fr);
% Jubobs's approach (prod/reshape/bsxfun)
fj = #() jubobs(n, x);
tj(k) = timeit(fj);
end
figure
hold on
plot(nx, tr, 'bo')
plot(nx, tj, 'ro')
hold off
xlabel('number of elements in vector x')
ylabel('time (s)')
legend('rayreng', 'jubobs')
title(['n = ' num2str(n)])
end
function y = jubobs(N,x)
y = reshape(prod(bsxfun(#plus,...
2 * x(:),...
-N + 1 : 2 : N - 1) / 2,...
2),...
size(x));
end
function y = rayreng(N, x)
p = poly(linspace(-(N-1)/2, (N-1)/2, N));
y = polyval(p, x);
end
An alternative
Alternatively, because the terms in your product form an arithmetic progression (each term is greater than the previous one by 1/2), you can use the formula for the product of an arithmetic progression.
I agree with #Jubobs in that you should avoid using for loops for this kind of computation. There are cases where for loops perform fast, but for something as simple as this, avoid using loops if possible.
An alternative approach to what Jubobs has suggested is that you can consider that polynomial equation to be in factored form where each factor denotes a root located at that particular location. You can use poly to convert these factors into a polynomial equation, then use polyval to evaluate the expression at the point you want. First, generate your roots by linspace where the points vary from -(N-1)/2 to (N-1)/2 and there are N of them, then plug this into poly. Finally, for any values of x, put this into polyval with the output of poly. The advantage of this approach is that you can evaluate multiple points of x in a single sweep.
Going with what you have, you would simply do this:
p = poly(linspace(-(N-1)/2, (N-1)/2, N));
out = polyval(p, x);
With your example, supposing that N = 6, this would be the output of the first line:
p =
1.0000 0 -8.7500 0 16.1875 0 -3.5156
As such, this is saying that when we expand out (x-5/2)(x-3/2)(x-1/2)(x+1/2)(x+3/2)(x+5/2), we get:
x^6 - 8.75x^4 + 16.1875x^2 - 3.5156
If we take a look at the roots of this equation, this is what we get:
r = roots(p)
r =
-2.5000
2.5000
-1.5000
1.5000
-0.5000
0.5000
As you can see, each term corresponds to one factor in your polynomial equation, so we do have the right mindset here. Now, all you have to do is use p with your values of x into polyval to obtain your results. For example, if I wanted to evaluate that polynomial from -2 <= x <= 2 where x is an integer, this is the result I get:
polyval(p, -2:2)
ans =
-14.7656 4.9219 -3.5156 4.9219 -14.7656
Therefore, when x = -2, the result is -14.7656 and so on.
Though I would recommend the solution by #Jubobs, it is also good to check what the issue is with your loop.
The first indication that something is wrong, is that you have a nested loop over 2 variables, and only index with one of them to store the result. Probably you just need a single loop.
Here is a loop that you may be interested in that should do roughly what you need:
N=6;
x=1;
k=(-N-1)/2:(N-1)/2
P = ones(size(k));
for n=1:numel(k)
P(n)=(x-k(n));
end
y=prod(P);
I tried to keep the code close to the original, so hopefully it is easy to understand.

Triangulation & Direct linear transform

Following Hartley/Zisserman's Multiview Geometery, Algorithm 12: The optimal triangulation method (p318), I got the corresponding image points xhat1 and xhat2 (step 10). In step 11, one needs to compute the 3D point Xhat. One such method is Direct Linear Transform (DLT), mentioned in 12.2 (p312) and 4.1 (p88).
The homogenous method (DLT), p312-313, states that it finds a solution as the unit singular vector corresponding to the smallest singular value of A, thus,
A = [xhat1(1) * P1(3,:)' - P1(1,:)' ;
xhat1(2) * P1(3,:)' - P1(2,:)' ;
xhat2(1) * P2(3,:)' - P2(1,:)' ;
xhat2(2) * P2(3,:)' - P2(2,:)' ];
[Ua Ea Va] = svd(A);
Xhat = Va(:,end);
plot3(Xhat(1),Xhat(2),Xhat(3), 'r.');
However, A is a 16x1 matrix, resulting in a Va that is 1x1.
What am I doing wrong (and a fix) in getting the 3D point?
For what its worth sample data:
xhat1 =
1.0e+009 *
4.9973
-0.2024
0.0027
xhat2 =
1.0e+011 *
2.0729
2.6624
0.0098
P1 =
699.6674 0 392.1170 0
0 701.6136 304.0275 0
0 0 1.0000 0
P2 =
1.0e+003 *
-0.7845 0.0508 -0.1592 1.8619
-0.1379 0.7338 0.1649 0.6825
-0.0006 0.0001 0.0008 0.0010
A = <- my computation
1.0e+011 *
-0.0000
0
0.0500
0
0
-0.0000
-0.0020
0
-1.3369
0.2563
1.5634
2.0729
-1.7170
0.3292
2.0079
2.6624
Update Working code for section xi in algorithm
% xi
A = [xhat1(1) * P1(3,:) - P1(1,:) ;
xhat1(2) * P1(3,:) - P1(2,:) ;
xhat2(1) * P2(3,:) - P2(1,:) ;
xhat2(2) * P2(3,:) - P2(2,:) ];
A(1,:) = A(1,:)/norm(A(1,:));
A(2,:) = A(2,:)/norm(A(2,:));
A(3,:) = A(3,:)/norm(A(3,:));
A(4,:) = A(4,:)/norm(A(4,:));
[Ua Ea Va] = svd(A);
X = Va(:,end);
X = X / X(4); % 3D Point
As is mentioned in the book (sec 12.2), pi T are the rows of P. Therefore, you don't need to transpose P1(k,:) (i.e. the right formulation is A = [xhat1(1) * P1(3,:) - P1(1,:) ; ...).
I hope that was just a typo.
Additionally, it is recommended to normalize each row of A with its L2 norm, i.e. for all i
A(i,:) = A(i,:)/norm(A(i,:));
And if you want to plot the triangulated 3D points, you have to normalize Xhat before plotting (its meaningless otherwise), i.e.
Xhat = Xhat/Xhat(4);
A(1,:) = A(1,:)/norm(A(1,:));
A(2,:) = A(2,:)/norm(A(2,:));
A(3,:) = A(3,:)/norm(A(3,:));
A(4,:) = A(4,:)/norm(A(4,:));
Could be simplified as A = normr(A).