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

dar*_*dor 2 matlab case switch-statement

虽然我已经提出了使用多个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
%      
Run Code Online (Sandbox Code Playgroud)

由于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
Run Code Online (Sandbox Code Playgroud)

Sue*_*ver 7

语句的case表达式不能 MATLAB中的条件.它们必须是价值观.switch

switch thing
    case 1
        % do thing
    case {2, 3}
        % do other thing
    otherwise
end
Run Code Online (Sandbox Code Playgroud)

那么MATLAB在你的情况下正在做的是它将你的条件转换为值.所以当你提供0.073的值时,MATLAB会看到这个.

switch 0.73
    case 0
    case 0
    case 0
    case 1
    case 0
    case 0
    case 0
    otherwise
end
Run Code Online (Sandbox Code Playgroud)

由于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
Run Code Online (Sandbox Code Playgroud)

请不要真正做到这一点.

真正的解决方案

一种理智的方法是使用一系列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
Run Code Online (Sandbox Code Playgroud)

最佳解决方案

个人会做的,就是删除所有代码,然后用以下语句替换它.

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
Run Code Online (Sandbox Code Playgroud)

在这种方法中,我同时ar_vo所有范围进行比较,然后bucket通过使用匹配的索引获得值.如果没有分配桶,则没有匹配,并且bucket是一个空数组.

这大大降低了复制/粘贴错误的可能性,并且如果您想在以后修改条件,则会更容易.它可能也更高效,特别是对于> 0.25的值,它必须遍历整个if/elseif构造.