森之张卫东 发表于 2015-9-8 22:24

逻辑数组与向量化


                              逻辑数组与向量化
matlab有两个基本类型的数据类型:数字型与字符型。数字型数据包括数字,字符型数据包含字符。除这两个数据类型之外,还有第三类数据类:逻辑型。
“逻辑”数据类型在matlab中并不真实存在。其实,它是带特定逻辑属性标准数字型数据类型。逻辑型数组通过所有的关系运算符和逻辑运算符创建。它们区别于数字型的是在调用whos命令时,(logical)会出现在类型的后面。
例如,考虑下面的语句
a = ;b = a > 5;

这些语句将会产生两个数组a和b。a将会产生一个数组file:///C:/Users/lx/AppData/Local/Temp/msohtmlclip1/01/clip_image002.gif,b将会产生一个特殊的含有逻辑属性file:///C:/Users/lx/AppData/Local/Temp/msohtmlclip1/01/clip_image004.gif。当调用whos命令时,结果如下。注意b后面的(logical)修饰符。
>> whos Name      Size                    Bytes  Class a         3x3                        72  double array b         3x3                         9  logical array Grand total is 18 elements using 81bytes

我们还可以用logical函数给一个数组加上一个逻辑属性。例如,语句c=logical(a),将会把a值赋于c,从而使c带有一定的逻辑性:
一个数组的逻辑属性可以通任何的数学运算去除。例如,如果我们在c数组加0,数组的值不会改变,而它的逻辑属性将会消失
>> c=b+0 c =     0     0     0    0     0     1    1     1     1 >> whos Name      Size                    Bytes  Class a         3x3                        72  double array b         3x3                         9  logical array c         3x3                        72  double array Grand total is 27 elements using 153bytes

                         逻辑数组的重要性


逻辑数组有一个重要的属性——它在算术运算中能提供一个屏蔽(mask)。
   屏蔽(mask)是指一个数组,它从另一个数组选择所需的元素参与运算。指定的运算只在选择的元素上执行,而不执行原有的元素。
例如,假设数组a和b的定义如上节所示。那么语句a(b)=sqrt(a(b))会计算a中相应的元素的平方根,相应的元素是指与b数组中的非零元素相对应的数组a中的元素。其他元素保持不变。
>> a(b)=sqrt(a(b)) a =    1.0000    2.0000    3.0000   4.0000    5.0000   2.4495   2.6458    2.8284    3.0000

对于一个数组的子集快速而简单,而不用循环和选择结构。
下面的语句,是用循环结构和选择结构计算上述问题。
for ii = 1:size(a,1)   for jj = 1:size(a,2)        if a(ii,jj) > 5            a(ii,jj)=sqrt(a(ii,jj));        end   endend b = a > 5;a(b) = sqrt(a(b));

例4.6
用逻辑数数组进行屏蔽运算为了比较循环结构,选择结构与应用逻辑数组运算的快慢,我们进行下面两个计算,并对它进行计时。
1.创建一个含10000个元素的数组,其值依次为1到10000之间的整数。用for循环和if结构计算大于5000的元素的平方根。
2.创建一个含10000个元素的数组,其值依次为1到10000之间的整数。用逻辑数组计算大于5000的元素的平方根。
答案:
这个程序必须创建一个含10000个元素的数组,其值依次为1到10000之间的整数。用两种不同的方法计算出大于5000的元素的平方根。
比较两种方法运行速度的matlab程序如下所示:
% Script file:logical1.m%% Purpose:%  This program calculates the time required to %  calculate the square roots of all elements in %  array a whose value exceeds 5000. This is done%  in two differents ways:%  1.Using a for loop and if construct.%  2.Using a logical array.%% Record of revisions:%  Date            Programmer          Description of change%  ====        ================    ==============================% 06/01/02      S. J.  Chapman         Original code%% Define variables:%  a                   --Array ofinput values%  b                   --Logicalarray to serve as a mask%  ii,jj               --Loop index%  average1            --Average timefor calculation 1%  average2            --Average timefor calculation 2%  maxcount            --Number oftimes to loop calculation%  month               --Month (mm)%  year                --Year (yyyy)%% Perform calculation using loops andbranchesmaxcount = 1;            % One repetitiontic;                    % Start timerfor jj = 1:maxcount   a = 1:10000;        %Declare arraya   for ii = 1:10000        if a(ii) > 5000            a(ii) = sqrt(a(ii));        end   endendaverage1 = (toc)/maxcount;%Calculateaverage time%% Perform calculation using logicalarrays.maxcount = 10;      %One repetitiontic;                %Start timerfor jj = 1:maxcount   a = 1:10000;    %Declare array a   b = a > 5000;   %Create mask   a(b) = sqrt(a(b));  %Take squarerootendaverage2 = (toc)/maxcount;  %Calculate average time%% Display resultfprintf('Loop/if approach = %8.4f\n',average1);fprintf('Logical array approach = %8.4f\n',average2);

这个程序在cpu为奔腾III(主频为733mhz)的计算机运行得到结果如下
>> logical1Loop /if approach =   0.1200Logical array approach =   0.0060

正如我们看到的,用逻辑数组方法速度是另一种方法的20倍。

好的编程习惯
如果用可能的话,可用逻辑函数选择数组中的元素。如果逻辑数组进行运算,要比循环快得多。



森之张卫东 发表于 2015-9-8 22:25

挺有用的,希望大家学习学习!!!

mathworker 发表于 2015-9-9 14:27

的确有用,在matlab中规避循环的一个很好的方法。

mathworker 发表于 2015-9-10 09:31

如数字型和字符型数据一样,逻辑型数据也无需事先定义,一般由比较运算后得到。
页: [1]
查看完整版本: 逻辑数组与向量化