У меня есть матрица A в MATLAB и вектор целых чисел B. Затем я создаю матрицу D, удаляя столбцы A, проиндексированные одним и тем же целым числом в B, и заменяя их одним столбцом нуля. У меня есть вопрос относительно кода, который я использую для создания D, поскольку он, кажется, работает в MATLAB R2017b, но не в MATLAB R2015b.

Позвольте мне лучше объяснить на примере:

b=8;
g=3;

B=[1;2;2;2;3;4;4;5]; %bx1
bnew=size(unique(B),1);

A=[1  2  3  4  5  6  7  8;
   9  10 11 12 13 14 15 16;
   17 18 19 20 21 22 23 24]; %gxb

Матрица B сообщает нам, какие столбцы A следует удалить и заменить столбцом с нулями. Например: второй, третий и четвертый элементы B равны; это означает, что следует удалить второй, третий и четвертый столбцы A и добавить один столбец с нулями.

Следовательно ,

D=[1  0  5   0  8;
   9  0  13  0  16;
   17 0  21  0  24]; %gxbnew

Чтобы построить D, я делаю следующее:

C=sparse(1:numel(B),B,1); 
E = A * C;
D= E .* (sum(C) <= 1); 

Примечание: важно рассматривать C,E,D как разреженные, потому что в моем случае они очень большие. В этом отношении можно, например, подумайте о том, чтобы получить D, делая

C=sparse(1:numel(B),B,1); 
D = E;
D(:, sum(C) > 1) = 0;

Но я не хочу этого, потому что это невероятно медленнее.


Вопрос: Когда я бегу

C=sparse(1:numel(B),B,1); 
E = A * C;
D= E .* (sum(C) <= 1); 

В MATLAB R2017b он работает отлично, но когда я запускаю его в MATLAB R2015b, ему не нравится последняя строка и выдается как ошибка

Error using .*
Matrix dimensions must agree. 

Как я могу решить эту проблему сохранения эффективности?

1
TEX 5 Окт 2018 в 14:24

1 ответ

Лучший ответ

Проблема в том, что ваш код полагается на широковещательное / неявное расширение в R2017b, что было введено в R2016b. Если вы попытаетесь транслировать в более старых версиях, вы получите ошибки размеров. Вот почему [1 2] + [1;2] ошибок в версии до R2016b, но работает в более поздних версиях и дает матрицу 2 на 2. Решение: Сардар Усама прокомментировал использование bsxfun, который стоит для Binary Singleton eXpansion FUNction , что означает, что он выполняет то же самое, что и неявное раскрытие, которое теперь включено по умолчанию.

A = [1 2]; % 1x2
B = [3;4]; % 2x1
C = B*A; % 2x2 matrix in post-R2016b, dimension error in pre-R2016b
D = bsxfun(@times,B,A); % Working pre-R2016b

Если вы хотите, чтобы ваш код работал с обеими версиями, используйте bsxfun или, в качестве альтернативы, заключите его в блок try/catch:

try % try implicit expansion
    C = B*A;
catch % if that fails, use bsxfun
    C = bsxfun(@times,B,A);
end

Ссылаясь на документацию bsxfun:

В MATLAB® R2016b и позже встроенные двоичные функции, перечисленные в этой таблице, независимо поддерживают неявное расширение. С помощью этих функций вы можете вызывать функцию или оператор напрямую вместо использования bsxfun. Например, вы можете заменить C = bsxfun(@plus,A,B) на A+B.

4
Adriaan 7 Окт 2018 в 20:45