This can be improved even more by separating out the rows that can be vectorized from those that can't. First I write NaN
values to the end of all the b
rows. This
I find all the rows of
a
andb
with some non-null values ("good" rows). Rows that aren't good are then filled withNaN
.I find all the rows of
a
andb
where the last value is non-null ("perfect" rows).For rows that are good but not perfect ("imperfect" rows):
For
b
I can loop over them an put theNaN
values at the end. This allows me to treat allb
rows as either "perfect" or "bad", since the "imperfect" rows already have theNaN
values at the end and thus can be used in the entirety.For
a
, I can loop over the rows wherea
are imperfect andb
are not good and putNaN
at the end of those. Whereb
is good,b
will be ovewriting those anyway so it isn't necessary as long asb
is at least as long asa
.I make
c
like in the previous example.In cases where
a
is perfect andb
is good, I can just writeb
toc
at the point wherea
ends.In the cases where
a
is bad andb
is food, I can just writeb
from the start ofc
.In the remaining cases, I have to calculate where
b
starts, and then writeb
.
This reduces the time for me by about another 1/4:
function c = catnonzero_3(a, b)
c=[a,alen NaN(= size(b)a, 2)];;
blen = size(b, 2);
agood = a~=0;
bgood = b~=0;
ailast = @(ii) find(agood(ii,:), 1, 'last');
bilast = @(ii) find(bgood(ii,:), 1, 'last');
agoodrows = any(agood, 2);
bgoodrows = any(bgood, 2);
aperfectrows = agood(:,end);
bperfectrows = bgood(:,end);
aimperfectrows = agoodrows & ~aperfectrows;
a(~agoodrows, :) = NaN;
b(~bgoodrows, :) = NaN;
forif ii=find(bgoodrowsalen <= blen
apadtarg = aimperfectrows & ~bperfectrows~bgoodrows;
else
apadtarg = aimperfectrows;
end
for ii=find(apadtarg)'
ba(ii, bilastailast(ii)+1:end) = NaN;
end
for ii=find(aimperfectrowsbgoodrows & ~bgoodrows~bperfectrows)'
cb(ii, ailastbilast(ii)+1:end) = NaN;
end
c=[a, NaN(size(b))];
ailast = @(ii) find(agood(ii,:), 1, 'last');
bilast = @(ii) find(bgood(ii,:), 1, 'last');
aperfbgood = aperfectrows & bgoodrows;
c(aperfbgood, size(a, 2)+1:end) = b(aperfbgood, :);
abadbgood = ~agoodrows & bgoodrows;
c(abadbgood, 1:blen) = b(abadbgood, :);
for ii=find(aimperfectrows & bgoodrows)'
ajj = ailast(ii);
c(ii, ajj+1:ajj+blen) = b(ii, :);
end
end