Следующее должно работать. В этом случае я выполняю неэффективное преобразование в массивы ячеек, поэтому возможна более эффективная реализация.
cuml = [0; cumsum(l(:))];
get_x = @(idx) x((1:l(idx))+cuml(idx));
x_cell = arrayfun(get_x, 1:numel(l), 'UniformOutput', false);
B = blkdiag(x_cell{:});
A = B*B';
Редактировать
После выполнения некоторых тестов я обнаружил, что реализация на основе прямого цикла примерно вдвое быстрее, чем описанный выше подход на основе ячеек.
A = zeros(sum(l));
B = zeros(sum(l), numel(l));
prev = 0;
for idx = 1:numel(l)
xidx = (1:l(idx))+prev;
A(xidx, xidx) = x(xidx,1) * x(xidx,1)';
B(xidx, idx) = x(idx,1);
prev = prev + l(idx);
end