Why does the one-dimensional variant of a 2-d random walk not work? - matlab

There is a two-dimensional random walk that one can find here which works perfectly in Octave. However, when I tried to write a one-dimensional random walk program, I got an error. Here is the program:
t=[];
x=[];
for i=1:100000
J=rand;
if J<0.5
x(i+1)=x(i)+1;
t(i+1)=t(i)+1;
else
x(i+1)=x(i)-1;
t(i+1)=t(i)+1;
end
end
plot(t,x)
Here is the error:
error: A(I): index out of bounds; value 1 out of bound 0
Thank you.

No need for a loop:
N = 100000;
t = 1:N;
x = cumsum(2*(rand(1,N)<.5)-1);
plot(t,x)
For the 2D case you could use the same approach:
N = 100000;
%// t = 1:N; it won't be used in the plot, so not needed
x = cumsum(2*(rand(1,N)<.5)-1);
y = cumsum(2*(rand(1,N)<.5)-1);
plot(x,y)
axis square

You get an error because you ask MATLAB to use x(1) in the first iteration when you actually defined x to be of length 0. So you need to either initialize x and t with the proper size:
x=zeros(1,100001);
t=zeros(1,100001);
or change your loop to add the new values at the end of the vectors:
x(i+1)=[x(i) x(i)+1];

Since t and x are empty, therefore, you cannot index them through x(i+1) and x(i).
I believe you should intialize x and t with all zeros.

In the first iteration, i = 1, you have x(2) = x(1) +or- 1 while x has dimension of zero. You should define the starting point for x and t, which is usually the origin, you can also change the code a little bit,
x = 0;
N = 100000;
t = 0 : N;
for i = 1 : N
x(i+1) = x(i) + 2 * round(rand) - 1;
end
plot(t,x)

Related

How to programmatically compute this summation

I want to compute the above summation, for a given 'x'. The summation is to be carried out over a block of lengths specified by an array , for example block_length = [5 4 3]. The summation is carried as follows: from -5 to 5 across one dimension, -4 to 4 in the second dimension and -3 to 3 in the last dimension.
The pseudo code will be something like this:
sum = 0;
for i = -5:5
for j = -4:4
for k = -3:3
vec = [i j k];
tv = vec * vec';
sum = sum + 1/(1+tv)*cos(2*pi*x*vec'));
end
end
end
The problem is that I want to find the sum when the number of dimensions are not known ahead of time, using some kind of variable nested loops hopefully. Matlab uses combvec, but it returns all possible combinations of vectors, which is not required as we only compute the sum. When there are many dimensions, combvec returning all combinations is not feasible memory wise.
Appreciate any ideas towards solutions.
PS: I want to do this at high number of dimensions, for example 650, as in machine learning.
Based on https://www.mathworks.com/matlabcentral/answers/345551-function-with-varying-number-of-for-loops I came up with the following code (I haven't tested it for very large number of indices!):
function sum = fun(x, block_length)
sum = 0;
n = numel(block_length); % Number of loops
vec = -ones(1, n) .* block_length; % Index vector
ready = false;
while ~ready
tv = vec * vec';
sum = sum + 1/(1+tv)*cos(2*pi*x*vec');
% Update the index vector:
ready = true; % Assume that the WHILE loop is ready
for k = 1:n
vec(k) = vec(k) + 1;
if vec(k) <= block_length(k)
ready = false;
break; % v(k) increased successfully, leave "for k" loop
end
vec(k) = -1 * block_length(k); % v(k) reached the limit, reset it
end
end
end
where x and block_length should be both 1-x-n vectors.
The idea is that, instead of using explicitly nested loops, we use a vector of indices.
How good/efficient is this when tackling the suggested use case where block_length can have 650 elements? Not much! Here's a "quick" test using merely 16 dimensions and a [-1, 1] range for the indices:
N = 16; tic; in = 0.1 * ones(1, N); sum = fun(in, ones(size(in))), toc;
which yields an elapsed time of 12.7 seconds on my laptop.

Matlab function for cumulative power

Is there a function in MATLAB that generates the following matrix for a given scalar r:
1 r r^2 r^3 ... r^n
0 1 r r^2 ... r^(n-1)
0 0 1 r ... r^(n-2)
...
0 0 0 0 ... 1
where each row behaves somewhat like a power analog of the CUMSUM function?
You can compute each term directly using implicit expansion and element-wise power, and then apply triu:
n = 5; % size
r = 2; % base
result = triu(r.^max((1:n)-(1:n).',0));
Or, maybe a little faster because it doesn't compute unwanted powers:
n = 5; % size
r = 2; % base
t = (1:n)-(1:n).';
u = find(t>=0);
t = t(u);
result = zeros(n);
result(u) = r.^t;
Using cumprod and triu:
% parameters
n = 5;
r = 2;
% Create a square matrix filled with 1:
A = ones(n);
% Assign the upper triangular part shifted by one with r
A(triu(A,1)==1)=r;
% cumprod along the second dimension and get only the upper triangular part
A = triu(cumprod(A,2))
Well, cumsum accumulates the sum of a vector but you are asking for a specially design matrix, so the comparison is a bit problematic....
Anyway, it might be that there is a function for this if this is a common special case triangular matrix (my mathematical knowledge is limited here, sorry), but we can also build it quite easily (and efficiently=) ):
N = 10;
r = 2;
% allocate arry
ary = ones(1,N);
% initialize array
ary(2) = r;
for i = 3:N
ary(i) = ary(i-1)*r;
end
% build matrix i.e. copy the array
M = eye(N);
for i = 1:N
M(i,i:end) = ary(1:end-i+1);
end
This assumes that you want to have a matrix of size NxN and r is the value that you want calculate the power of.
FIX: a previous version stated in line 13 M(i,i:end) = ary(i:end);, but the assignment needs to start always at the first position of the ary

How to increase number in range set till it gives a specific answer?

I've wrote a rungekutta code and there is a specific x range that it should calculate up to it. The problem is that the prof. wants a code that keeps on adding up by itself till it reaches the required answer.
I tried using the 'if' function but it only works once and no more (thus, even creating a mismatch in array lengths.
Code:
h=0.5;% step size
z=0.5;
x = 0:h:z;% the range of x
y = zeros(1,length(x));
y(1) = 50;% initial condition
F_xy = #(t,x) (37.5-3.5*x);%function
for i=1:(length(x)-1)% calculation loop
k_1 = F_xy(x(i),y(i));
k_2 = F_xy(x(i)+h,y(i)+h*k_1);
y(i+1) = y(i) + (h/2)*(k_1+k_2);% main equation
if y(i+1)>11
x=0:h:z+1;
end
end
disp (y(i+1))
Error of arrays length (shows that if function only works once)
41.4063
Error using plot
Vectors must be the same length.
Error in code6rungekutta2ndorder (line 30)
plot(x,y), grid on
it should keep on increasing by +1 in the 'z' variable till the answer of y(i+1) is less than 11. (correct z should be 9.5)
As #medicine_man suggested, you need a while loop:
h=0.5;% step size
z=0.5;
x = 0;
y = 50;% initial condition
F_xy = #(t,x) (37.5-3.5*x);%function
m = 0;
while y(m+1) > 11
m = m+1;
x = x+h;
k_1 = F_xy(x,y(m));
k_2 = F_xy(x+h,y(m)+h*k_1);
y(m+1) = y(m) + (h/2)*(k_1+k_2);% main equation
end
figure;
plot(0:h:x, y);
Your terminate condition, which is y(m+1) > 11, is checked at the beginning of each iteration of the while loop. In the loop, you can increment the value of x and update your y array. The loop runs until the terminate condition is met.
The result of the above code:

Implementing Simplex Method infinite loop

I am trying to implement a simplex algorithm following the rules I was given at my optimization course. The problem is
min c'*x s.t.
Ax = b
x >= 0
All vectors are assumes to be columns, ' denotes the transpose. The algorithm should also return the solution to dual LP. The rules to follow are:
Here, A_J denotes columns from A with indices in J and x_J, x_K denotes elements of vector x with indices in J or K respectively. Vector a_s is column s of matrix A.
Now I do not understand how this algorithm takes care of condition x >= 0, but I decided to give it a try and follow it step by step. I used Matlab for this and got the following code.
X = zeros(n, 1);
Y = zeros(m, 1);
% i. Choose starting basis J and K = {1,2,...,n} \ J
J = [4 5 6] % for our problem
K = setdiff(1:n, J)
% this while is for goto
while 1
% ii. Solve system A_J*\bar{x}_J = b.
xbar = A(:,J) \ b
% iii. Calculate value of criterion function with respect to current x_J.
fval = c(J)' * xbar
% iv. Calculate dual solution y from A_J^T*y = c_J.
y = A(:,J)' \ c(J)
% v. Calculate \bar{c}^T = c_K^T - u^T A_K. If \bar{c}^T >= 0, we have
% found the optimal solution. If not, select the smallest s \in K, such
% that c_s < 0. Variable x_s enters basis.
cbar = c(K)' - c(J)' * inv(A(:,J)) * A(:,K)
cbar = cbar'
tmp = findnegative(cbar)
if tmp == -1 % we have found the optimal solution since cbar >= 0
X(J) = xbar;
Y = y;
FVAL = fval;
return
end
s = findnegative(c, K) %x_s enters basis
% vi. Solve system A_J*\bar{a} = a_s. If \bar{a} <= 0, then the problem is
% unbounded.
abar = A(:,J) \ A(:,s)
if findpositive(abar) == -1 % we failed to find positive number
disp('The problem is unbounded.')
return;
end
% vii. Calculate v = \bar{x}_J / \bar{a} and find the smallest rho \in J,
% such that v_rho > 0. Variable x_rho exits basis.
v = xbar ./ abar
rho = J(findpositive(v))
% viii. Update J and K and goto ii.
J = setdiff(J, rho)
J = union(J, s)
K = setdiff(K, s)
K = union(K, rho)
end
Functions findpositive(x) and findnegative(x, S) return the first index of positive or negative value in x. S is the set of indices, over which we look at. If S is omitted, whole vector is checked. Semicolons are omitted for debugging purposes.
The problem I tested this code on is
c = [-3 -1 -3 zeros(1,3)];
A = [2 1 1; 1 2 3; 2 2 1];
A = [A eye(3)];
b = [2; 5; 6];
The reason for zeros(1,3) and eye(3) is that the problem is inequalities and we need slack variables. I have set starting basis to [4 5 6] because the notes say that starting basis should be set to slack variables.
Now, what happens during execution is that on first run of while, variable with index 1 enters basis (in Matlab, indices go from 1 on) and 4 exits it and that is reasonable. On the second run, 2 enters the basis (since it is the smallest index such that c(idx) < 0 and 1 leaves it. But now on the next iteration, 1 enters basis again and I understand why it enters, because it is the smallest index, such that c(idx) < 0. But here the looping starts. I assume that should not have happened, but following the rules I cannot see how to prevent this.
I guess that there has to be something wrong with my interpretation of the notes but I just cannot see where I am wrong. I also remember that when we solved LP on the paper, we were updating our subjective function on each go, since when a variable entered basis, we removed it from the subjective function and expressed that variable in subj. function with the expression from one of the equalities, but I assume that is different algorithm.
Any remarks or help will be highly appreciated.
The problem has been solved. Turned out that the point 7 in the notes was wrong. Instead, point 7 should be

MATLAB replacing some elements from a vector

If i have a vector, lets say L=[10;10;10;11;11;13;13] which is associated to another vector X=[1;6;65;34;21;73;14] and I want to create a third vector, Z, with almost all the elements in X, but just replacing a 0 in X when the element (i,j) from L changes. Lets say that the result that I want should look like this Z=[1;6;65;0;21;0;14]
Any ideas how to solve this?
I would be really thankful :)
That's easy:
X = [1;6;65;34;21;73;14];
L = [10;10;10;11;11;13;13];
Z = X;
ind = [false; diff(L)~=0]; %// logical index of values to be set to 0
Z(ind) = 0;
This works by computing a logical index ind = [false; diff(L)~=0] of the elements where a change has ocurred. The initial false is needed because the first element doesn't have a previous one to compare with. The logical index is used to select which values of Z should be set to 0.
This should work
Z = zeros(length(L))
for i = 2:length(L)
if(L(i-1) == L(i)
Z(i) = X(i);
else
Z(i) = 0;
end
end