How to linearize the nested parfor loop? - matlab

I have two variables i,j, where j index start depends on i index.
n = 3;
for i = 1:n
for j = i+1:n
% Feature matching
matches = getMatches(input, allDescriptors{i}, allDescriptors{j});
nf = size(matches, 2);
numMatches(i,j) = nf;
end
end
I am trying to linearize it using the below code:
n = 3;
M = n;
N = n;
parfor i = 1:M*N
% IND2SUB converts from a "linear" index into individual
% subscripts
[ii,jj] = ind2sub([M,N], i);
if (ii~=jj)
matches = getMatches(input, allDescriptors{ii}, allDescriptors{jj});
nf = size(matches, 2);
numMatches(i) = nf;
end
end
But have some entries on the lower triangular part of the square matrix.
Any help is appreciated!

Related

double sum in Matlab

I would like to write a Matlab code to calculate the following:
\sum_{k=0}^{N-1} \frac{1}{k!} \sum_{i=0}^{k} {k \choose i}(a-1)^{k-i} a^k
and my code is:
N = 3;
a = [3 4];
for k = 0:N-1
f = 0;
for i = 0:k
f = f + nchoosek(k,i).* a.^k .* (a-1).^(k-i);
end
sumoff = sum(f);
all = (( 1./ (factorial(k))).*sumoff);
end
overall= sum(all);
'all' variable gives different value when it is inside the for loop rather than outside. But I want it to calculate when k = 0:N-1. What am I doing wrong?
Thank you.
The issue is your current code overwrites all on every iteration. Moving it outside the loop also doesn't work because you'll only save the result of the last iteration.
To save the all of every iteration, define all as a vector and then assign each intermediate result into that vector:
N = 3;
a = [3 4];
% preallocate a vector for `all`
all = nan(N-1, 1);
for k = 0:N-1
f = 0;
for i = 0:k
f = f + nchoosek(k,i) .* a.^k .* (a-1).^(k-i);
end
sumoff = sum(f);
% assign your intermediate result into the `all` vector
all(k+1) = ((1./(factorial(k))) .* sumoff);
end
overall = sum(all);

Manually upsample/replicate matrix

I'm trying to upsample a matrix by two by replicating another matrix, but i'm confused with the code, basically what i want is if:
Y = [1,2]
then the upsampled version would look like:
Up = [1,1,2,2;1,1,2,2]
What i've written so far is:
[row,col] = size(y)
Up = zeros(row*2,col*2);
for i = 1:2:row*2
for j = 1:2:col*2
Up(i, j) = Y(i,j);
Up(i+1, j) = Y(i,j);
Up(i, j+1) = Y(i,j);
Up(i+1, j+1) = Y(i,j);
end
end
but it says Index exceeds matrix dimensions, which i understand is because of the +1s but i'm not sure how else to go about doing this...
Data:
Y = [1,2]; % matrix
n = 2; % repetition factor
Solution using the repelem function (introduced in R2015a):
Up = repelem(Y,n,n);
Solution using indexing;
Up = Y(ceil(1/n:1/n:end), ceil(1/n:1/n:end));
Solution using a Kronecker product:
Up = kron(Y, ones(n))
The solution i ended up using is:
[row,col] = size(Y);
Up = zeros(row*2,col*2);
idx_row = 1;
for i = 1:D:row
idx_col = 1;
for j = 1:D:col
Up(i:i+1, j:j+1) = repmat(repmat(Y(idx_row,idx_col),1,2),2,1);
idx_col = idx_col + 1;
end
idx_row = idx_row + 1;
end

Jacobi method to solve linear systems in MATLAB

How would you code this in MATLAB?
This is what I've tried, but it doesn't work quite right.
function x = my_jacobi(A,b, tot_it)
%Inputs:
%A: Matrix
%b: Vector
%tot_it: Number of iterations
%Output:
%:x The solution after tot_it iterations
n = length(A);
x = zeros(n,1);
for k = 1:tot_it
for j = 1:n
for i = 1:n
if (j ~= i)
x(i) = -((A(i,j)/A(i,i)) * x(j) + (b(i)/A(i,i)));
else
continue;
end
end
end
end
end
j is an iterator of a sum over each i, so you need to change their order. Also the formula has a sum and in your code you're not adding anything so that's another thing to consider. The last thing I see that you're omitting is that you should save the previous state of xbecause the right side of the formula needs it. You should try something like this:
function x = my_jacobi(A,b, tot_it)
%Inputs:
%A: Matrix
%b: Vector
%tot_it: Number of iterations
%Output:
%:x The solution after tot_it iterations
n = length(A);
x = zeros(n,1);
s = 0; %Auxiliar var to store the sum.
xold = x
for k = 1:tot_it
for i = 1:n
for j = 1:n
if (j ~= i)
s = s + (A(i,j)/A(i,i)) * xold(j);
else
continue;
end
end
x(i) = -s + b(i)/A(i,i);
s = 0;
end
xold = x;
end
end

Merge result after for function

Good morning everybody
I work to develop mathematical model to solve one of the industrial engineering problem but I have a problem in the write of the MATLAB code. So I simplified this problem in the following code. I need to merge all the result of X in one matrix after the for function used to use it in the next step (in this simple case this matrix will be 40*3)
LIST=randi([0,1],[4,3]);
for i = 1:10
j=i
V=randi([0,1],[4,3]);
for m = 1:4
for n = 1:2
if V(m,n)== 1;
X(m,n) = LIST(m,n);
elseif V(m,n)== 0;
X(m,n) = 2;
end
end
end
for m = 1:4
for n = 3
if V(m,n)== 1;
X(m,n) = LIST(m,n);
elseif V(m,n)== 0;
X(m,n) = 3;
end
end
end
X
end
Thank you for your time and your consideration
At each iteration of the outer loop (for i = 1:10) the values in the X matrix are overwritten.
In order to store all the values you need to increment the row value of the X matrix of the value of max limit of the second loop (for m = 1:4) that is 4.
You can do it by modifying the indexing of the X matrix as follows:
X(m+(i-1)*4,n)
You can make your script more "general" by identifying the limit evaluating it as the number of rows in the LIST matrix using the function size function:
[n_row,n_col]=size(LIST)
In this way
at the first iteration of the outer loop, the row index will range from 1 to 4.
at the second iteration itr will range from 1+(2-1)*4 to 4+(2-1)*4 that is from 5 to 8
and so on
This is the updated code
LIST=randi([0,1],[4,3]);
[n_row,n_col]=size(LIST)
for i = 1:10
j=i
V=randi([0,1],[4,3]);
% for m = 1:4
for m = 1:n_row
for n = 1:2
if V(m,n)== 1;
% X(m,n) = LIST(m,n);
X(m+(i-1)*n_row,n) = LIST(m,n);
elseif V(m,n)== 0;
% X(m,n) = 2
X(m+(i-1)*n_row,n) = 2;
end
end
end
% for m = 1:4
for m = 1:n_row
for n = 3
if V(m,n)== 1;
% X(m,n) = LIST(m,n)
X(m+(i-1)*n_row,n) = LIST(m,n);
elseif V(m,n)== 0;
% X(m,n) = 3;
X(m+(i-1)*n_row,n) = 3;
end
end
end
X
end
Hope this helps.
Qapla'

Finding correct index value for matrix in Matlab using meshgrid

I'm trying to build make a code where an equation is not calculated for some certain values. I have a meshgrid with several values for x and y and I want to include a for loop that will calculate some values for most of the points in the meshgrid but I'm trying to include in that loop a condition that if the points have a specified index, the value will not be calculated. In my second group of for/if loops, I want to say that for all values of i and k (row and column), the value for z and phi are calculated with the exception of the specified i and k values (in the if loop). What I'm doing at the moment is not working...
The error I'm getting is:
The expression to the left of the equals sign is not a valid target for an assignment.
Here is my code at the moment. I'd really appreciate any advice on this! Thanks in advance
U_i = 20;
a = 4;
c = -a*5;
b = a*10;
d = -20;
e = 20;
n = a*10;
[x,y] = meshgrid([c:(b-c)/n:b],[d:(e-d)/n:e]');
for i = 1:length(x)
for k = 1:length(x)
% Zeroing values where cylinder is
if sqrt(x(i,k).^2 + y(i,k).^2) < a
x(i,k) = 0;
y(i,k) = 0;
end
end
end
r = sqrt(x.^2 + y.^2);
theta = atan2(y,x);
z = zeros(length(x));
phi = zeros(length(x));
for i = 1:length(x)
for k = 1:length(x)
if (i > 16 && i < 24 && k > 16 && k <= length(x))
z = 0;
phi = 0;
else
z = U_i.*r.*(1-a^2./r.^2).*sin(theta); % Stream function
phi = U_i*r.*(1+a^2./r.^2).*cos(theta); % Velocity potential
end
end
end
The original code in the question can be rewritten as seen below. Pay attention in the line with ind(17:24,:) since your edit now excludes 24 and you original question included 24.
U_i = 20;
a = 4;
c = -a*5;
b = a*10;
d = -20;
e = 20;
n = a*10;
[x,y] = meshgrid([c:(b-c)/n:b],[d:(e-d)/n:e]');
ind = find(sqrt(x.^2 + y.^2) < a);
x(ind) = 0;
y(ind) = 0;
r = sqrt(x.^2 + y.^2);
theta = atan2(y,x);
ind = true(size(x));
ind(17:24,17:length(x)) = false;
z = zeros(size(x));
phi = zeros(size(x));
z(ind) = U_i.*r(ind).*(1-a^2./r(ind).^2).*sin(theta(ind)); % Stream function
phi(ind) = U_i.*r(ind).*(1+a^2./r(ind).^2).*cos(theta(ind)); % Velocity potential