median
требует сортировки элементов массива. Можно также отсортировать вручную и выделить средний блок ( редактировать: комментарий OP указывает, что элементы уже отсортированы, больше обоснования для простоты ):
function data = cntr(data,x)
x = min(x,numel(data)); % don't pick more elements than exist
data = sort(data);
start = floor((numel(data)-x)/2) + 1;
data = data(start:start+x-1);
Вы можете вставить это в однострочную анонимную функцию с некоторыми хитростями, но это только делает код уродливым. :)
Обратите внимание, что в случае неравномерного деления (когда мы не пропускаем четное количество элементов), здесь мы расставляем приоритеты для элемента слева. Вот что я имею в виду:
0 0 0 0 0 0 0 0 0 0 0 => 11 elements, x=4
\_____/
picking these 4 values
Этот выбор можно сделать более сложным, например, сдвиг интервала влево или вправо в зависимости от того, какое из этих значений ближе всего к среднему.
Учитывая, что data
(т.е. vec
) уже отсортировано, операцию индексации можно сохранить в одной строке:
cntr = @(data,x) data( floor((numel(data)-x)/2) + (1:x) );
В этой строке отсутствует значение x = min(x,numel(data))
, которое нам нужно добавить дважды, потому что мы не можем изменить переменную в анонимной функции:
cntr = @(data,x) data( floor((numel(data)-min(x,numel(data)))/2) + (1:min(x,numel(data))) );
Это мы можем упростить до:
cntr = @(data,x) data( floor(max(numel(data)-x,0)/2) + (1:min(x,numel(data))) );