Подматрица MATLAB над переменными размерами - PullRequest
1 голос
/ 28 мая 2010

У меня есть матрица переменного размера, X. Мне нужна функция, которая получит первую половину X в одном измерении. Я хочу что-то вроде этого:

function x = variableSubmatrix(x, d)
    if d == 1
        switch ndims(x)
            case 1
                x = x(1:end/2);
            case 2
                x = x(1:end/2, :);
            case 3
                x = x(1:end/2, :, :);
            (...)
        end
    elseif d == 2
        switch ndims(x)
            case 2
                x = x(:, 1:end/2);
            case 3
                x = x(:, 1:end/2, :);
            (...)
        end
    elseif (...)
    end
end

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

Ответы [ 3 ]

7 голосов
/ 28 мая 2010

Это должно сработать:

function x = variableSubmatrix(x, d)
  index = repmat({':'},1,ndims(x));  %# Create a 1-by-ndims(x) cell array
                                     %#   containing ':' in each cell
  index{d} = 1:size(x,d)/2;          %# Create an index for dimension d
  x = x(index{:});                   %# Index with a comma separated list
end

Вышеуказанное сначала создает массив ячеек размером 1 на ndims(x) с ':' в каждой ячейке. Ячейка, соответствующая измерению d, затем заменяется вектором, содержащим числа от 1 до половины размера измерения d. Затем содержимое массива ячеек выводится в виде списка, разделенного запятыми (с использованием синтаксиса {:}) и используется в качестве индексов для x. Это работает, потому что ':' и : обрабатываются одинаково (то есть "все элементы этого измерения") при использовании в операторе индексирования.

0 голосов
/ 28 мая 2010

Для чего стоит, вот решение на Python (с numpy):

Чтобы уменьшить размер вдвое i:

def halve(x,i):
    return x[(slice(None),)*i+(slice(x.shape[i]/2),)]

x = zeros([2,4,6,8])
y = halve(x,2) # dimension 2 was 6
y.shape # (2,4,3,8) # dimension 2 is now 3

Если вы просто хотите вдвое уменьшить первое измерение, тогда достаточно x[:len(x)/2].

Редактировать

Я получил несколько скептических комментариев по поводу моего предыдущего решения, x[:len(x)/2], поэтому вот пример:

x=zeros([4,2,5,6,2,3]) # first dimension is 4
len(x) # 4
x.shape # 4,2,5,6,2,3
x[:len(x)/2].shape # 2,2,5,6,2,3 <- first dimension divided by two
0 голосов
/ 28 мая 2010

Вы можете использовать s = size(X), чтобы получить размеры X, а затем попытаться X(1:floor(s(1)),:), чтобы получить половину матрицы.

Обратите внимание, что size возвращает векторный массив, содержащий длину в каждом измерении (например, матрица 2x3 вернет размер [2 3]). Таким образом, вы можете изменить s(1) на любой размер, который вам требуется.

Пример:

a = [1 2 3 4; 5 6 7 8;]

s = size(a);          % s = [2 4]

b = a(1:s(1)/2,:);    % b = [1 2 3 4];
c = a(:,1:s(2)/2);    % c = [1 2; 5 6];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...