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

Jan
Jan 2022년 11월 28일
편집: Jan 2022년 11월 28일
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 2022년 11월 28일
편집: federico nutarelli 2022년 11월 28일
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 2022년 11월 28일
편집: Jan 2022년 11월 28일
"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 2022년 11월 28일
편집: federico nutarelli 2022년 11월 28일
Oh sorry @Jan.
I will attach the function here.
As for pre-allocation I will check the best way to pre-allocate vell arrays.
federico nutarelli
federico nutarelli 2022년 11월 28일
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?

댓글을 달려면 로그인하십시오.

 채택된 답변

Matt J
Matt J 2022년 11월 28일
편집: Matt J 2022년 11월 28일

1 개 추천

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

federico nutarelli
federico nutarelli 2022년 11월 28일
편집: federico nutarelli 2022년 11월 28일
@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 2022년 11월 28일
편집: Matt J 2022년 11월 28일
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 2022년 11월 28일
편집: federico nutarelli 2022년 11월 28일
@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 2022년 11월 28일
편집: Matt J 2022년 11월 28일
Yes! Sorry, you should be indexing by n,
if ~flag
CompletedMat_parvec{n}=CompletedMat;
end
It is equivalent to,
CompletedMat_parvec{RIPETIZIONE,k}=CompletedMat;

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

제품

릴리스

R2021b

질문:

2022년 11월 28일

편집:

2022년 11월 28일

Community Treasure Hunt

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

Start Hunting!

Translated by