Выполнение операции усреднения по каждому n элементу в векторе - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть логический вектор, в котором я хотел бы перебирать все n-элементы. Если в любом данном окне по крайней мере 50% являются единицами, то я изменяю каждый элемент на 1, в противном случае я сохраняю как есть и перехожу к следующему окну. Например.

n = 4;

input = [0 0 0 1 0 1 1 0 0 0 0 1 0 1 0 1 0 0 0 1];

output = func(input,4);

output = [0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 0 0 0 1];

Эта функция тривиальна для реализации, но возможно ли применить векторизованную реализацию с использованием логической индексации ?. Я пытаюсь создать интуицию применения этой техники.

Ответы [ 2 ]

2 голосов
/ 28 апреля 2020

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

%% The inputs
n = 4;
input = [0 0 0 1 0 1 1 0 0 0 0 1 0 1 0 1 0 0 0 1];

1) Разделите ваш ввод на блоки размером n (обратите внимание, что ваша последняя функция нужно будет проверить, что число элементов в input является целым кратным n)

c  = reshape(input,n,[]) ;

Дает вам матрицу с вашими блоками, организованными в столбцы:

c =
     0     0     0     0     0
     0     1     0     1     0
     0     1     0     0     0
     1     0     1     1     1

2) Выполните тестовое условие на каждом блоке. Для этого мы воспользуемся тем, что Matlab работает по столбцам для функции sum:

>> cr = sum(c) >= (n/2)
cr =
     0     1     0     1     0

Теперь у вас есть логический вектор cr, содержащий столько элементов, сколько и начальных блоков. Каждое значение является результатом условия проверки по блоку. Блоки 0 останутся без изменений, для блоков 1 будет установлено значение 1.

3) Принудительно 1 столбцы / блок для значения 1:

>> c(:,cr) = 1
c =
     0     1     0     1     0
     0     1     0     1     0
     0     1     0     1     0
     1     1     1     1     1

4) Теперь осталось только развернуть вашу матрицу. Вы можете сделать это несколькими способами:

res = c(:) ; %% will give you a column vector

ИЛИ

>> res = reshape(c,1,[]) %% will give you a line vector
res =
     0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 0 0 0 1
2 голосов
/ 28 апреля 2020

вот один вкладыш (который работает для вашего ввода):

func = @(input,n) input | kron(sum(reshape(input ,n,[]))>=n/2,ones(1,n));

конечно, есть случаи, которые нужно решить, что это не отвечает, что если размер ввода не соизмерим в n? et c ... я не уверен, что вы имели в виду векторизацию, и я не сравнивал ее с a для l oop ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...