如何在Matlab中创建一个稀疏随机矩阵,其值范围不同于默认[0,1]
,比如[-1,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
我想要一个不涉及任何循环的解决方案,只使用矩阵操作或内置Matlab函数。
答案 0 :(得分:0)
实际上我找到了一种方法:
>> p = sprand(5,5,0.1)
>> d = 2 * rand(5) - 1
>> p(find(p)) = d(find(p))
这使用sprand
生成稀疏结构rand
,the canonical way移动随机值的范围,得到5x5矩阵,其值在[-1,1]范围内],然后find
函数找到具有非零值的稀疏矩阵的线性索引,并使用这些索引从随机矩阵中分配相应的值。
我看到的唯一缺点是你仍然必须生成完整的随机矩阵,所以我仍然想知道如何更有效地做到这一点。
答案 1 :(得分: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