Sum with for loop in MATLAB - matlab

(https://i.stack.imgur.com/vkYy6.png)
How should I implement this sum with for loops in matlab, for i = 1:20 , N = 20 and ε is a vector, I have to avoid ε[0] so should I write a for loop, for each R?
for i=1:1:20
R (i) =symsum(e(k)-e(k-i),k+i,0,N);
end

Related

Nested For loops in MATLAB - Possibility for optimization?

Given n by n orthogonal matrix Q and diagonal matrix D such that all diagonal elements of D are nonnegative, I want to compute diagonal matrix T such that diagonal elements were equal to t(i)=1/(q(i,1)*q(i,1)*d(1)+q(i,2)*q(i,2)*d(2)+...+q(i,n)*q(i,n)*d(n)).
I am using Matlab:
Q=[0.7477 0.0742 0.6599; -0.5632 0.5973 0.5710; -0.3518 -0.7986 0.4883];
D=diag([0 0.7106 2.2967]);
n=length(Q);
L=Q*sqrt(D);
t = zeros(n,1);
for i=1:n
for j=1:n
t(i) = t(i) + sum(L(i,j)^2);
end
end
T = sqrt(inv(diag(t)));
As you can see I have used nested for loops. Is it possible to avoid using loops at all?
for i=1:n
for j=1:n
t(i) = t(i) + sum(L(i,j)^2);
end
end
What are you trying to do? sum sums more than one number, but L(i,j)^2 is one number.
Instead, we can use your code to sum over j indices and remove the loop.
for i=1:n
t(i) = t(i) + sum(L(i,:).^2);
end
But, you defined t = zeros(n,1);, i.e. t has nothing in it, so your for loop is equivalent to:
for i=1:n
t(i) = sum(L(i,:)^2);
end
Knowing this, we can do it in one go:
t = sum(L.^2,2)

Vectorise a "triangular" loop in matlab

In Matlab I have the following for loop:
for i=1:n
for j=i+1:n
P(i) = P(i) - Q(j);
end
end
I call this a "triangular" loop because of how j depends on i.
Is it possible to vectorise this into a single line statement that will run faster than the for loop?
What are the type of P and Q? Are they vectors? If so what about:
P = P - [fliplr(cumsum(fliplr(Q(2:n)))) 0]
You can even do a reverse cumulative sum so the fliplr can go:
P = P - [cumsum(Q(2:n),'reverse') 0]

Generating random diagonally dominant dense/sparse matrices in matlab

Is there a matlab command for generating a random n by n matrix, with elements taken in the interval [0,1], with x% of the entries on the off-diagonal to be 0. Then, additionally setting the element in the diagonal to be the sum of every element in its respective column? In order to create a diagonally dominant dense/sparse matrix? This may be easy enough to write a code for but I was wondering if there was already a built in function with this capability.
EDIT:
I am new to Matlab/programming so this was an easier said than done. I'm having trouble making the matrix with the percentage ignoring the diagonal. It's a n x n matrix, so there are $n^2$ entries, with n of them on the diagonal, I want the percentage of zeros to be taken from $n^2 - n$ elements, i.e. all the off-diagonal elements. I cannot implement this correctly. I do not know how to initialize my M (see below) to correspond correctly.
% Enter percentage as a decimal
function [M] = DiagDomSparse(n,x)
M = rand(n);
disp("Original matrix");
disp(M);
x = sum(M);
for i=1:n
for j=1:n
if(i == j)
M(i,j) = x(i);
end
end
end
disp(M);
Here is one approach that you could use. I'm sure you will get some other answers now with a more clever approach, but I like to keep things simple and understandable.
What I'm doing below is creating the data to be put in the off-diagonal elements first. I create an empty matrix and copy this data into the off-diagonal elements using linear indexing. Now I can compute the sum of columns and write those into the diagonal elements using linear indexing again. Because the matrix was initialized to zero, the diagonal elements are still zero when I compute the sum of columns, so they don't interfere.
n = 5;
x = 0.3; % fraction of zeros in off-diagonal
k = round(n*(n-1)*x); % number of zeros in off-diagonal
data = randn(n*(n-1)-k,1); % random numbers, pick your distribution here!
data = [data;zeros(k,1)]; % the k zeros
data = data(randperm(length(data))); % shuffle
diag_index = 1:n+1:n*n; % linear index to all diagonal elements
offd_index = setdiff(1:n*n,diag_index); % linear index to all other elements
M = zeros(n,n);
M(offd_index) = data; % set off-diagonal elements to data
M(diag_index) = sum(M,1); % set diagonal elements to sum of columns
To refer to the diagonal you want eye(n,'logical'). Here is a solution:
n=5;
M = rand(n);
disp("Original matrix");
disp(M);
x = sum(M);
for i=1:n
for j=1:n
if(i == j)
M(i,j) = x(i);
end
end
end
disp('loop solution:')
disp(M);
M(eye(n,'logical'))=x;
disp('eye solution:')
disp(M);

Function "pdist" in Matlab

I have an N by 2 matrix called r (N is very large). r is the position of points in 2D. I searched for the best-optimized way of calculating distance between point. I find that dist function is the best on in less time-consuming if one doesn't try to change it to a square matrix. I wonder if I write
D= pdist(r, 'euclidean');
When I need distance between particle i and j, what is the best way to find it using D vector? I do not really any way without using if.
I know that I can do it by
if (i < j)
D((i–1)*(m–i/2)+j–i)
end
But as N is very large, this is not efficient. Could anyone help me, please?
I'm using ii and jj as row and column indices into the hypohetical distance matrix M = squareform(D) of size and N. The result is ind, such that D(ind) equals M(ii,jj).
t = sort([ii, jj]); % temporary variable
ii = t(2); % maximum of ii and jj
jj = t(1); % minimum of ii and jj
t = N-1:-1:1;
ind = sum(t(1:jj-1)) + ii - jj;

Choose k vectors from n vectors in Matlab

Suppose there are a matrix of three row vectors
A = [1,2;
1,3;
2,3]
I would like to create a new matrix B which draws two vectors from A with repetitions, and there are 3^2 possible combinations. Some simple implementation is as follows:
For i = 1:3
c = A(i,:);
for j=1:3
d = A(j,:);
B = [c;d];
end
end
But, in general, if I need to choose k vectors from n vectors, what is the more general way to write such loop? It's difficult to continue write loop using i, j, ... I guess. Thanks!
For sampling at random, matlab has randsample:
rowIdx = randsample( size(A,1), k, true );
B = A(rowIdx,:);
You can just use randi for this to pick k uniformly distributed numbers in the range 1:n (with replacement)
k = 2;
n = size(A,1);
rowIdx = randi(n,k)
B = A(rowIdx,:)
Thanks for all previous suggestions.
In the end I figure out what I want is called permutations with repetitions. The matlab function permun from file exchange solves my problem.