简体   繁体   English

稀疏矩阵matlab意外行为

[英]sparse matrix matlab unexpected behavior

I am creating a sparse matrix 我正在创建一个稀疏矩阵

sp = sparse(I,J,Val,X,Y)

My Val matrix is a ones matrix. 我的Val矩阵是一个矩阵。 Much to my surprise the sp matrix does not contain only zeros and ones. 令我惊讶的是, sp矩阵不仅包含0和1。 I suppose that this happens because in some cases there are duplicates in I , J . 我想这是因为在某些情况下IJ有重复。 I mean the sp(1,1) is set to 1 2 times, and this makes it 2. 我的意思是sp(1,1)设置为1 2次,这使它成为2。

Question 1: Is my assumption true? 问题1:我的假设是正确的吗? Instead of overwriting the value, does MATLAB really add it? MATLAB真的添加它而不是覆盖这个值吗?

Question 2: How can we get around this, given that it would be very troublesome to manipulate I and J . 问题2:我们如何解决这个问题,因为操纵IJ会非常麻烦。 Something I can think of, is to use find (thus guaranteeing uniqueness) and then recreate the matrix using ones once more. 我能想到的是使用find(从而保证唯一性),然后再使用它重新创建矩阵。 Any better suggestion? 还有更好的建议吗?

Question 1: Is my assumption true? 问题1:我的假设是正确的吗? Instead of overwriting the value, does Matlab really add it? Matlab是否真的添加了它而不是覆盖该值?

Correct. 正确。 If you have duplicate row and column values each with their own values, MATLAB will aggregate them all into the same row and column location by adding them. 如果您有重复的行和列值,每个值都有自己的值,MATLAB将通过添加它们将它们全部聚合到相同的行和列位置。

This is clearly seen in the documentation but as a reproducible example, suppose I have the following row and column locations and their associated values at these locations: 这在文档中可以清楚地看到,但作为一个可重现的示例,假设我在这些位置具有以下行和列位置及其关联值:

i = [6 6 6 5 10 10 9 9].';
j = [1 1 1 2 3 3 10 10].';
v = [100 202 173 305 410 550 323 121].';

Note that these are column vectors as this shape is the expected input. 请注意,这些是列向量,因为此形状是预期输入。 In a neater presentation: 在一个更简洁的演示文稿:

>> [i j v]

ans =

     6     1   100
     6     1   202
     6     1   173
     5     2   305
    10     3   410
    10     3   550
     9    10   323
     9    10   121

We can see that there are three values that get mapped to location (6, 1) , two values that get mapped to location (10, 3) and finally two that get mapped to location (9, 10) . 我们可以看到有三个值被映射到位置(6, 1) ,两个值被映射到位置(10, 3) ,最后两个被映射到位置(9, 10)

By creating the sparse matrix and displaying it, we thus get: 通过创建稀疏矩阵并显示它,我们得到:

>> S = sparse(i,j,v)

S =

   (6,1)      475
   (5,2)      305
  (10,3)      960
   (9,10)     444

As you can see, the three values mapped to (6, 1) are summed: 100 + 202 + 173 = 475. You can verify this with the other duplicate row and column locations. 如您所见,映射到(6, 1) 6,1 (6, 1)的三个值相加:100 + 202 + 173 = 475.您可以使用其他重复的行和列位置对此进行验证。


Question 2: How can we get around this, given that it would be very troublesome to manipulate I and J. Something I can think of, is to use find (thus guaranteeing uniqueness) and then recreate the matrix using ones once more. 问题2:我们如何解决这个问题,因为操纵I和J会非常麻烦。我能想到的是使用find(从而保证唯一性),然后再使用它重新创建矩阵。 Any better suggestion? 还有更好的建议吗?

There are two possible ways to mitigate this if it is truly your desire to only have a binary matrix. 如果确实只需要二进制矩阵,那么有两种方法可以缓解这个问题。

The first way which may be more preferable to you as you mentioned that manipulating the row and column locations is troublesome is to create the matrix that you have now, but then convert it to logical so that any values that are non-zero are set to 1: 当你提到操作行和列位置时,第一种可能比你更优选的方法是创建你现在拥有的矩阵,然后将其转换为logical以便将任何非零值设置为1:

>> S = S ~= 0

S =

  10×10 sparse logical array

   (6,1)      1
   (5,2)      1
  (10,3)      1
   (9,10)     1

If you require that the precision of the matrix be back in its original double form, cast the result after you convert to logical : 如果您要求矩阵的精度返回其原始的double精度形式,请在转换为logical后转换结果:

>> S = double(S ~= 0)

S =

   (6,1)        1
   (5,2)        1
  (10,3)        1
   (9,10)       1

The second way if you wish is to work on your row and column locations so that you filter out any indices that are non-unique, then create a vector of ones for val that is as long as the unique row and column locations. 如果你愿意的第二种方法是在你的行和列的位置,这样您过滤掉非唯一索引的任何,然后创建的矢量onesval即只要独特的行和列的位置。 You can use the unique function to help you do that. 您可以使用unique功能来帮助您实现这一目标。 Concatenate the row and column locations in a two column matrix and specify that you want to operate on 'rows' . 在两列矩阵中连接行和列位置,并指定您要对'rows'进行操作。 This means that each row is considered an input rather than individual elements in a matrix. 这意味着每行被视为输入而不是矩阵中的单个元素。 Once you find the unique row and column locations, use these as input for creating the sparse matrix: 找到唯一的行和列位置后,使用这些作为输入来创建稀疏矩阵:

>> unique_vals = unique([i j], 'rows')

unique_vals =

     5     2
     6     1
     9    10
    10     3

>> vals = ones(size(unique_vals, 1));
>> S = sparse(unique_vals(:, 1), unique_vals(:, 2), vals)

S =

   (6,1)        1
   (5,2)        1
  (10,3)        1
   (9,10)       1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM