嵌套函数中间隔的多个CASE语句

时间:2016-03-10 14:29:24

标签: matlab switch-statement case

虽然我已经提出了使用多个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

2 个答案:

答案 0 :(得分:7)

MATLAB中case语句cannot be conditionalsswitch表达式。它们必须是

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