Efficient way to do cell multiplication and stacking of sparse matrices in MATLAB










0















What I have is a cell J of size 1xs filled with sparse matrices of size mxn (m>=n), and two full matrices r and l of size mxcxp and sxcxp, respectively. The dimensions are roughly



s = 4; % or 9
m = 10000; % can increase up to 300k
n = 36; % can increase up to m
c = 3;
p = 25;


What I do until now is this (see code below), but this seems to be quite inefficient. I’m looking for a way on how to speed up things in a scalable way, as I need to do this operation many times (also m can increase up to 300k), thus having this step as fast as possible would be great, as this seems to be the bottleneck till now. Here the code on what I need to do:



J = cell(s, 1);
% just fill J with sparse matrices of size mxn. Each sparse matrix is different for each cell, but all have the same nnz.
J(:) = sprand(m,n,0.1);
r = rand(m, c, p);
l = rand(s, c, p);

% preallocate vectors
row_vec = zeros(nnz(J1),c*p);
col_vec = zeros(nnz(J1),c*p);
val_vec = zeros(nnz(J1),c*p);

% do computation
for pi = 1:p
for ci = 1:c
J_ = 0;
for si=1:s % multiply each sparse matrix in cell with scalar l(si,ci,pi) and sum them up
J_ = J_ + Jsi * l(si,ci,pi);
end
% multiply resulting sparse matrix with diagonal matrix (resulting from vector r(:,ci,pi)) and get final indices for later
[row_vec_temp, ...
col_vec(:,(pi-1)*c+ci), ...
val_vec(:,(pi-1)*c+ci)] = find(spdiags(r(:,ci,pi),0,m,m) * J_);
row_vec(:,(pi-1)*c+ci) = row_vec_temp + row_vec(end,max(1,(pi-1)*c+ci-1));
end
end
% build final stacked sparse matrix of size m*c*pxn using calculated indices.
J_final = sparse(row_vec, col_vec, val_vec);


Additionally, I found this way without nested for-loops, but this seems to be even less efficient:



% create cell 1xcxp cell from r, where each cell is mx1 vector
R = mat2cell(r, m, ones(c,1), ones(p,1));
% make each cell a sparse diagonal matrix
R = repmat(cellfun(@(x) spdiags(x,0,m,m), R, 'UniformOutput', false), s, 1, 1);
% do point-wise computation
C = cellfun(@(x,y,z) z*(x.*y), repmat(J',1,c,p), mat2cell(l,ones(s,1),ones(c,1),ones(p,1)), R, 'UniformOutput',false);
% sum over each row of resulting cell C
J_ = cell(1,c,p);
J_(:) = 0;
for si=1:s
J_(1,:,:) = cellfun(@(x,y) (x+y), J_(1,:,:), C(si,:,:), 'UniformOutput',false);
end
% stack final cell and convert it to sparse matrix
J_final = cell2mat(cat(1,J_(:)));


The first version takes roughly 0.27s and the second version takes about 0.3s.










share|improve this question
























  • Do you have access to the Parallel processing toolbox? Looking at the code, it seems like your process is mostly independent (as in each loop isn't dependent on the loop before) and a Parfor loop might help speed it up.

    – Hojo.Timberwolf
    Nov 13 '18 at 5:53















0















What I have is a cell J of size 1xs filled with sparse matrices of size mxn (m>=n), and two full matrices r and l of size mxcxp and sxcxp, respectively. The dimensions are roughly



s = 4; % or 9
m = 10000; % can increase up to 300k
n = 36; % can increase up to m
c = 3;
p = 25;


What I do until now is this (see code below), but this seems to be quite inefficient. I’m looking for a way on how to speed up things in a scalable way, as I need to do this operation many times (also m can increase up to 300k), thus having this step as fast as possible would be great, as this seems to be the bottleneck till now. Here the code on what I need to do:



J = cell(s, 1);
% just fill J with sparse matrices of size mxn. Each sparse matrix is different for each cell, but all have the same nnz.
J(:) = sprand(m,n,0.1);
r = rand(m, c, p);
l = rand(s, c, p);

% preallocate vectors
row_vec = zeros(nnz(J1),c*p);
col_vec = zeros(nnz(J1),c*p);
val_vec = zeros(nnz(J1),c*p);

% do computation
for pi = 1:p
for ci = 1:c
J_ = 0;
for si=1:s % multiply each sparse matrix in cell with scalar l(si,ci,pi) and sum them up
J_ = J_ + Jsi * l(si,ci,pi);
end
% multiply resulting sparse matrix with diagonal matrix (resulting from vector r(:,ci,pi)) and get final indices for later
[row_vec_temp, ...
col_vec(:,(pi-1)*c+ci), ...
val_vec(:,(pi-1)*c+ci)] = find(spdiags(r(:,ci,pi),0,m,m) * J_);
row_vec(:,(pi-1)*c+ci) = row_vec_temp + row_vec(end,max(1,(pi-1)*c+ci-1));
end
end
% build final stacked sparse matrix of size m*c*pxn using calculated indices.
J_final = sparse(row_vec, col_vec, val_vec);


Additionally, I found this way without nested for-loops, but this seems to be even less efficient:



% create cell 1xcxp cell from r, where each cell is mx1 vector
R = mat2cell(r, m, ones(c,1), ones(p,1));
% make each cell a sparse diagonal matrix
R = repmat(cellfun(@(x) spdiags(x,0,m,m), R, 'UniformOutput', false), s, 1, 1);
% do point-wise computation
C = cellfun(@(x,y,z) z*(x.*y), repmat(J',1,c,p), mat2cell(l,ones(s,1),ones(c,1),ones(p,1)), R, 'UniformOutput',false);
% sum over each row of resulting cell C
J_ = cell(1,c,p);
J_(:) = 0;
for si=1:s
J_(1,:,:) = cellfun(@(x,y) (x+y), J_(1,:,:), C(si,:,:), 'UniformOutput',false);
end
% stack final cell and convert it to sparse matrix
J_final = cell2mat(cat(1,J_(:)));


The first version takes roughly 0.27s and the second version takes about 0.3s.










share|improve this question
























  • Do you have access to the Parallel processing toolbox? Looking at the code, it seems like your process is mostly independent (as in each loop isn't dependent on the loop before) and a Parfor loop might help speed it up.

    – Hojo.Timberwolf
    Nov 13 '18 at 5:53













0












0








0








What I have is a cell J of size 1xs filled with sparse matrices of size mxn (m>=n), and two full matrices r and l of size mxcxp and sxcxp, respectively. The dimensions are roughly



s = 4; % or 9
m = 10000; % can increase up to 300k
n = 36; % can increase up to m
c = 3;
p = 25;


What I do until now is this (see code below), but this seems to be quite inefficient. I’m looking for a way on how to speed up things in a scalable way, as I need to do this operation many times (also m can increase up to 300k), thus having this step as fast as possible would be great, as this seems to be the bottleneck till now. Here the code on what I need to do:



J = cell(s, 1);
% just fill J with sparse matrices of size mxn. Each sparse matrix is different for each cell, but all have the same nnz.
J(:) = sprand(m,n,0.1);
r = rand(m, c, p);
l = rand(s, c, p);

% preallocate vectors
row_vec = zeros(nnz(J1),c*p);
col_vec = zeros(nnz(J1),c*p);
val_vec = zeros(nnz(J1),c*p);

% do computation
for pi = 1:p
for ci = 1:c
J_ = 0;
for si=1:s % multiply each sparse matrix in cell with scalar l(si,ci,pi) and sum them up
J_ = J_ + Jsi * l(si,ci,pi);
end
% multiply resulting sparse matrix with diagonal matrix (resulting from vector r(:,ci,pi)) and get final indices for later
[row_vec_temp, ...
col_vec(:,(pi-1)*c+ci), ...
val_vec(:,(pi-1)*c+ci)] = find(spdiags(r(:,ci,pi),0,m,m) * J_);
row_vec(:,(pi-1)*c+ci) = row_vec_temp + row_vec(end,max(1,(pi-1)*c+ci-1));
end
end
% build final stacked sparse matrix of size m*c*pxn using calculated indices.
J_final = sparse(row_vec, col_vec, val_vec);


Additionally, I found this way without nested for-loops, but this seems to be even less efficient:



% create cell 1xcxp cell from r, where each cell is mx1 vector
R = mat2cell(r, m, ones(c,1), ones(p,1));
% make each cell a sparse diagonal matrix
R = repmat(cellfun(@(x) spdiags(x,0,m,m), R, 'UniformOutput', false), s, 1, 1);
% do point-wise computation
C = cellfun(@(x,y,z) z*(x.*y), repmat(J',1,c,p), mat2cell(l,ones(s,1),ones(c,1),ones(p,1)), R, 'UniformOutput',false);
% sum over each row of resulting cell C
J_ = cell(1,c,p);
J_(:) = 0;
for si=1:s
J_(1,:,:) = cellfun(@(x,y) (x+y), J_(1,:,:), C(si,:,:), 'UniformOutput',false);
end
% stack final cell and convert it to sparse matrix
J_final = cell2mat(cat(1,J_(:)));


The first version takes roughly 0.27s and the second version takes about 0.3s.










share|improve this question
















What I have is a cell J of size 1xs filled with sparse matrices of size mxn (m>=n), and two full matrices r and l of size mxcxp and sxcxp, respectively. The dimensions are roughly



s = 4; % or 9
m = 10000; % can increase up to 300k
n = 36; % can increase up to m
c = 3;
p = 25;


What I do until now is this (see code below), but this seems to be quite inefficient. I’m looking for a way on how to speed up things in a scalable way, as I need to do this operation many times (also m can increase up to 300k), thus having this step as fast as possible would be great, as this seems to be the bottleneck till now. Here the code on what I need to do:



J = cell(s, 1);
% just fill J with sparse matrices of size mxn. Each sparse matrix is different for each cell, but all have the same nnz.
J(:) = sprand(m,n,0.1);
r = rand(m, c, p);
l = rand(s, c, p);

% preallocate vectors
row_vec = zeros(nnz(J1),c*p);
col_vec = zeros(nnz(J1),c*p);
val_vec = zeros(nnz(J1),c*p);

% do computation
for pi = 1:p
for ci = 1:c
J_ = 0;
for si=1:s % multiply each sparse matrix in cell with scalar l(si,ci,pi) and sum them up
J_ = J_ + Jsi * l(si,ci,pi);
end
% multiply resulting sparse matrix with diagonal matrix (resulting from vector r(:,ci,pi)) and get final indices for later
[row_vec_temp, ...
col_vec(:,(pi-1)*c+ci), ...
val_vec(:,(pi-1)*c+ci)] = find(spdiags(r(:,ci,pi),0,m,m) * J_);
row_vec(:,(pi-1)*c+ci) = row_vec_temp + row_vec(end,max(1,(pi-1)*c+ci-1));
end
end
% build final stacked sparse matrix of size m*c*pxn using calculated indices.
J_final = sparse(row_vec, col_vec, val_vec);


Additionally, I found this way without nested for-loops, but this seems to be even less efficient:



% create cell 1xcxp cell from r, where each cell is mx1 vector
R = mat2cell(r, m, ones(c,1), ones(p,1));
% make each cell a sparse diagonal matrix
R = repmat(cellfun(@(x) spdiags(x,0,m,m), R, 'UniformOutput', false), s, 1, 1);
% do point-wise computation
C = cellfun(@(x,y,z) z*(x.*y), repmat(J',1,c,p), mat2cell(l,ones(s,1),ones(c,1),ones(p,1)), R, 'UniformOutput',false);
% sum over each row of resulting cell C
J_ = cell(1,c,p);
J_(:) = 0;
for si=1:s
J_(1,:,:) = cellfun(@(x,y) (x+y), J_(1,:,:), C(si,:,:), 'UniformOutput',false);
end
% stack final cell and convert it to sparse matrix
J_final = cell2mat(cat(1,J_(:)));


The first version takes roughly 0.27s and the second version takes about 0.3s.







matlab performance cell sparse-matrix






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 12 '18 at 13:01







SemtexB

















asked Nov 12 '18 at 12:43









SemtexBSemtexB

1469




1469












  • Do you have access to the Parallel processing toolbox? Looking at the code, it seems like your process is mostly independent (as in each loop isn't dependent on the loop before) and a Parfor loop might help speed it up.

    – Hojo.Timberwolf
    Nov 13 '18 at 5:53

















  • Do you have access to the Parallel processing toolbox? Looking at the code, it seems like your process is mostly independent (as in each loop isn't dependent on the loop before) and a Parfor loop might help speed it up.

    – Hojo.Timberwolf
    Nov 13 '18 at 5:53
















Do you have access to the Parallel processing toolbox? Looking at the code, it seems like your process is mostly independent (as in each loop isn't dependent on the loop before) and a Parfor loop might help speed it up.

– Hojo.Timberwolf
Nov 13 '18 at 5:53





Do you have access to the Parallel processing toolbox? Looking at the code, it seems like your process is mostly independent (as in each loop isn't dependent on the loop before) and a Parfor loop might help speed it up.

– Hojo.Timberwolf
Nov 13 '18 at 5:53












0






active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53262468%2fefficient-way-to-do-cell-multiplication-and-stacking-of-sparse-matrices-in-matla%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53262468%2fefficient-way-to-do-cell-multiplication-and-stacking-of-sparse-matrices-in-matla%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

Syphilis

Darth Vader #20