Consider a difference equation with its initial conditions.
5y(n) + y(n-1) - 3y(n-2) = (1/5^n) u(n), n>=0
y(n-1) = 2, y(n-2) = 0
How can I determine y(n) in Matlab?
Use an approach similar to this (using filter), but specifying initial conditions as done here (using filtic).
I'm assuming your initial conditions are: y(-1)=2, y(-2)=0.
num = 1; %// numerator of transfer function (from difference equation)
den = [5 1 -3]; %// denominator of transfer function (from difference equation)
n = 0:100; %// choose as desired
x = (1/5).^n; %// n is >= 0, so u(n) is 1
y = filter(num, den, x, filtic(num, den, [2 0], [0 0]));
%// [2 0] reflects initial conditions on y, and [0 0] those on x.
Here's a plot of the result, obtained with stem(n,y).
The second line of your code does not give initial conditions, because it refers to the index variable n. Since Matlab only allows positive integer indices, I'll assume that you mean y(1) = 0 and y(2) = 2.
You can get an iteration rule out of your first equation by simple algebra:
y(n) = ( (1/5^n) u(n) - y(n-1) + 3y(n-2) ) / 5
Code to apply this rule in Matlab:
n_max = 100;
y = nan(n_max, 1);
y(1) = 0;
y(2) = 2;
for n = 3 : n_max
y(n) = ( (1/5^n) * u(n) - y(n-1) + 3 * y(n-2) ) / 5;
end
This code assumes that the array u is already defined. n_max specifies how many elements of y to compute.
Related
I have a problem with MatLab in Octave
I need to make a program, which solves a Triangular system of linear equations, using back substitution method (https://i.stack.imgur.com/ETPxn.png)
I have a problem with my code, Octave displays this error:
error: =: nonconformant arguments (op1 is 1x1, op2 is 2x2)
error: called from
backsub at line 6 column 10
prog31 at line 3 column 1
run at line 93 column 5
Here is my code:
Backsub function (backsub.m)
function X = backsub(A,B)
n = length(B);
X = zeros(n, 1);
X(n) = B(n)./A(n,n);
for k = n-1:-1:1
X(k) = (B(k)-A(k,k+1:n)+X(k+1:n))./A(k,k);
end
Main function (prog31.m)
A = [3 -2 1 -1; 0 4 -1 2; 0 0 2 3; 0 0 0 5];
B = [8; -3; 11; 15];
X = backsub(A, B);
disp(X);
You mistyped * as + in the for-loop, hence the error. This is the fix:
function X = backsub(A,B)
n = length(B);
X = zeros(n, 1);
X(n) = B(n)/A(n,n); % remove . because A(n,n) is scalar
for k = flip(1:n-1)
X(k) = (B(k)-(A(k,k+1:n)*X(k+1:n)))/A(k,k); % remove . and replace + with *
end % end the for loop
end
As a side note: The product in the for-loop is a dot product, because A(k,k+1:n) is a row vector while X(k+1:n) is a column vector of appropriate size.
If you want to use provided formula verbatim (with the sigma sum), it would be
X(k) = (B(k)-sum(A(k,k+1:n)'.*X(k+1:n)))/A(k,k);
I'm trying to implement this kernel function
which is also known as radial basis function. Suppose that a = 2, b = 1 and σ = 150.
Xi is a 425x3 matrix
Xj is a 4x3 matrix
I've came up with this code but I'm not sure that is correct. Can you help me?
kS = exp( - (pdist2(Xj,Xi).^2) / (sigma^2) )
Note: the original answer was completely redefined, because I misinterpreted the definition of the problem.
The evaluation of the kernel distance between Xi and Xj is presented below. Two codes that implement the algorithm are presented. The first code is inefficient but can be easily related to the definition of the kernel distance. The second code is much more efficient, but may not be as clear due to several vectorisation tricks.
The code assumes the following interpretation of the problem:
Xi and Xj are 2 data sets that contain 425 and 4 points, respectively. Each point belongs to R^3 (real vector space with dimension 3).
The kernel distance between two data sets is calculated according to the definition given in the article by J.M. Phillips and S. Venkatasubramanian "A Gentle Introduction to the Kernel Distance" that can be found at the following link. The definition is also provided below:
The most straightforward implementation of the algorithm:
% Initialisation.
clear;
clc;
% Construct Xi.
Xi = [randn(425, 1) randn(425, 1) randn(425, 1)];
% Definition of Xj.
Xj = [0.1 0.2 0.3; 0 0 0; -0.1 -0.1 -0.2; 1 -8 4];
% Convert to cell arrays.
Xi = mat2cell(Xi, ones(1, length(Xi(:, 1))), 3);
Xj = mat2cell(Xj, ones(1, length(Xj(:, 1))), 3);
% First, construct the kernel function for the evaluation of individual
% points in Xi and Xj
omega = 150;
a = 2;
kerFunction = #(xi, xj) exp(sum(abs(xi - xj).^a)/(omega^2));
kerDist = 0;
for i = 1 : length(Xj)
for j = 1 : length(Xj)
kerDist = kerDist + kerFunction(Xj{i}, Xj{j});
end
end
for i = 1 : length(Xi)
for j = 1 : length(Xi)
kerDist = kerDist + kerFunction(Xi{i}, Xi{j});
end
end
for i = 1 : length(Xi)
for j = 1 : length(Xj)
kerDist = kerDist - 2*kerFunction(Xi{i}, Xj{j});
end
end
A more efficient implementation of the algorithm is presented below:
clear;
% Define constants.
omega = 150;
a = 2;
% Definition of Xi.
Xi = [randn(425, 1) randn(425, 1) randn(425, 1)];
% Definition of Xj.
Xj = [0.1 0.2 0.3; 0 0 0; -0.1 -0.1 -0.2; 1 -8 4];
% Definition of the characteristics of the data sets.
numPointsXj = length(Xj(:, 1));
numPointsXi = length(Xi(:, 1));
% Define a handle function for the definition of indices for the
% vectorisation of the kernel function.
hdlRepIdxPermutation = #(numPoints, numMatrixRep) ...
repmat( ...
(1 : numPoints : numPoints*(numMatrixRep - 1) + 1)', ...
1, numPoints ...
) + ...
repmat(0 : (numPoints - 1), numMatrixRep, 1);
tic
% Calculate the term that corresponds to K(p, p') in the definition of the
% kernal distance.
repXiRight = repmat(Xi, numPointsXi, 1);
leftIdxPermutationXi = hdlRepIdxPermutation(numPointsXi, numPointsXi);
repXiLeft = repXiRight(leftIdxPermutationXi(:), :);
kerDistComp1 = sum(exp(sum(abs(repXiLeft - repXiRight).^a, 2)/(omega^2)));
% Calculate the term that corresponds to K(q, q') in the definition of the
% kernal distance.
repXjRight = repmat(Xj, numPointsXj, 1);
leftIdxPermutationXj = hdlRepIdxPermutation(numPointsXj, numPointsXj);
repXjLeft = repXjRight(leftIdxPermutationXj(:), :);
kerDistComp2 = sum(exp(sum(abs(repXjLeft - repXjRight).^a, 2)/(omega^2)));
% Calculate the term that corresponds to K(p, q) in the definition of the
% kernal distance.
repXjRight = repmat(Xj, numPointsXi, 1);
repXiLeft = repmat(Xi, numPointsXj, 1);
leftIdxPermutationXi = hdlRepIdxPermutation(numPointsXi, numPointsXj);
repXiLeft = repXiLeft(leftIdxPermutationXi(:), :);
kerDistComp3 = -2*sum(exp(sum(abs(repXiLeft - repXjRight).^a, 2)/(omega^2)));
kerDist = kerDistComp1 + kerDistComp2 + kerDistComp3;
toc
disp(kerDist);
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)]).'
I can't seem to find a fix to my infinite loop. I have coded a Jacobi solver to solve a system of linear equations.
Here is my code:
function [x, i] = Jacobi(A, b, x0, TOL)
[m n] = size(A);
i = 0;
x = [0;0;0];
while (true)
i =1;
for r=1:m
sum = 0;
for c=1:n
if r~=c
sum = sum + A(r,c)*x(c);
else
x(r) = (-sum + b(r))/A(r,c);
end
x(r) = (-sum + b(r))/A(r,c);
xxx end xxx
end
if abs(norm(x) - norm(x0)) < TOL;
break
end
x0 = x;
i = i + 1;
end
When I terminate the code it ends at the line with xxx
The reason why your code isn't working is due to the logic of your if statements inside your for loops. Specifically, you need to accumulate all values for a particular row that don't belong to the diagonal of that row first. Once that's done, you then perform the division. You also need to make sure that you're dividing by the diagonal coefficient of A for that row you're concentrating on, which corresponds to the component of x you're trying to solve for. You also need to remove the i=1 statement at the beginning of your loop. You're resetting i each time.
In other words:
function [x, i] = Jacobi(A, b, x0, TOL)
[m n] = size(A);
i = 0;
x = [0;0;0];
while (true)
for r=1:m
sum = 0;
for c=1:n
if r==c %// NEW
continue;
end
sum = sum + A(r,c)*x(c); %// NEW
end
x(r) = (-sum + b(r))/A(r,r); %// CHANGE
end
if abs(norm(x) - norm(x0)) < TOL;
break
end
x0 = x;
i = i + 1;
end
Example use:
A = [6 1 1; 1 5 3; 0 2 4]
b = [1 2 3].';
[x,i] = Jacobi(A, b, [0;0;0], 1e-10)
x =
0.048780487792648
-0.085365853612062
0.792682926806031
i =
20
This means it took 20 iterations to achieve a solution with tolerance 1e-10. Compare this with MATLAB's built-in inverse:
x2 = A \ b
x2 =
0.048780487804878
-0.085365853658537
0.792682926829268
As you can see, I specified a tolerance of 1e-10, which means we are guaranteed to have 10 decimal places of accuracy. We can certainly see 10 decimal places of accuracy between what Jacobi gives us with what MATLAB gives us built-in.
In Matlab I want to create the partial derivative of a cost function called J(theta_0, theta_1) (in order to do the calculations necessary to do gradient descent).
The function J(theta_0, theta_1) is defined as:
Lets say h_theta(x) = theta_1 + theta_2*x. Also: alpha is fixed, the starting values of theta_1 and theta_2 are given. Let's say in this example: alpha = 0.1 theta_1 = 0, theta_2 = 1. Also I have all the values for x and y in two different vectors.
VectorOfX =
5
5
6
VectorOfX =
6
6
10
Steps I took to try to solve this in Matlab: I have no clue how to solve this problem in matlab. So I started off with trying to define a function in Matlab and tried this:
theta_1 = 0
theta_2 = 1
syms x;
h_theta(x) = theta_1 + t2*x;
This worked, but is not what I really wanted. I wanted to get x^(i), which is in a vector. The next thing I tried was:
theta_1 = 0
theta_2 = 1
syms x;
h_theta(x) = theta_1 + t2*vectorOfX(1);
This gives the following error:
Error using sym/subsindex (line 672)
Invalid indexing or function definition. When defining a
function, ensure that the body of the function is a SYM
object. When indexing, the input must be numeric, logical or
':'.
Error in prog1>gradientDescent (line 46)
h_theta(x) = theta_1 + theta_2*vectorOfX(x);
I looked up this error and don't know how to solve it for this particular example. I have the feeling that I make matlab work against me instead of using it in my favor.
When I have to perform symbolic computations I prefer to use Mathematica. In that environment this is the code to get the partial derivatives you are looking for.
J[th1_, th2_, m_] := Sum[(th1 + th2*Subscript[x, i] - Subscript[y, i])^2, {i, 1, m}]/(2*m)
D[J[th1, th2, m], th1]
D[J[th1, th2, m], th2]
and gives
Coming back to MATLAB we can solve this problem with the following code
%// Constants.
alpha = 0.1;
theta_1 = 0;
theta_2 = 1;
X = [5 ; 5 ; 6];
Y = [6 ; 6 ; 10];
%// Number of points.
m = length(X);
%// Partial derivatives.
Dtheta1 = #(theta_1, theta_2) sum(2*(theta_1+theta_2*X-Y))/2/m;
Dtheta2 = #(theta_1, theta_2) sum(2*X.*(theta_1+theta_2*X-Y))/2/m;
%// Loop initialization.
toll = 1e-5;
maxIter = 100;
it = 0;
err = 1;
theta_1_Last = theta_1;
theta_2_Last = theta_2;
%// Iterations.
while err>toll && it<maxIter
theta_1 = theta_1 - alpha*Dtheta1(theta_1, theta_2);
theta_2 = theta_2 - alpha*Dtheta2(theta_1, theta_2);
it = it + 1;
err = norm([theta_1-theta_1_Last ; theta_2-theta_2_Last]);
theta_1_Last = theta_1;
theta_2_Last = theta_2;
end
Unfortunately for this case the iterations does not converge.
MATLAB is not very flexible for symbolic computations, however a way to get those partial derivatives is the following
m = 10;
syms th1 th2
x = sym('x', [m 1]);
y = sym('y', [m 1]);
J = #(th1, th2) sum((th1+th2.*x-y).^2)/2/m;
diff(J, th1)
diff(J, th2)