虽然我已经提出了使用多个if / else if
语句的解决方法,但我很想知道我的case
语句出了什么问题,如下所示:
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)
...
效率低但工作正常的解决方案多个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
答案 0 :(得分:7)
MATLAB中case
语句cannot be conditionals的switch
表达式。它们必须是值。
switch thing
case 1
% do thing
case {2, 3}
% do other thing
otherwise
end
所以MATLAB在你的情况下正在做的是它将你的条件转换为值。因此,当您提供的值为0.073时,MATLAB会看到这一点。
switch 0.73
case 0
case 0
case 0
case 1
case 0
case 0
case 0
otherwise
end
由于0.73显然与这些值中的任何一个都不匹配,因此您会遇到otherwise
并收到错误。
这就是为什么switch语句真的只适用于将输入值与精确可能值进行比较的分类数据(显然不适合浮点数)。
如果您真的想要将其保留为switch语句,那么可以做一些小动作并实际让您的切换表达式只是“1”(true
)它会按照你的意愿行事。
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
语句的长树)。这是一种很好的方法(并且非常适合浮点数),因为它只是检查该数字是否在给定范围内。
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
我个人会做的事情就是删除所有代码,只需将其替换为以下语句。
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
是一个空数组。
这大大降低了复制/粘贴错误的可能性,如果您想在以后修改条件,则会更容易。特别是对于价值而言,它可能也更具性能。 0.25必须遍历整个if/elseif
构造。
答案 1 :(得分:1)
在Suever's answer的基础上,考虑到您实际上是在尝试解决数据分箱问题,如果您有 R2015a 或更高版本,您也可以使用在discretize
函数中实现同样的事情;例如:
function bucket = ri(ar_vo,edgz)
if nargin < 1
edgz = [0, 0.005, 0.02, 0.05, 0.1, 0.15, 0.25, inf];
end
bucket = discretize(ar_vo,edgz);
if isnan(bucket)
error('MATLAB:RI Bucket:NotAvailable.');
end
end