【问题标题】:Subtracting rows and columns from a vector at non-zero indices MATLAB从非零索引处的向量中减去行和列 MATLAB
【发布时间】:2017-02-18 21:11:48
【问题描述】:

假设我在 MATLAB 中有以下矩阵:

A =[0    0    4    0; 
    0    5    0    3; 
    1    2    0    0];

给定以下向量:

b1 = [1 2 3];
b2 = [2 3 4 5];

输出应如下所示:

C1 =[0    0    3    0; 
     0    3    0    1; 
    -2   -1    0    0];

C2 =[0    0    0    0; 
     0    2    0   -2; 
    -2   -1    0    0];

C1 和 C2 是从发生在非零元素处的向量中按列和按行减去原始矩阵 A。注意 A 实际上是稀疏矩阵。显然,不使用循环的答案值得赞赏!谢谢

【问题讨论】:

    标签: matlab matrix vector


    【解决方案1】:

    这个可能会更节省内存:

    A =[0    0    4    0; 
        0    5    0    3; 
        1    2    0    0];
    
    b1 = [1 2 3].';   % transpose so it's a column vector
    b2 = [2 3 4 5].';
    
    [Arows Acols Avals] = find(A);
    C1 = sparse([Arows;Arows], [Acols;Acols], [Avals;-b1(Arows)]);
    C2 = sparse([Arows;Arows], [Acols;Acols], [Avals;-b2(Acols)]);
    

    结果:

    >> full(C1)
    ans =
    
       0   0   3   0
       0   3   0   1
      -2  -1   0   0
    
    >> full(C2)
    ans =
    
       0   0   0   0
       0   2   0  -2
      -1  -1   0   0
    

    这利用了sparse 添加为重复下标给出的值这一事实。 A 可以是稀疏的,也可以是完整的。

    【讨论】:

    • 您的解决方案正是我想要的。因此,从本质上讲,您的解决方案和 Tony 的解决方案提供了相同的结果,但您的解决方案专注于稀疏矩阵的非零元素,而不是 Tony 的零元素。我承认我在最初的问题中没有提到我的矩阵的大小,这是我的错误,但我提到我正在寻找适用于稀疏矩阵的解决方案这一事实,这可能表明我的矩阵包含许多零(零比非零多)。因此,对于此类矩阵,您的解决方案更有效。谢谢大家的考虑。
    • 没错,这只会从向量b1b2 生成与A 中的非零元素一样多的值。
    【解决方案2】:

    无需使用循环。首先执行减法,然后替换应该保留的元素0

    C1 = A - repmat(b1.',1,size(A,2));
    C2 = A - repmat(b2,size(A,1),1);
    C1(A==0)=0;
    C2(A==0)=0;
    
    C1 =
    
         0     0     3     0
         0     3     0     1
        -2    -1     0     0
    
    C2 =
    
         0     0     0     0
         0     2     0    -2
        -1    -1     0     0
    

    稀疏矩阵测试

    您还可以确认这将适用于稀疏矩阵

    A = sparse(10,10);
    A(5:6,5:6)=rand(2);
    b1 = rand(10,1);
    b2 = rand(1,10);
    
    B1 = A - repmat(b1,1,size(A,2));
    B2 = A - repmat(b2,size(A,1),1);
    
    B1(A==0)=0;
    B2(A==0)=0;
    

    【讨论】:

    • 感谢您的解决方案,您知道它们是否也适用于稀疏矩阵吗?
    • 您的解决方案非常适合小型矩阵。就我而言,对于一个大矩阵,我收到此错误:Error using == Requested 4658367597x1 (34.7GB) array exceeds maximum array size preference. Creation of arrays greater than this limit may take a long time and cause MATLAB to become unresponsive. See array size limit or preference panel for more information. Error in demo_main (line 50) B1(A==0)=0; 我必须想办法替换A==0,有什么想法吗?
    • @YAS 我的回答正确地解决了您的具体问题。但你只是在旋转和改变它。如果您的问题与大数据有关,那么您应该在另一个问题中提及它。评论不是提出完全不同的问题的好地方。
    • @YAS 另外你可以清楚地看到错误消息array exceeds maximum array size preference不是因为方法而是因为内存限制。
    • 我唯一没有提到的是我的原始矩阵可能很大。我有几个原始矩阵 A,我使用了您的解决方案,它适用于大小有限的矩阵,但不适用于大矩阵。在这种情况下,A 的大小为 76K*65K。
    【解决方案3】:
    C1 = A ~= 0; // save none zero elements of A
    b1 = b1.';   // transpose b1
    b1 = [b1, b1, b1, b1];  // create matrix of same size as A
    C1 = C1.*b1;            
    C1 = A-C1;
    

    C1:

     0     0     3     0
     0     3     0     1
    -2    -1     0     0
    

    接下来是C2

     C2 = A ~= 0;
     k = [b2; b2; b2];
     C2 = C2.*k;
     C2 = A-C2;
    

    C2:

     0     0     0     0
     0     2     0    -2
    -1    -1     0     0
    

    【讨论】:

    • 感谢您的回复。您的解决方案也有效,但我更喜欢尽可能避免矩阵算术运算,因为我正在处理相当大的矩阵。你能帮忙回答我在NKN下的最新评论吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-19
    • 2013-12-16
    • 1970-01-01
    • 2014-10-21
    • 1970-01-01
    • 2023-03-21
    • 2021-11-22
    相关资源
    最近更新 更多