Как добавить к конечному размеру?

Я загружаю несколько структур из отдельных файлов и хочу собрать их в одну структуру массивов. Поскольку в структуре много полей, я перебираю ее fieldnames в данный момент так:

for fnc = fieldnames(result)'
  fn = fnc{:}
  results.(fn) = [results.(fn) result.(fn)];
end

Это прекрасно работает для скалярных полей, однако некоторые поля являются векторами или матрицами и поэтому должны храниться как матрицы или тензоры 3-го ранга соответственно. Я могу использовать некоторые if length и if ndims для индивидуального рассмотрения этих случаев, но

есть ли более общий способ использовать следующее более высокое измерение для добавления?


person Tobias Kienzler    schedule 25.02.2011    source источник


Ответы (2)


Чтобы добавить последнее измерение, вы можете использовать команды CAT и NDIMS:

%# find the number of dimensions
nd = ndims(results.(fn));
%# catenate along the last dimension
results.(fn) = cat(nd,results.(fn), newResult.(fn));

Обратите внимание, что построение массивов с помощью катенации может быть довольно медленным, если есть много итераций, хотя в вашем случае предварительное выделение будет несколько связано, поэтому я бы делал это только в том случае, если это действительно необходимо. Кроме того, использование переменных results, а также result настраивает вас на наличие трудно обнаруживаемых ошибок.

person Jonas    schedule 25.02.2011
comment
поскольку для первой итерации результаты (которые я на самом деле называю r, чтобы уменьшить (?!) путаницу) не инициализируются, вместо этого я использую nd = ndims(result.(fn))+1. Тогда работает отлично, спасибо - person Tobias Kienzler; 25.02.2011

Это мое текущее решение, которым я не очень доволен:

    % merge current result fields into results
    resFields = fieldnames(result);
    for jf = 1:numel(resFields)
        rf = resFields{jf};
        resf = result.(rf);
        nd = ndims(resf);
        rt = r.(rf);
        if nd==2 && min(size(result.(rf)))==1 % scalar or vector
            rt = [ rt; result.(rf) ];
        elseif nd == 2 % true matrix, so append to 3rd rank tensor
            rt(:,:,end+1) = result.(rf);
        elseif ndims(result.(rf)) == 3 % 3rd rank tensor, append to 4th rank tensor
            rt(:,:,:,end+1) = result.(rf);
        else
            warning(['Too many dimensions for result field ' rf ': ' num2str(ndims(result.(rf)))]);
            rt(end+1) = result.(rf);
        end;
        results.(rf) = rt;
        end;
    end;

Я мог бы, конечно, вручную расширить это до любого ранга тензора до разумной степени, но это очень избыточно и уродливо, поэтому я был бы очень признателен за более красивое решение, которое работает и в общем случае.

person Tobias Kienzler    schedule 25.02.2011