Matlab 中的稀疏随机矩阵,其值范围不同于 [0,1]
Sparse random matrix in Matlab with values in different range than [0,1]
如何在 Matlab 中创建一个值范围不同于默认 [0,1]
的稀疏随机矩阵,比如 [-1,1]
?我尝试过但显然不起作用的两件事是:
p = 2 * sprand(5,5,0.1) - 1
哪个returns
>> 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)
哪个returns
>> 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 函数的解决方案。
其实我想出了一个办法:
>> p = sprand(5,5,0.1)
>> d = 2 * rand(5) - 1
>> p(find(p)) = d(find(p))
这使用 sprand
生成稀疏结构,rand
和 the canonical way 移动随机值的范围以获得值在 [-1] 范围内的 5x5 矩阵,1],然后 find
函数找到具有非零值的稀疏矩阵的线性索引,并使用这些索引从随机矩阵中分配相应的值。
我看到的唯一缺点是您仍然必须生成完整的随机矩阵,所以我仍然想知道如何更有效地做到这一点。
没有必要丢弃 sprand
中的均匀随机变量并分配第二个完整的随机值矩阵。我会这样做 logical indexing and 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
and 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×N 矩阵或将 p
转换为完整矩阵然后再转换回稀疏矩阵。如果你不介意临时创建一个大的全矩阵,fasted方法(假设你有足够的内存)可能是这样的:
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
如何在 Matlab 中创建一个值范围不同于默认 [0,1]
的稀疏随机矩阵,比如 [-1,1]
?我尝试过但显然不起作用的两件事是:
p = 2 * sprand(5,5,0.1) - 1
哪个returns
>> 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)
哪个returns
>> 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 函数的解决方案。
其实我想出了一个办法:
>> p = sprand(5,5,0.1)
>> d = 2 * rand(5) - 1
>> p(find(p)) = d(find(p))
这使用 sprand
生成稀疏结构,rand
和 the canonical way 移动随机值的范围以获得值在 [-1] 范围内的 5x5 矩阵,1],然后 find
函数找到具有非零值的稀疏矩阵的线性索引,并使用这些索引从随机矩阵中分配相应的值。
我看到的唯一缺点是您仍然必须生成完整的随机矩阵,所以我仍然想知道如何更有效地做到这一点。
没有必要丢弃 sprand
中的均匀随机变量并分配第二个完整的随机值矩阵。我会这样做 logical indexing and 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
and 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×N 矩阵或将 p
转换为完整矩阵然后再转换回稀疏矩阵。如果你不介意临时创建一个大的全矩阵,fasted方法(假设你有足够的内存)可能是这样的:
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