Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
提高MATLAB中分段函数的速度_Matlab_Optimization_Vectorization - Fatal编程技术网

提高MATLAB中分段函数的速度

提高MATLAB中分段函数的速度,matlab,optimization,vectorization,Matlab,Optimization,Vectorization,我有一个小的分段函数,分析显示它占用了程序运行时间的60%。它经常被调用,因为它包含在一些积分中,我在代码中执行了很多积分 根据分析,它被调用了213560次,总共需要47.786秒,相当于每次调用约220微秒 我想给它传递一个数组,它应该返回一个数组,操作元素 我知道在Matlab中使用循环非常慢,应该避免,但我不知道如何将这种函数矢量化 function bottleradius = aux_bottle_radius(z_array) %AUXBOTTLERADIUS Radius of

我有一个小的分段函数,分析显示它占用了程序运行时间的60%。它经常被调用,因为它包含在一些积分中,我在代码中执行了很多积分

根据分析,它被调用了213560次,总共需要47.786秒,相当于每次调用约220微秒

我想给它传递一个数组,它应该返回一个数组,操作元素

我知道在Matlab中使用循环非常慢,应该避免,但我不知道如何将这种函数矢量化

function bottleradius = aux_bottle_radius(z_array)
%AUXBOTTLERADIUS Radius of aux bottle
%   This returns the radius of the aux bottle as a function of z. It works for all
%   heights of aux bottle, just remember to integrate over the right height
%   range
    bottleradius = zeros(size(z_array));
    for i = 1 : max(size(z_array))
        if z_array(i)<-30e-3
            %door cavity
            bottleradius(i) = 34e-3;
        elseif z_array(i)>=-30e-3 && z_array(i)<-20e-3
            %radiussing door cavity
            bottleradius(i) = 34e-3 + 10e-3 - sqrt((10e-3).^2 - (z_array(i)+30e-3).^2);
        elseif z_array(i)>=-20e-3 && z_array(i)<-10e-3
            %aluminium plate
            bottleradius(i) = 46e-3;
        elseif z_array(i)>=-10e-3 && z_array(i)<0e-3
            %radiussing aluminium plate to main bottle
            bottleradius(i) = 46e-3 + 10e-3 - sqrt((10e-3).^2 - (z_array(i)+10e-3).^2);
        elseif z_array(i)>=0e-3
            %top of Al plate, bottom of main bottle
            bottleradius(i) = 185e-3;
        else
            bottleradius(i) = 0;
        end
    end
end
函数瓶半径=辅助瓶半径(z_数组)
%aux瓶的AUXBOTTLERADIUS半径
%这将返回辅助瓶的半径作为z的函数。它适用于所有人
%aux瓶的高度,请记住在正确的高度上进行整合
%射程
半径=零(大小(z_数组));
对于i=1:max(大小(z_数组))
如果z_数组(i)=-30e-3&&z_数组(i)=-20e-3&&z_数组(i)=-10e-3&&z_数组(i)=0e-3
%铝板顶部,主瓶底部
半径(i)=185e-3;
其他的
半径(i)=0;
终止
终止
终止

您可以使用
逻辑
运算符完全矢量化。您基本上可以用以下代码替换该代码:

function bottleradius = aux_bottle_radius(z_array)

%// Declare initial output array of all zeroes
bottleradius = zeros(size(z_array));

%// Condition #1 - Check for all values < -30e-3 and set accordingly
bottleradius(z_array < -30e-3) = 34e-3;

%// Condition #2 - Check for all values >= -30e-3 and < -20e-3 and set accordingly
ind = z_array >= -30e-3 & z_array < -20e-3;
bottleradius(ind) = 34e-3 + 10e-3 - sqrt((10e-3).^2 - (z_array(ind)+30e-3).^2);

%// Condition #3 - Check for all values >= -20e-3 and < -10e-3 and set accordingly
bottleradius(z_array >=-20e-3 & z_array < -10e-3) = 46e-3;

%// Condition #4 - Check for all values >= -10e-3 and < 0 and set accordingly
ind = z_array >=-10e-3 & z_array < 0;
bottleradius(ind) = 46e-3 + 10e-3 - sqrt((10e-3).^2 - (z_array(ind)+10e-3).^2);

%// Condition #5 - Check for all values >= 0 and set accordingly
bottleradius(z_array >= 0) = 185e-3;
end
函数瓶半径=辅助瓶半径(z_数组)
%//声明所有零的初始输出数组
半径=零(大小(z_数组));
%//条件#1-检查所有值<-30e-3并进行相应设置
半径(z_阵列<-30e-3)=34e-3;
%//条件#2-检查所有值>=-30e-3和<-20e-3,并进行相应设置
ind=z_阵列>=-30e-3&z_阵列<-20e-3;
半径(ind)=34e-3+10e-3-sqrt((10e-3)。^2-(z_阵列(ind)+30e-3)。^2;
%//条件#3-检查所有值>=-20e-3和<-10e-3,并进行相应设置
半径(z_阵列>=-20e-3和z_阵列<-10e-3)=46e-3;
%//条件#4-检查所有值>=-10e-3和<0,并进行相应设置
ind=z_数组>=-10e-3&z_数组<0;
半径(ind)=46e-3+10e-3-sqrt((10e-3)。^2-(z_阵列(ind)+10e-3)。^2;
%//条件#5-检查所有大于等于0的值并进行相应设置
半径(z_阵列>=0)=185e-3;
终止
次要评论
  • 0e-3
    在精度方面没有任何意义。这与
    0
    基本相同,我在您的代码中对其进行了更改
  • 注意,对于条件#2和#4,我预计算了一个
    逻辑
    数组,该数组指示我们需要访问
    z_数组中相应值的位置
    ,以简化操作,并将
    中的相同位置设置为所需的计算输出。对于其他条件,我不这样做,因为你只是将它们设置为一个常数
  • 谢天谢地,您对条件#2和#4使用了元素操作符,因此无需更改这些条件的表达式

  • 您可以使用
    逻辑
    运算符完全矢量化。您基本上可以用以下代码替换该代码:

    function bottleradius = aux_bottle_radius(z_array)
    
    %// Declare initial output array of all zeroes
    bottleradius = zeros(size(z_array));
    
    %// Condition #1 - Check for all values < -30e-3 and set accordingly
    bottleradius(z_array < -30e-3) = 34e-3;
    
    %// Condition #2 - Check for all values >= -30e-3 and < -20e-3 and set accordingly
    ind = z_array >= -30e-3 & z_array < -20e-3;
    bottleradius(ind) = 34e-3 + 10e-3 - sqrt((10e-3).^2 - (z_array(ind)+30e-3).^2);
    
    %// Condition #3 - Check for all values >= -20e-3 and < -10e-3 and set accordingly
    bottleradius(z_array >=-20e-3 & z_array < -10e-3) = 46e-3;
    
    %// Condition #4 - Check for all values >= -10e-3 and < 0 and set accordingly
    ind = z_array >=-10e-3 & z_array < 0;
    bottleradius(ind) = 46e-3 + 10e-3 - sqrt((10e-3).^2 - (z_array(ind)+10e-3).^2);
    
    %// Condition #5 - Check for all values >= 0 and set accordingly
    bottleradius(z_array >= 0) = 185e-3;
    end
    
    函数瓶半径=辅助瓶半径(z_数组)
    %//声明所有零的初始输出数组
    半径=零(大小(z_数组));
    %//条件#1-检查所有值<-30e-3并进行相应设置
    半径(z_阵列<-30e-3)=34e-3;
    %//条件#2-检查所有值>=-30e-3和<-20e-3,并进行相应设置
    ind=z_阵列>=-30e-3&z_阵列<-20e-3;
    半径(ind)=34e-3+10e-3-sqrt((10e-3)。^2-(z_阵列(ind)+30e-3)。^2;
    %//条件#3-检查所有值>=-20e-3和<-10e-3,并进行相应设置
    半径(z_阵列>=-20e-3和z_阵列<-10e-3)=46e-3;
    %//条件#4-检查所有值>=-10e-3和<0,并进行相应设置
    ind=z_数组>=-10e-3&z_数组<0;
    半径(ind)=46e-3+10e-3-sqrt((10e-3)。^2-(z_阵列(ind)+10e-3)。^2;
    %//条件#5-检查所有大于等于0的值并进行相应设置
    半径(z_阵列>=0)=185e-3;
    终止
    
    次要评论
  • 0e-3
    在精度方面没有任何意义。这与
    0
    基本相同,我在您的代码中对其进行了更改
  • 注意,对于条件#2和#4,我预计算了一个
    逻辑
    数组,该数组指示我们需要访问
    z_数组中相应值的位置
    ,以简化操作,并将
    中的相同位置设置为所需的计算输出。对于其他条件,我不这样做,因为你只是将它们设置为一个常数
  • 谢天谢地,您对条件#2和#4使用了元素操作符,因此无需更改这些条件的表达式

  • 不需要对代码进行矢量化…同意@OSryx-需要进行矢量化。不需要这些嵌套的
    if
    语句。不需要对代码进行矢量化…同意@OSryx-需要进行矢量化。不需要这些嵌套的
    if
    语句。感谢接受!我很想知道你的加速有多快!谢谢-此代码将213560次调用的此函数的总执行时间缩短到15.28s,即每次调用71微秒~47秒,减少到~15.28秒,这是一个巨大的改进。谢谢分享!在我找到一个被标记为ArrayValue的积分后,我成功地将该函数所花费的总时间降到了10.28秒,而这个积分并不需要,甚至比我想象的还要好!谢谢你的接受!我很想知道你的加速有多快!谢谢-此代码将213560次调用的此函数的总执行时间缩短到15.28s,即每次调用71微秒~47秒,减少到~15.28秒,这是一个巨大的改进。谢谢分享!在我找到一个被标记为ArrayValue的积分后,我成功地将该函数所花费的总时间降到了10.28秒,而这个积分并不需要,甚至比我想象的还要好!