2015-05-16 1 views
1

Как создать разреженную случайную матрицу в Matlab со значением, отличным от значения по умолчанию [0,1], скажем [-1,1]? Две вещи, которые я пробовал, что, очевидно, не работает, являются:Локальная случайная матрица в Matlab со значениями в разных диапазонах, чем [0,1]

p = 2 * sprand(5,5,0.1) - 1 

который возвращает

>> p = -1.0000 -1.0000 -1.0000 -1.0000 -1.0000 
     -1.0000 -1.0000 -1.0000 -1.0000 -1.0000 
     -1.0000 -1.0000 -1.0000 -1.0000 -1.0000 
     -1.0000 -1.0000 -0.4850 -1.0000 -1.0000 
     0.6814 -1.0000 -1.0000 -1.0000 -1.0000 

И

p = ceil(sprand(5,5,0.1)); 
p(find(p)) = 2 * rand(5) - 1; 
full(p) 

который возвращает

>> ans =   0 0  0 0 0 
        0 0  0 0 0 
        0 0  0 0 0 
        0 0 0.3112 0 0 
      0.3112 0  0 0 0 

Я хотел бы решение, которое не связано с циклом g и использует только матричные манипуляции или встроенные функции Matlab.

ответ

0

Не нужно выбрасывать равномерные случайные вариации от sprand и выделять вторую полную матрицу случайных значений. Я бы сделать это так, используя logical indexing и nonzeros:

p = sprand(5,5,0.1); 
p(p~=0) = 2*nonzeros(p)-1; 

В качестве альтернативы, вы можете сделать это (немного медленнее, для больших массивов в некоторых простых испытаний с R2015a):

p = sprand(5,5,0.1); 
ne0 = (p~=0); 
p(ne0) = 2*p(ne0)-1; 

Возможно логично индексирование не поддерживается для разреженных массивов в очень старых версиях Matlab. В этом случае, вы можете использовать find:

p = sprand(5,5,0.1); 
p(find(p)) = 2*nonzeros(p)-1; 

Наконец, вы также можете реализовать свою собственную функцию, чтобы сделать это с помощью randperm, ind2sub, rand и sparse:

function R = sprand11(m,n,density) 
%SPRAND11 Sparse random matrix distributed on the interval (-1,1) 
idx = randperm(m*n,round(density*m*n));  % Find random indices 
[i,j] = ind2sub([m n],idx);     % Convert linear indices subscripts 
R = sparse(i,j,2*rand(1,numel(idx))-1,m,n); % Create sparse random matrix 

Я не уверен, если именно так sprand реализован под капотом, но он должен быть близок. Это примерно в два раза быстрее, чем вышеупомянутые решения.


Все эти варианты не позволяют генерировать полную матрицу M-by-N или преобразовывать p в полный, а затем обратно в разреженный. Если вы не возражаете временно создать большую полную матрицу, метод голодания (если у вас достаточно памяти) может быть примерно так:

function R = sprand11(m,n,density) 
idx = randperm(m*n,round(density*m*n)); % Find random indices 
R = zeros(m,n); 
R(idx) = 2*rand(1,numel(idx))-1;  % Create random matrix 
R = sparse(R);       % Convert to sparse 
0

На самом деле я придумал, как сделать это:

>> p = sprand(5,5,0.1) 
>> d = 2 * rand(5) - 1 
>> p(find(p)) = d(find(p)) 

Это использует sprand для создания разреженной структуры, rand с the canonical way сдвига диапазона случайных значений, чтобы получить матрицу 5х5 со значениями в диапазон [-1,1], а затем функцию find, чтобы найти линейные индексы разреженной матрицы с ненулевыми значениями и использовать эти индексы для присвоения соответствующих значений из случайной матрицы.

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