数学建模社区-数学中国

标题: 逻辑数组与向量化 [打印本页]

作者: 森之张卫东    时间: 2015-9-8 22:24
标题: 逻辑数组与向量化

                              逻辑数组与向量化
matlab有两个基本类型的数据类型:数字型与字符型。数字型数据包括数字,字符型数据包含字符。除这两个数据类型之外,还有第三类数据类:逻辑型。

逻辑数据类型在matlab中并不真实存在。其实,它是带特定逻辑属性标准数字型数据类型。逻辑型数组通过所有的关系运算符和逻辑运算符创建。它们区别于数字型的是在调用whos命令时,(logical)会出现在类型的后面。

例如,考虑下面的语句

a = [1 2 3; 4 5 6; 7 8 9];
b = a > 5;


这些语句将会产生两个数组aba将会产生一个数组file:///C:/Users/lx/AppData/Local/Temp/msohtmlclip1/01/clip_image002.gifb将会产生一个特殊的含有逻辑属性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)是指一个数组,它从另一个数组选择所需的元素参与运算。指定的运算只在选择的元素上执行,而不执行原有的元素。

例如,假设数组ab的定义如上节所示。那么语句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
   end
end
b = a > 5;
a(b) = sqrt(a(b));


4.6
用逻辑数数组进行屏蔽运算为了比较循环结构,选择结构与应用逻辑数组运算的快慢,我们进行下面两个计算,并对它进行计时。

1.创建一个含10000个元素的数组,其值依次为110000之间的整数。用for循环和if结构计算大于5000的元素的平方根。

2.创建一个含10000个元素的数组,其值依次为110000之间的整数。用逻辑数组计算大于5000的元素的平方根。

答案:

这个程序必须创建一个含10000个元素的数组,其值依次为110000之间的整数。用两种不同的方法计算出大于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 andbranches
maxcount = 1;            % One repetition
tic;                    % Start timer
for jj = 1:maxcount
   a = 1:10000;        %Declare arraya
   for ii = 1:10000
        if a(ii) > 5000
            a(ii) = sqrt(a(ii));
        end
   end
end
average1 = (toc)/maxcount;%Calculateaverage time
%
% Perform calculation using logicalarrays.
maxcount = 10;      %One repetition
tic;                %Start timer
for jj = 1:maxcount
   a = 1:10000;    %Declare array a
   b = a > 5000;   %Create mask
   a(b) = sqrt(a(b));  %Take squareroot
end
average2 = (toc)/maxcount;  %Calculate average time
%
% Display result
fprintf('Loop/if approach = %8.4f\n',average1);
fprintf('Logical array approach = %8.4f\n',average2);


这个程序在cpu为奔腾III(主频为733mhz)的计算机运行得到结果如下

>> logical1
Loop /if approach =   0.1200
Logical array approach =   0.0060


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


好的编程习惯

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




作者: 森之张卫东    时间: 2015-9-8 22:25
挺有用的,希望大家学习学习!!!

作者: mathworker    时间: 2015-9-9 14:27
的确有用,在matlab中规避循环的一个很好的方法。

作者: mathworker    时间: 2015-9-10 09:31
如数字型和字符型数据一样,逻辑型数据也无需事先定义,一般由比较运算后得到。





欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5