嵌套函数中的时间间隔上有多个CASE语句 [英] multiple CASE statements on interval within nested functions
问题描述
尽管我想出了使用多个if / else if
语句的解决方法,但我很想知道我的case
语句看起来有什么问题,如下所示:
Although I have come up with a work-around using multiple if / else if
statements, I am curious in knowing what looks wrong with my case
statements, illustrated below:
function [ar_vo,bucket] = revEng(v)
...
s=solve(solve>0) * sqrt(T);
ar_vo=s;
bucket=ri(ar_vo);
%%%%%%%%%%%%%%%%%%%%%
function bucket = ri(ar_vo)
% switch(ar_vo)
% case ((ar_vo >= 0)&&(ar_vo < 0.005)) (1)
% bucket=1;
% case ((ar_vo >= 0.005)&&(ar_vo < 0.02)) (2)
% bucket=2;
% case ((ar_vo >= 0.02)&&(ar_vo < 0.05)) (3)
% bucket=3;
% case ((ar_vo >= 0.05)&&(ar_vo < 0.1)) (4)
% bucket=4;
% case ((ar_vo >= 0.1)&&(ar_vo < 0.15)) (5)
% bucket=5;
% case ((ar_vol >= 0.15)&&(ar_vol < 0.25)) (6)
% bucket=6;
% case (ar_vo >= 0.25) (7)
% bucket=7;
% otherwise
% error('MATLAB:RI Bucket:NotAvailable.'); (8)
% end
%
在调试代码时给出ar_vo = 0.073...
,由于某些原因,它会跳过case (4)
并到达case (8)
...
Given ar_vo = 0.073...
while debugging the code, it skips case (4)
for some reasons and reaches case (8)
...
效率低下但可行的解决方案,其中包含多个if / else if
:
if ((ar_vo >= 0)&&(ar_vo < 0.005))
bucket=1;
else if ((ar_vo >= 0.005)&&(ar_vo < 0.02))
bucket=2;
else if ((ar_vo >= 0.02)&&(ar_vo < 0.05))
bucket=3;
else if ((ar_vo >= 0.05)&&(ar_vo < 0.1))
bucket=4;
else if ((ar_vo >= 0.1)&&(ar_vo < 0.15))
bucket=5;
else if ((ar_vo >= 0.15)&&(ar_vo < 0.25))
bucket=6;
else if (ar_vo >= 0.25)
bucket=7;
else
error('MATLAB:RI Bucket:NotAvailable.');
end
end
end
end
end
end
end
推荐答案
The case
expressions for your switch
statement cannot be conditionals in MATLAB. They must be values.
switch thing
case 1
% do thing
case {2, 3}
% do other thing
otherwise
end
因此,MATLAB在您的情况下所做的就是将条件转换为值.因此,当您提供0.073的值时,MATLAB会看到的是这个.
So what MATLAB is doing in your case, is that it is converting your conditionals into values. So when you supply a value of 0.073 what MATLAB sees is this.
switch 0.73
case 0
case 0
case 0
case 1
case 0
case 0
case 0
otherwise
end
由于0.73显然与您进入otherwise
并收到错误的那些值都不匹配.
Since 0.73 obviously doesn't match any of those values you fall through to the otherwise
and receive the error.
这就是为什么switch语句实际上仅最适合将输入值与 exact 可能值进行比较(显然不适合浮点数)的分类数据的原因.
This is why switch statements are really only best for categorical data where you are comparing the input value against exact possible values (obviously not good for a floating point number).
如果您真的希望将其保留为switch语句,则可以进行一些欺骗,实际上将您的switch表达式简单地设置为"1"(true
)并它会表现出您想要的样子.
If you REALLY want to keep this as a switch statement you could do a little trickery and actually make your switch expression simply "1" (true
) and it will behave as you want it to.
switch(1)
case ((ar_vo >= 0)&&(ar_vo < 0.005))
bucket=1;
case ((ar_vo >= 0.005)&&(ar_vo < 0.02))
bucket=2;
case ((ar_vo >= 0.02)&&(ar_vo < 0.05))
bucket=3;
case ((ar_vo >= 0.05)&&(ar_vo < 0.1))
bucket=4;
case ((ar_vo >= 0.1)&&(ar_vo < 0.15))
bucket=5;
case ((ar_vo >= 0.15)&&(ar_vo < 0.25))
bucket=6;
case (ar_vo >= 0.25)
bucket=7;
otherwise
error('MATLAB:RI Bucket:NotAvailable.');
end
请实际上不要这样做.
一种理智的方法是使用一系列 if/elseif
语句(与if else if
语句的长树相反).这是一个很好的方法(非常适合浮点数),因为它只是检查该数字是否在给定范围内.
One sane approach is to use a series of if/elseif
statements (as opposed to your long tree of if else if
statements). This is a good approach (and is well-suited to floating point numbers) as it simply checks if that number is within a given range.
if ((ar_vo >= 0)&&(ar_vo < 0.005))
bucket=1;
elseif ((ar_vo >= 0.005)&&(ar_vo < 0.02))
bucket=2;
elseif ((ar_vo >= 0.02)&&(ar_vo < 0.05))
bucket=3;
elseif ((ar_vo >= 0.05)&&(ar_vo < 0.1))
bucket=4;
elseif ((ar_vo >= 0.1)&&(ar_vo < 0.15))
bucket=5;
elseif ((ar_vo >= 0.15)&&(ar_vo < 0.25))
bucket=6;
elseif (ar_vo >= 0.25)
bucket=7;
else
error('MATLAB:RI Bucket:NotAvailable.');
end
最佳解决方案
我个人将要做的是删除所有代码,并简单地将其替换为以下语句.
The Best Solution
What I personally would do though, would be to remove all of that code and simply replace it with the following statements.
lowerlimits = [0, 0.005, 0.02, 0.05, 0.1, 0.15, 0.25]
upperlimits = [lowerlimits(2:end), inf];
bucket = find(ar_vo >= lowerlimits & ar_vo < upperlimits);
if isempty(bucket)
error('MATLAB:RI Bucket:NotAvailable.');
end
在这种方法中,我同时将ar_vo
与所有范围 进行比较,然后使用匹配索引获得bucket
值.如果没有分配存储桶,则没有匹配项,并且bucket
是一个空数组.
In this approach I compare ar_vo
to all ranges simultaneously and then get the bucket
value by using the index of the match. If there was no bucket assigned, there was no match, and bucket
is an empty array.
这大大减少了复制/粘贴错误的可能性,并且如果您以后想要修改条件,则可以更轻松地进行操作.尤其对于大于0.25的值(可能必须遍历整个if/elseif
构造),它的性能也可能更高.
This drastically reduces the chance of copy/paste errors and makes it easier if you want to modify the conditions at a later date. It is likely also more performant particularly for values > 0.25 which would have to traverse your entire if/elseif
construct.
这篇关于嵌套函数中的时间间隔上有多个CASE语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!