2013-11-07 2 views
1

Я новичок в Matlab, но я тратил документацию и не могу найти ответ на то, что я ищу.Создание матрицы из индексов и матрицы значений

Я сделал ряд вычислений на матрице, и я закончил список индексов и список значений, которые должны идти по этим индексам.

, например:

Data = 

     0   0   0   0   0   0 
    3.7417 3.7417 3.7417 7.0711 3.3166 3.3166 
    4.2426 4.2426 3.7417 7.0711 5.3852 7.0711 
    7.0711 6.0828 5.3852 7.4833 6.0828 7.6158 
    7.1414 7.4833 7.8740 8.7750 7.1414 7.8740 

и

Indices = 

    1  2  3  4  5  6 
    3  3  1  1  6  5 
    2  1  2  6  3  4 
    4  5  5  2  2  2 
    5  4  6  5  1  3 

То, что я хочу быть в состоянии сделать, это построить квадратную матрицу (размера п на основе наибольшего значного индекса найденного в матрице индексов), так что первый столбец Indices используется для индексации первой строки матрицы Result, а значения Data помещаются в соответствующие местоположения матрицы Result со всеми местами, не проиндексированными да ta установлено на 0.

I.e. с данными и индексами матриц из выше Я хочу, чтобы конечная матрица выглядеть следующим образом:

Result = 
      0 4.2426 3.7417 7.0711 7.1414   0 
    4.2426  0 3.7417 7.4833 6.0828   0 
    3.7417 3.7417   0   0 5.3852 7.8740 
    7.0711 7.4833   0   0 8.7750 7.0711 
    7.1414 6.0828 5.3852   0   0 3.3166 
      0 7.6158 7.8740 7.0711 3.3166   0 

(Там могут быть некоторые ошибки с выше, как я делал это вручную, но это должно дать представление о том, что я желающий сделать)

В Матлабе есть быстрый способ сделать это? Многие функции возвращают индексы, и я надеялся, что будет простой способ обновить/построить матрицу с использованием этих индексов.

Спасибо,

Грег

ответ

3

Чистейшая, как я знаю, как сделать это путем создания разреженной матрицы на основе ваших данных и индексов:

[M,N] = size(Indices); indmax = max(Indices(:)); 
Result = sparse(repmat(1:N,M,1),Indices,Data,indmax,indmax); 

Надеюсь, кто-то приходит и показывает нам даже более чистый метод.

+0

Я не думаю, что это становится намного чище, чем это. Если это цель, вы всегда можете «разрезать» на «полный». +1 – chappjc

+0

@chappjc Я продолжаю надеяться, что на днях кто-то придет и покажет мне, как индексировать непересекающийся список элементов в матрице, не используя 'sub2ind'. По какой-то причине я всегда сталкивался с проблемой того, что я должен указать размер матрицы, в которую я индексирую. – nispio

+0

Да, тот факт, что индексы взяты попарно, не является интуитивным. Почему «Результат» ([1 2], [1 2]) »относится к 4 элементам, а не к 2 может быть трудно проглотить. Если только MathWorks может набирать различные скобки для «автоматического подчинения». – chappjc

3

То, что вы описываете, осуществляется следующим образом:

[II,JJ]=meshgrid(1:size(Data,2),1:size(Data,1)); 
Result = zeros(size(Data,2)); 
Result(sub2ind(size(Result),II(:),Indices(:))) = Data(:); 

Обратите внимание, что получение II через meshgrid утверждение эквивалентно II=repmat(1:size(Data,2),size(Data,1),1);.

2

Это решение, основанное на bsxfun, кажется, немного быстрее, чем те, по @nispio и @chappjc:

S = max(Indices(:)); 
Result = zeros(S); 
Result(bsxfun(@plus, (Indices-1)*S, 1:S)) = Data; 
+0

+1 для написания собственной функции 'sub2ind'. :) Однако, что вы получаете в скорости, вы теряете в удобочитаемости, на мой взгляд. – nispio

+0

@nispio Полностью согласен. 'sub2ind' является более читаемым –