Double for loop MATLAB - matlab

I need to do an estimation procedure for n time series (n vectors of T observations). I have the formula to evaluate my variable (using a for loop) but I need to repeat this n times (the number of vectors).
h0 = var(residuals);
ht=zeros(T,n); ht(T,1)=h0;
for i=2:T
ht(i) = theta(1) + theta(2)*residuals(i-1)^2 + theta(3)*ht(i-1);
end
So this loop calculates ht for all of the observations in series one, but I need another for loop that helps me to use this formula for all of the series.
Edit: This is what I've done based on the below answer:
function ht = VarEQ(theta,residuals)
[T,n] = size(residuals)
for k=1:n
h0 = var(residuals(:,k));
ht=zeros(T,n); ht(1,k)=h0;
for i=2:T
ht(i,k) = theta(1,k) + theta(2,k)*residuals(i-1,k)^2 + theta(3,k)*ht(i-1,k);
end
end
end
Current problem:
Now ht is all columns of zero and just the last column of correct values.
Variables
var is a 1xn row vector of variances. Using k, I want just the scalar for each residual.
theta is a 3xn matrix of parameters.
residuals is a Txn matrix.

This seems simple given what you already have set up:
function ht = VarEQ(theta,residuals)
[T,n] = size(residuals)
ht=zeros(T,n); % Initialise matrix OUTSIDE loop so it isn't over-written!
for k=1:n % additional loop for series 1 to n
ht(1,k) = var(residuals(:,k));;
for i = 2:T
% Ensure you are referencing the kth series
ht(i,k) = theta(1,k) + theta(2,k)*residuals(i-1,k)^2 + theta(3,k)*ht(i-1,k);
end
end
end
Note: previously, all columns of ht were the same, because theta and residuals were the same for each series!
With your updated code, and the updated code in this answer, that has been fixed.

Related

MATLAB: how do I create a vector where each element is a function of the previous element

Working in Matlab.
I am trying to create a vector where each element is a function of the previous element. The goal is to put the first 50 (or so) values of a logistical function in a vector. So I start with 0.200, with r=4 (for example), the second element would then be 40.200(1-0.200)=0.640.
The third element would take the value 0.64 and perform the same function on that number, and so on...
I have tried a for-loop, but since there is no counter in the function, the loop doesn't work.
EDIT: I have created the following function:
n = 0;
x = 0.200;
for n=0:100
x=4*x*(1-x)
n=n+1
end
This gives the first 100 values. But I fail to get them as values in a vector...
Any suggestions on how to solve this would be appreciated.
You need to use indexing for the x vector you are creating. The way you currently have it coded, everything is going into a scalar x and not a vector x. E.g.,
n = 50; % the number of elements you want to fill
x = zeros(1,n); % allocate a vector to hold the numbers
x(1) = 0.200; % set the first value
for k=2:n % loop through the remaining values
x(k) = 4*x(k-1)*(1-x(k-1)); % set the next value using the previous value
end
Note that in the above code all of the usages of x other than the initial allocation involve indexing, e.g. x(1) and x(k) and x(k-1).

How can I factor specific variables out of a formula in Matlab?

Suppose I have a column vector of formulae like this
N =
4*k2 + 5*k3 + k1*x
7*k2 + 8*k3 + k1*y
and a column vector of symbolic variables like this
k =
k1
k2
k3
The formulae are linear with respect to k. I'd like to find a matrix M such that M*k equals N.
I can do this with N/k. However, that gives
[ (4*k2 + 5*k3 + k1*x)/k1, 0, 0]
[ (7*k2 + 8*k3 + k1*y)/k1, 0, 0]
which is correct, but not what I want. What I want is the matrix
x 4 5
y 7 8
which seems to me the simplest answer in that it involves no variables from k.
How do I convince Matlab to factor out the specified variables from a formula or a vector of formulae?
You can use coeffs, specifically the form
C = coeffs(p,vars) returns coefficients of the multivariate polynomial p with respect to the variables vars.
Since the first input needs to be a polynomial, you need to pass each component of N:
coeffs(N(1), k)
coeffs(N(2), k)
Or use a loop and store all results in a symbolic array:
result = sym('result', [numel(N) numel(k)]); % create symbolic array
for m = 1:numel(N)
result(m,:) = coeffs(N(m), k);
end
In your example, this gives
result =
[ 5, 4, x]
[ 8, 7, y]
Based on #LuisMendo's answer, I used coeffs. But there are a couple of problems with coeffs. The first is that its result doesn't include any coefficients that are 0. The second is that it doesn't seem to guarantee that the coefficients are ordered the same way as the variables in its second argument. I came up with the following function to replace coeffs.
Luckily coeffs returns a second result that lists the variables associated with each item in the first result. (It's more complicated if the formula is not linear.)
function m = factorFormula(f, v )
% Pre: f is a 1x1 sym representing a
% linear function of the variables in v.
% Pre: v is a column vector of variables
% Post: m is a row vector such that m*v equals f
% and the formulas in m do not contain the
% variables in v
[cx,tx] = coeffs(f,v)
n = size(v,1)
m = sym(zeros(1,n))
for i = 1:n
j = find(tx==v(i))
if size(j,2) == 1
m(i) = cx(j)
end
end
end
This only works for one formula, but it can be extended to a vector using the loop in #LuisMendo's answer or this equivalent expression in #Sanchises comment there.
cell2sym(arrayfun( #(f)factorFormula(f,k),N,'UniformOutput',false ) )
I hope there is a better answer than this.

Matlab - subtract a vector to each row of a matrix without for statement

I have a piece a code for an exam, what They want me to do in order to achieve a better grade is to implement the same thing without a second "for" statement.
The code is:
piv = 1:n; %// piv: position vector
for k = 1:n-1 %// for each column :
if ((max(abs(A(piv(k:n),k)))) > eps(normA)) %// if pivot is non zero
[~, I] = max(A(piv(k:n),k)); %// find the max index
I = I + (k-1);
piv([k,I]) = piv([I,k]); %// swap pivot elements
A(piv(k+1:n),k) = A(piv(k+1:n),k)/A(piv(k),k); %// calculate the multipliers and save them in the column
for j = k+1:n
A(piv(j),k+1:n) = A(piv(j),k+1:n) - (A(piv(k),k+1:n)*A(piv(j),k)); %// multiply for multipliers and subtract them by the row
end
end
end
This is the Gauss factorizing method but doesn't matter, the matter is I need to have the same result without the second for e and the j variable.
You can certainly kill the innermost loop with bsxfun. I am leaving it to you to explain to your prof on how it does what it does. Going through the bsxfun docs would be a good idea and in this process you might learn some vectorization techniques. Here's the implementation -
parte2 = bsxfun(#times,A(piv(k),k+1:n),A(piv(k+1:n),k))
A(piv(k+1:n),k+1:n) = A(piv(k+1:n),k+1:n) - parte2

Find the product of all entries of vector x

Here is what I am trying to do:
Let x be a vector with n entries x1,x2,...xn. Write a mat-lab program which computes the vector p with entries defined by
pk = X1*X2....Xk-1*Xk+1...Xn.
for each k =1,2,...n.
pk is the product of all the entries of x except xk. (use prod command of compute the product of all the entries, then divide by xk). Take the appropriate special action if either one of more the entries of x is zero. Using vectors throughout and no 'for' loop.
I spent too much time to figure out this problem. I still could not get it. Please help!
Brute force:
n = numel(x);
X = repmat(x(:),1,n); %// put vector in column form and repeat
X(1:n+1:end) = 1; %// make diagonal 1
result = prod(X); %// product of each column
Saving computations:
ind = find(x==0);
if numel(ind)>1 %// result is all zeros
result = zeros(size(x));
elseif numel(ind)==1 %// result is all zeros except at one entry
result = zeros(size(x));
result(ind) = prod(nonzeros(x));
else %// compute product of all elements and divide by each element
result = prod(x)./x;
end

MatLab: Code for a sparse version of Horner's rule

I have written code to evaluate polynomials
p(x)=a_0+x(a_1+x(a_2+x(a_3+...+x(a_(n-1)+xa_n)...)))
using Horner's rule as follows
function [answer ] = Simple( a,x )
%Simple takes two arguments that are in order and returns the value of the
%polynomial p(x). Simple is called by typing Simple(a,x)
% a is a row vector
%x is the associated scalar value
n=length(a);
result=a(n);
if (any(a~=floor(a))
error('The values in a must be integers')
end
for j=n-1:-1:1 %for loop working backwards through the vector a
result=x*result+a(j);
end
answer=result;
end
I am now trying to write a code for a sparse version of this ie
p(x)=x^(i_1)(b_1+x^((i_2)-(i_1))(b_2+x^((i_3)-(i_2))(b_3+...+x^((i_(k-1))-(i_(k-2)))(b_(k-1)+x^((i_k)-(i(k-1)))b_k)...)))
I think I need the inputs to be a row vector of i and a row vector of b and a scalar value x. Any ideas where I can find this? I am unsure how to code it myself.
One way to answer this is to look at an intermediate term in p(x),
this will be
...(b_j + x^(i_(j+1) - i_j)(...
instead of the usual ...(a_j + x(..., thus you need to change the line result=x*result+a(j);.
Also there is a slight flaw in your formula for p(x), it should be p(x) = x^(i_1 - 1)(..., this comes from the fact that p(x) = a_1 x^0 + a_2 x^1 + ... + a_n x^(n-1) which comes from the fact that indexes of matrices in Matlab start at 1 instead of 0. Here is the full code
function [answer ] = SparseHorner( a,x )
% SparseHorner takes two arguments that are in order and returns the value of the
% polynomial p(x). SparseHorner is called by typing SparseHorner(a,x)
% a is a sparse row vector
% x is the associated scalar value
%// Find the entries where a is nonzero
[xInd yInd aVal] = find(a);
if any(aVal~=floor(aVal))
error('The values in a must be integers')
end
%// a is a row vector so only yInd's values change
ind = yInd;
result=aVal(end);
%// for loop working backwards through the vector a
%// numel is better than length
for j=(numel(ind)-1):-1:1
%// a(ind(j)) is much slower than aVal(j)
result=x^(ind(j+1)-ind(j))*result + aVal(j);
end
answer=result*x^(ind(1)-1);
end
Note that this treats a differently than Matlab's polyval, the latter has p(x) = a_1 x^n + ... + a_n; if you want to be consistent, then add the line a = fliplr(a) near the beginning of the function.