Hi all,
is there a way to vectorize the following loop?
for RIPETIZIONE = 1:10
%for k = 1:size(lambda_tol_vector.Value,1)
parfor (k = 1:size(lambda_tol_vector.Value,1))
%fprintf('Completion using nuclear norm regularization... \n');
[CompletedMat,flag] = matrix_completion_nuclear_GG_vec( ...
A.Value.*double(B), double(B), N, lambda_tol_vector.Value(k), tol);
if flag==1
CompletedMat_parvec{RIPETIZIONE,k}=zeros(size(A));
end
CompletedMat_parvec{RIPETIZIONE,k}=CompletedMat;
end
end

5 Commenti

Jan
Jan il 28 Nov 2022
Modificato: Jan il 28 Nov 2022
Move the PARFOR loops outside. Starting a parallel loop inside another loop is expensive.
The main part happens inside matrix_completion_nuclear_GG_vec(), so post this code instead of the outer loops.
What are the input values? If B is a large array, creating a copy in double format can be expensive already. Then doing this once only can increase the speed already. A.Value.*double(B) is a constand also. So do not claculate it repeatedly, but once before the loops.
What is the purpose of checking the values of flag?
if flag==1
CompletedMat_parvec{RIPETIZIONE,k}=zeros(size(A));
end
CompletedMat_parvec{RIPETIZIONE,k}=CompletedMat;
This wasted time only, because if flag equals 1, the output is filled by a zero array, but overwritten directly. Maybe you want:
if flag==1
CompletedMat_parvec{RIPETIZIONE,k}=zeros(size(A));
else
CompletedMat_parvec{RIPETIZIONE,k}=CompletedMat;
end
If CompletedMat_parvec pre-allocated?
federico nutarelli
federico nutarelli il 28 Nov 2022
Modificato: federico nutarelli il 28 Nov 2022
Hi @Jan aand thnks for the reply.
Yes CompletedMat_parvec is pre-allocated as a cell array: CompletedMat_parvec={};
However there is a huge time expense when I use the outer for loop.
Please, refer to this thred to see the matrix_completion_nuclear_GG_vec function
As far as the input are concerned you can use these:
clear
%reduce the size of A if necessary.
A=rand(646,200);
B=int8(rand(size(A,1),size(A,2))>0.5);
lambda_tol=0.000000000000004;
N=10;
Jan
Jan il 28 Nov 2022
Modificato: Jan il 28 Nov 2022
"Yes CompletedMat_parvec is pre-allocated as a cell array: CompletedMat_parvec={};" - This is not a pre-allocation. Pre-allocating means, to create the array with the final size instead of letting it grow iteratively.
I do not find the code of matrix_completion_nuclear_GG_vec in the other thread, but only matrix_completion_nuclear_GG_alt. Please do not let the readers guess, which code you are using.
By the way, avoid overdoing when naming functions. Too long functions names let you loose the overview.
federico nutarelli
federico nutarelli il 28 Nov 2022
Modificato: federico nutarelli il 28 Nov 2022
Oh sorry @Jan.
I will attach the function here.
As for pre-allocation I will check the best way to pre-allocate vell arrays.
Oh @Jan another thing that I am nnoticing when putting the arfor loop on the outer one, is tht the final results in term of CompletedMat_parvec is different from the same result when I use only for loos (both outer and inner). Is there a way to make the two results equal?

Accedi per commentare.

 Risposta accettata

Matt J
Matt J il 28 Nov 2022
Modificato: Matt J il 28 Nov 2022
EDITED:
R=10;
K=size(lambda_tol_vector.Value,1);
CompletedMat_parvec=cell(R,K);
B=double(B);
parfor n=1:R*K
[RIPETIZIONE,k]=ind2sub([R,K],n);
%fprintf('Completion using nuclear norm regularization... \n');
[CompletedMat,flag] = matrix_completion_nuclear_GG_vec( ...
A.Value.*B,B, N, lambda_tol_vector.Value(k), tol);
if ~flag
CompletedMat_parvec{n}=CompletedMat;
end
end
idx=cellfun('isempty', CompletedMat_parvec);
CompletedMat_parvec(idx)={zeros(size(A))};

4 Commenti

federico nutarelli
federico nutarelli il 28 Nov 2022
Modificato: federico nutarelli il 28 Nov 2022
@Matt J thank you for the kind reply.
There is however a red flag in CompletedMat_parvec stating that valid indices for the latter are restricted in parfor loops:
Explanation
For MATLAB to execute parfor loops efficiently, the amount of data sent to the MATLAB workers must be minimal. One of the ways MATLAB achieves this is by restricting the way variables can be indexed in parfor iterations. The indicated variable is indexed in a way that is incompatible with parfor.
Suggested Action
Fix the indexing. For a description of the indexing restrictions, see Sliced Variables.
Maybe this line CompletedMat_parvec(1:R,1:K)={zeros(size(A))}; should be substituted by this one:
N_RIPETIZIONI=10;
L=size(lambda_tol_vector.Value,1);
CompletedMat_parvec= cell(N_RIPETIZIONI,L);
?
Matt J
Matt J il 28 Nov 2022
Modificato: Matt J il 28 Nov 2022
Try this replacement,
R=10; %
K=size(lambda_tol_vector.Value,1);
CompletedMat_parvec=cell(R,K);
B=double(B);
parfor n=1:R*K
[RIPETIZIONE,k]=ind2sub([R,K],n);
%fprintf('Completion using nuclear norm regularization... \n');
[CompletedMat,flag] = matrix_completion_nuclear_GG_vec( ...
A.Value.*B,B, N, lambda_tol_vector.Value(k), tol);
if ~flag
CompletedMat_parvec{n}=CompletedMat;
end
end
idx=cellfun('isempty', CompletedMat_parvec);
CompletedMat_parvec(idx)={zeros(size(A))};
federico nutarelli
federico nutarelli il 28 Nov 2022
Modificato: federico nutarelli il 28 Nov 2022
@Matt J same problem unfortunately. Maaybe we should index it by n? Thhough I don't think so since ideally I need CompletedMat_parvec{RIPETIZIONE,k}=...;
Furthermore it looks like the variable n is not creted when evaluaating the parfor loop.
Matt J
Matt J il 28 Nov 2022
Modificato: Matt J il 28 Nov 2022
Yes! Sorry, you should be indexing by n,
if ~flag
CompletedMat_parvec{n}=CompletedMat;
end
It is equivalent to,
CompletedMat_parvec{RIPETIZIONE,k}=CompletedMat;

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Loops and Conditional Statements in Centro assistenza e File Exchange

Prodotti

Release

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by