bsxfun против repmat с использованием матричных входов разных размеров для соответствия индексам - PullRequest
0 голосов
/ 06 июня 2018

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

Я использую короткий кодс репмат.Цель этого кода состоит в том, чтобы идентифицировать индексы между A и B, где векторы строк одинаковы, поэтому я могу позже удалить их, но использование repmat занимает слишком много времени с использованием Matlab R2016a.

Здесь A и B не обязательно имеют одинаковый размер, поэтому использование repmat в общем случае не работает.В настоящее время размеры A и B составляют 8020x3 и 21615x3.Я обнаружил, что этот метод создания размеров A и B одинаков, работает, но я открыт и для других методов.

if isequal(size(A),size(B))==1

else
    a = size(A,1);
    b = size(B,1);

    if a<b
        A = [A;nan(abs(B-A),3)];
    else
        B = [B;nan(abs(B-A),3)];
    end
end

Я просматривал документацию bsxfun ина этом сайте Mathworks https://www.mathworks.com/matlabcentral/answers/297088-speed-up-indexing-repmat-operation и кажется, что я должен иметь возможность заменить repmat(B,length(A),1)' на bsxfun(@times, B, length(A)), но они не выводят один и тот же окончательный массив, поэтому я должен что-то делать неправильно.

Если возможно, я бы хотел изменить мой код выше, чтобы он занимал меньше времени для расчета, а также иметь A и B разных размеров, таких как приведенные выше, если это возможно.При необходимости я могу по-прежнему работать с A и B одинакового размера, но оба они будут больше, в этом случае 571000x3, поэтому вычисления также будут занимать больше времени по этой причине.

Добавление: В комментариях обсуждалось, будет ли intersect работать.Теоретически, так как A (черный) и B должны определяться как находящиеся внутри или снаружи изоповерхности (красный) в большем объеме T с использованием функции inpolyhedron https://www.mathworks.com/matlabcentral/fileexchange/37856-inpolyhedron-are-points-inside-a-triangulated-volume-#comments. По некоторым причинам,результат inpolyhedron представляет собой набор точек внутри изоповерхности с некоторыми рассеянными точками также снаружи.При использовании inpolyhedron для поиска значений за пределами изоповерхности эти "лишние" точки рассеяния не включаются в набор B, поэтому intersect находит пустой набор при вводе A и B.Points inside the isosurface

1 Ответ

0 голосов
/ 05 января 2019

Получается, что у создателя inpolyhedron есть «патч», который в основном исправляет эту проблему.

По сути, вам нужно переместить точки на небольшое количество.

Давайтескажем, все мои точки находятся в массиве с именем TestPoints.

TestPoints = combvec(x',y',z')';  % x, y, and z are column vectors
NudgedPoints = TestPoints + repmat([1e-10 1e-10 0],length(TestPoints),1);

Создание поверхности с гранями и вершинами из данных

[F,V] = isosurface(X,Y,Z,A,-3);   % you can use any value, and X, Y, and Z are positions from a meshgrid
in = inpolyhedron(F,V,NudgedPoints,'FlipNormals',false);
TestPoints_in = TestPoints(in,:);

Все заслуги в этом решении принадлежат Свенусоздатель inpolyhedron.Вы можете связаться с ним здесь .

...