我想知道当我做类似的事情时,Matlab是否使用了懒惰的评估:
sum(points.power(points.object == 5 & points.x .^2 + points.y .^2 < r^2))
这里的想法是计算物体5上所有点的功率,只要这些点在(0,0)的r范围内。点结构是这样的:
points.object = [...]
points.x = [...]
points.y = [...]
points.power [...]
我希望Matlab不会评估那些不属于对象5的点的x ^ 2 + y ^ 2,原因与它不会评估2>3 && 3>4
的第二部分相同。我是对的吗?
答案 0 :(得分:3)
首先,我认为您正在混淆lazy evaluation和short-circuit evaluation。
了解&&
和&
是不同的运算符非常重要。 &&
运算符allows for short-circuiting和此行为取决于评估为logical
标量的每个输入。
另一方面,&
运算符接受两个数组作为输入,并在两个数组之间执行逐元素and
。为了进行这种逐元素比较,将在执行操作之前评估运算符两侧的语句。您的陈述相当于:
and(points.object == 5, points.x.^2 + points.y.^2 < r^2)
points.object == 5
和point.x.^2 + points.y.^2 < r^2
的评估都会产生logical
数组。
如果要将第二个组件的计算限制为仅条件的第一部分为true
的元素,则可以将其分解为多个语句,并使用第一个语句中的逻辑索引来确定评估第二个陈述的元素。
touse = points.object == 5;
touse(touse) = (points.x(touse).^2 + points.y(touse).^2) < r^2;
output = sum(points.power(touse));
重要的是要注意,这不一定会更快,因为现在正在执行一些额外的索引。
话虽如此,如果您在循环中执行此操作并且在要比较多个point.object
值和r
值时关注性能,则可以预先计算{{1}在循环之外。在这种情况下,您还可以继续计算此值的平方根,这样您每次循环时都不必平方points.x.^2 + points.y.^2
。
r