Оптимизировать реорганизацию матрицы без циклов - PullRequest
0 голосов
/ 15 марта 2019

TL; DR : я пытаюсь оптимизировать следующий короткий код в Matlab. Поскольку он включает циклы над большими матрицами, он слишком медленный.

for i = 1:sz,
    for j = 1:sz,
        if X(j) == Q(i) && Y(j) == R(i),
            S(i) = Z(j);
            break
        end
    end
end

Особенности : По сути, я начал с трех векторов данных x, y и z, которые я хотел построить как поверхность. Я сгенерировал сетку из данных x и y, а затем сделал матрицу для соответствующих значений z, используя

[X, Y] = meshgrid(x, y);
Z = griddata(x, y, z, X, Y);

Поскольку данные собираются в случайном порядке, при создании графика поверхности все соединения неправильны, и график выглядит все триангулированным, как в следующем примере. enter image description here

Итак, чтобы убедиться, что Matlab соединял правильные точки, я затем реорганизовал матрицы X и Y, используя

[R, R_indx] = sort(Y);
[Q, Q_indx] = sort(X, 2);

Отсюда я подумал, что это будет простая проблема реорганизации матрицы Z на основе индексов сортировки для матриц X и Y. Но я сталкиваюсь с проблемами, потому что независимо от того, как я использую индексы, я не могу произвести правильную матрица. Например я попробовал

S = Z(R_indx); % to match the rearrangement of Y
S = S(Q_indx); % to match the rearrangement of X

и я получил этот штрих-код ... enter image description here

Запуск первого блока кода дает мне «желаемый» результат, изображенный здесь. Однако это занимает слишком много времени, поскольку это двойная петля над очень большой матрицей. enter image description here

Вопрос : Как мне оптимизировать эту перестановку матрицы Z без использования циклов?

1 Ответ

1 голос
/ 15 марта 2019

Пожалуйста, посмотрите на следующие решения и протестируйте оба с вашими матрицами.Они работают быстрее?Решение индексирования массива делает то, что вы просили, то есть переупорядочение матриц.Векторная индексация может быть даже лучше, поскольку она сортирует ваши исходные векторы вместо матриц и генерирует выходные данные непосредственно оттуда.

% Parameters.
dim = 4;

% Test input.
x = [2, -2, 5, 4];
y = [1, -4, 6, -2];
z = rand(dim);
[X, Y] = meshgrid(x, y);
Z = griddata(x, y, z, X, Y);
[R, R_indx] = sort(Y);
[Q, Q_indx] = sort(X, 2);

% Initialize output.
S = zeros(dim);

% Provided solution using loop.
for i = 1:numel(z)
  for j = 1:numel(z)
    if (X(j) == Q(i) && Y(j) == R(i))
      S(i) = Z(j);
      break
    end
  end
end

% Output.
S

% Solution using array indexing; output.
S_array = reshape(((X(:) == Q(:).') & (Y(:) == R(:).')).' * Z(:), dim, dim)

% Solution using vector indexing; output.
[r, r_indx] = sort(y);
[q, q_indx] = sort(x);
[X, Y] = meshgrid(q, r);
Z = griddata(q, r, z, X, Y);
idx = (ones(dim, 1) * ((q_indx - 1) * dim) + r_indx.' * ones(1, dim));
S_vector = Z(idx)

Пример выходных данных:

S = 
   0.371424   0.744220   0.777214   0.778058
   0.580353   0.686495   0.356647   0.577780
   0.436699   0.217288   0.883900   0.800133
   0.594355   0.405309   0.544806   0.085540

S_array =
   0.371424   0.744220   0.777214   0.778058
   0.580353   0.686495   0.356647   0.577780
   0.436699   0.217288   0.883900   0.800133
   0.594355   0.405309   0.544806   0.085540

S_vector =
   0.371424   0.744220   0.777214   0.778058
   0.580353   0.686495   0.356647   0.577780
   0.436699   0.217288   0.883900   0.800133
   0.594355   0.405309   0.544806   0.085540
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...