【问题标题】:Why does this MATLAB 'if' statement not work?为什么这个 MATLAB 'if' 语句不起作用?
【发布时间】:2014-11-02 13:56:29
【问题描述】:

我对 MATLAB 还是很陌生,我不知道为什么我的“if”语句和条件不起作用。我有一个 100×4 矩阵 (randQ)。 13 列是随机整数,第 4 列每行包含 1 或 2。

我想将所有1 更改为0 并将所有2 更改为1 在该100×4 矩阵中的列4 中。 我正在做的是:

if randQ(:,4) == 1
    randQ(:,4) = 0
elseif randQ(:,4) ==2
    randQ(:,4) = 1
end

它不会引发任何错误,但矩阵不会改变,在我看来,这些条件非常合理。我不知道为什么它不起作用。欢迎任何解释。

【问题讨论】:

    标签: matlab if-statement matrix


    【解决方案1】:

    免责声明

    其他一些答案包含不正确/不准确的声明:

    举个例子,

    if [1, 1, 1] == 1
        disp("True")
    end
    

    将显示"True"。请参阅下面的说明。


    你写

    我不明白为什么我的“if”语句和条件不起作用

    发生的事情实际上非常微妙。您需要了解几件事:

    1. randQ(:,4) == 1 的表达式返回什么,
    2. “if”语句在呈现谓词(不是标量,而是数组)时的作用,
    3. randQ(:,4) = 0 做了什么。

    此外,您需要开始使用logical indexing进行此类操作。

    randQ(:,4) == 1 返回的内容

    假设randQ 是一个100×4 数组,表达式randQ(:,4) == 1 返回一个100×1 logical array,即充满(逻辑)0 和1:

    • 如果这个数组的第i个条目是(逻辑的)1,则意味着randQ的条目(i,4)等于1
    • 如果此数组的第 i 个条目是(逻辑)0,则意味着 randQ 的条目 (i,4)等于 1

    数组作为谓词

    现在您知道您正在使用数组作为“if”语句的谓词,让我们看看会发生什么。如果您的“if”语句的谓词是一个数组,MATLAB 将执行“if”分支只有当该数组的所有条目的计算结果都为逻辑 1

    例如,

    if [1, 2; 3, 4]
        disp("True")
    else
       disp("False")
    end
    

    将显示"True",因为[1,2;3,4] 的所有条目都被转换为逻辑1,这导致谓词被评估为逻辑1 (true)。然而,

    if [1, 2; 3, 0]
        disp("True")
    else
       disp("False")
    end
    

    将显示"False",因为[1,2;3,0] 的条目(2,2) 被强制转换为逻辑0,这导致谓词被评估为逻辑0 (false)。因此,如果randQ(:,4) 中至少有一项为零,则if 将不会被执行。

    你的赋值语句还是不正确

    赋值语句

    randQ(:,4) = 0
    

    将用0 覆盖第 4 列中的所有条目,这不是您想要的。

    更好的方法:使用逻辑索引

    你写

    我想在该 100×4 矩阵的第 4 列中将所有 1 更改为 0,将所有 2 更改为 1。

    对此,as pointed out by giuseppe 更惯用的方法是使用 logical indexing

    randQ(randQ(:,4) == 1, 4) = 0;
    randQ(randQ(:,4) == 2, 4) = 1;
    

    不过,不需要使用find 函数,因为randQ(:,4) == 1 已经返回您想要的:一个100×1 逻辑数组,指示randQ 的第4 列的哪些条目等于1 .

    【讨论】:

    • 谢谢!这是一个很好的解释。
    • 我将它回滚到您的正确版本。 randQ(:,4) == 1 确实返回一个逻辑数组。 find 返回索引列表。不是一回事,但是当用于索引时,两者都会给出相同的结果。
    • @BenVoigt 谢谢:s 有了所有这些编辑,我最终把自己搞糊涂了。
    【解决方案2】:

    randQ(:,4) 的结果是一个长度为 100 的向量。然后您尝试将其与标量进行比较,只有当向量(或矩阵)的所有成员都等于标量时才会如此.

    > M=[1 1; 2 1; 3 2]
    M =                                            
    
       1   1
       2   2
       3   1
    
    > M(:,1)
    ans =
    
       1
       2
       3
    

    此外,您尝试更改值的方式不正确,如果您这样做randQ(:,4) = 1,那么整个第 4th 列将获得值 1:

    >M(:,2)=0
    M =
    
       1   0
       2   0
       3   0
    

    实现你想要的最简单的方法是在循环中逐行迭代矩阵,检查值然后更改它。

    【讨论】:

    • 然后你试图将它与一个标量进行比较,这永远不会是真的。试试if [1,1] == 1, disp("True"), end
    【解决方案3】:

    您是在问您的向量是否 == 1,但事实并非如此。

    还有更多方法可以做到这一点,但您可以使用 for 循环每个值。

    【讨论】:

    • 您是在询问您的向量是否 == 1,但事实并非如此。 试试if [1,1] == 1, disp("True"), end
    • @Jubobs:不,卢克是对的。根据问题中的描述,all(randQ(:,4) == 1) 不是真的,因为损坏的代码实际上确实适用于这种情况。
    • @BenVoigt 我只想指出,在某些情况下<array> == <scalar> 可以评估为逻辑1,在这种情况下,它与@987654325 的尺寸无关@.
    猜你喜欢
    • 1970-01-01
    • 2014-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    相关资源
    最近更新 更多