MATLAB的新用户会犯的一个错误是,他们想把if语句应用到矩阵或向量的每个元素上。例如:
M =魔法(7)
M =
30 39 48 1 10 19 28 38 47 7 9 18 27 29 46 6 8 17 26 35 37 5 14 16 25 34 36 45 13 15 24 33 42 44 4 21 23 32 41 43 3 12 22 31 40 49 2 11 20
M是一个矩阵。现在,用户希望有一个if语句,它将对矩阵的每个元素做不同的事情,这取决于一些测试,而MATLAB没有这样的能力,至少不是他们想要的。但有一些事情你可以做。例如,假设我想把所有的偶数除以2,但对于奇数,我想乘以3,然后加1?(你可能知道我在这里做什么,如果不知道,那么你可以读一下Collatz猜想,有时也叫3n+1问题。)
解决方案1:使用循环。
米
M =
15 118 24 4 5 58 14 19 142 22 28 9 82 88 23 34 52 13 106 112 16 7 8 76 17 18 136 40 46 12 100 21 22 2 64 70 16 124 130 106 11 94 20 148 1 34 10
它就像我们需要的那样,分别对M中的每个元素进行运算。注意,该循环使用线性索引,将矩阵视为元素向量。这在MATLAB中工作,所以我不需要在M的行和列上创建一个双循环。
但MATLAB的方法是使用矩阵。这就是MATLAB如何高效地编写的。我们可以用下一个想法。(我直接把它应用到m的最后结果上)
解决方案2:
evenloc =快速眼动(M, 2) = = 0;
M (evenloc) = M (evenloc) / 2;
M(oddloc) = 3*M(oddloc) + 1;
米
M =
46 59 12 2 16 29 7 58 71 11 14 28 41 44 70 10 2 26 40 53 56 8 22 4 38 52 9 68 20 23 6 50 64 11 1 32 35 8 62 65 53 34 47 10 74 4 17 5
如你所见,这也起作用了。没有使用显式循环,尽管在MATLAB内部,它将在较低层次的语言中执行循环,所以是隐式循环。它采用了所谓的布尔索引。我也可以用类似的方法来使用find。
解决方案3:
if (currbarscount = 1, if (currbarscount = 1, currbarscount = 1, currbarscount = 1), colorred;
if (redhat (M,2) == 1), redhat (M,2) == 1), colorred;
M (evenloc) = M (evenloc) / 2;
M(oddloc) = 3*M(oddloc) + 1;
米
M =
23 178 6 1 8 88 22 29 214 34 7 14 124 22 35 5 1 13 20 160 28 4 11 2 19 26 28 34 10 70 3 25 32 34 4 16 106 4 31 196 16 10 17 142 5 37 2 52 16
这些是常见的解决方案。万博 尤文图斯当然也有其他的方法。我本可以耍点花招,也许是这样的:
解决方案4:
M = mfac(rem(M,2) + 1) .* M + afac(rem(M,2) + 1)
M =
70 89 34 4 44 11 88 107 17 22 7 62 11 106 16 4 40 10 80 14 2 34 1 58 13 14 17 5 35 10 76 16 17 2 8 53 2 94 98 8 5 52 71 16 112 1 26 8
你可能希望仔细看看最后一个。为什么会成功呢?(因为它确实有效。)我们甚至可以把最后一个想法用在一个简单的迭代方案中,来解决经典的Collatz问题。
斜方= @ (M) mfac (rem (M, 2) + 1)。长期以来* M +我们(rem (M, 2) + 1);
而任何(~ ismember (M (:), [1 2 4]))
米
M =
4 1 2 4 4 4 4 1 1 2 4 4 1 1 2 4 4 1 1 2 2 1 2 1 4 2 1 2 2 1 2 1 4 2 1 2 2 1 2 1 4 2 1 2 1 4 2 1 2 1 4 2 1 2 1 4 2 1 2 1 4 2 1 2 4 4 1 2 4 4 1 2 4 1 2 1 1 4 4 1 2 4 1 2 1 1 4 4 1 2 1 1 4 4 1 2 1 1 4 4 1 2 1
当然,还有其他创造性的方法来解决这个问题。在任何这样的方案中,我可能会担心这个数字太大了,以至于无法在MATLAB中精确地表示为浮点算术中的整数,因此是一个双精度数。极限是在MATLAB中调用flintmax,但现在我离题太远了。