FORTRAN中的数组.ppt

上传人:牧羊曲112 文档编号:6505866 上传时间:2023-11-07 格式:PPT 页数:56 大小:285.49KB
返回 下载 相关 举报
FORTRAN中的数组.ppt_第1页
第1页 / 共56页
FORTRAN中的数组.ppt_第2页
第2页 / 共56页
FORTRAN中的数组.ppt_第3页
第3页 / 共56页
FORTRAN中的数组.ppt_第4页
第4页 / 共56页
FORTRAN中的数组.ppt_第5页
第5页 / 共56页
点击查看更多>>
资源描述

《FORTRAN中的数组.ppt》由会员分享,可在线阅读,更多相关《FORTRAN中的数组.ppt(56页珍藏版)》请在三一办公上搜索。

1、第9章 Fortran中的数组,数组是Fortran语言中功能最为强大、运用最为灵活的一种数据结构。数组(ARRAY)在科学和工程计算中通常用来表示矩阵和向量。同一般的变量声明相比,数组能够同时保存多个数据。它是一种使用大规模数据的方法。配合Fortran语言中的数组操作,可用于对大量不同的数据进行处理。在存储结构上,数组占用一片连续的存储单元。程序中通过数组索引来对数组元素、片断进行操作。,9.1 数组的定义,要在程序中使用数组,需要首先在变量声明中进行数组定义。数组定义规定了数组的维数和大小,以及数组所能保存的数据类型。在程序中,通过数组引用来对数组、数组元素或者数组片断进行操作。数组是类

2、型相同、种别一致的一组变量的有序集合。它可以是整型、实型、双精度型、复型、逻辑型、字符型以及自定义类型等中的任意一种。组成数组的每一个变量被称为数组元素,并由唯一的下标来进行标识。数组定义说明了数组所能保存的数据类型、数组的维数、维的范围和数组的大小。本节主要介绍Fortran中数组定义的几种方式。,9.1.1 定义形式一,第一种数组定义形式的语法格式如下所示。类型说明:数组名(下标下界:下标上界,),该定义形式通过类型说明来显式声明数组的数据类型,并通过下标下界和下标上界来规定数组中某一维的范围。下标下界和下标上界共同组成了维说明符。当维说明符省略下标下界时,默认所在维的下标从1开始。如下代

3、码都是合法的数组定义。REAL:A(1:2,2:4)INTEGER B(10),9.1.2 定义形式二,第二种数组定义形式的语法格式如下所示。DIMENSION:数组名(下标下界:下标上界,),类型说明:数组名,该定义形式通过DIMENSION语句来进行数组的定义,通过下标下界和下标上界来规定数组中某一维的范围。在第二行通过类型说明来显式声明数组的数据类型。当省略类型说明时,采用默认的“I-N”规则来对数组的数据类型进行定义。如下代码合法的对数组进行了定义。DIMENSION:A(10),B(2:11)INTEGER:A,9.1.3 定义形式三,第三种数组定义形式的语法格式如下所示。DIMEN

4、SION(下标下界:下标上界,):数组名,类型说明:数组名,该定义形式通过DIMENSION语句直接说明了数组的维数和维的范围。这种形式定义的数组全部具有相同的维数和大小。如下代码表示了如何采用上述形式进行数组的定义。DIMENSION(10,4:10):A,B,NINTEGER:AREAL(8):N,9.1.4 定义形式四,第四种数组定义形式的语法格式如下所示。类型说明,DIMENSION:数组名(下标下界:下标上界,),类型说明,DIMENSION(下标下界:下标上界,):数组名,该定义形式可以说是前三种定义形式的综合形式。通过在DIMENSION语句前引入类型说明来显式的说明数组的数据类

5、型。下列代码演示了此种形式的数组定义。REAL,DIMENSION:I(10),M(10,5)INTEGER,DIMENSION(10):A,C,9.1.5 数组定义的特点,上述数组定义的形式中,中括弧内的部分可有可无。数组定义语句必须出现在所有可执行语句之前。除了上述基本的定义形式外,在Fortran77中可以使用COMMON语句,在Fortran90中可以用POINTER语句、ALLOCATABLE语句等对数组定义进行加强。在前面所述的四种定义形式中,定义形式因简洁直观而常见于实际使用中。此外,如下问题是在实际编程中应该注意的。在前面所述的数组定义中,I(10)、M(10,5)、A、C等称

6、为数组说明符。在同一个说明语句中有多个数组说明符时,用逗号进行分隔。数组说明符中的I、M、A、C等是数组名,其取名规则与变量相同并且不应与程序中的其他变量同名。在同一个程序单元中,一个数组名只允许定义一次,不能重复定义。例如下面的数组定义是错误的。INTEGER:A(10),A(10,20),9.2 数组的引用方式,数组经过定义之后,就可以在程序中使用了。在Fortran77标准中,数组只允许在输入输出语句中进行整体操作。在其他场合,只能对数组的元素通过下标索引的方式逐个进行操作。到了Fortran90标准,这一限制被大大放宽了。数组除了能够进行整体操作以外,还能对数组中的片断和数组的整体进行

7、操作。这进一步增强了Fortran语言在数值处理方面的能力。Fortran中数组的引用方式可以概括为以下几种:,9.2.1 引用数组元素,引用数组元素的语法格式如下所示。数组名(下标,)这种引用方式通过下标索引来对数组中的每一个元素进行操作。它是Fortran中最为传统的一种引用方式。采用这种方式进行引用时,下标的值不能超出数组定义时的下标上下界。目前市面上绝大部分的Fortran编译器都会提供在编译时进行数组下标越界检查的功能。而其他计算机语言的编译器,如C/C+编译器往往不提供这样的功能,需要程序员自行检查代码中是否存在数组越界的行为。,9.2.2 引用数组整体,引用数组整体的语法格式如下

8、所示。数组名这种引用方式通过数组名来对数组进行整体操作。这种引用方式是Fortan90中新增的,大大提高了程序编写的灵活性和简单性。我们对前一个例程TEST0901进行修改,通过整体引用来对数组进行赋值。TEST0902.F90!引用数组整体的范例PROGRAM TEST0902 IMPLICIT NONE!变量定义 REAL:A,B(5,5)READ(*,*)A!数组整体引用 B=AEND PROGRAM TEST0902,9.2.3 引用数组片断,引用数组片断的语法格式如下所示。数组名(下标范围,)在这种引用方式中,数组中的元素可以用过数组片断来进行引用。当需要给数组中的不同片断的元素赋予

9、不同数值时,这种引用方式非常方便。来看下面一个例子。TEST0903.F90!引用数组片断的范例PROGRAM TEST0903 IMPLICIT NONE!变量定义 REAL:A1,A2,A3,A4,A5,B(5,5)READ(*,*)A1,A2,A3,A4,A5!数组片断的引用 B(1,1:5)=A1 B(2,1:5)=A2 B(3,1:5)=A3 B(4,1:5)=A4 B(5,1:5)=A5END PROGRAM TEST0903,9.3 数组的存储,尽管在Fortran语言中,允许程序员声明维数高达7维的数组来使用,但是计算机的内存却只是一维的。所以不管声明的数组有几维,数组在内存中

10、都是以一维的方式来进行存储。数组中元素在计算机内的存储顺序同时也被用作输入/输出时确定其中的元素数据在进行操作时的先后顺序。,9.3.1 数组的存储结构,Fortran中,一维数组在计算机内存中的存储是最简单的一种情况。在逻辑结构上,一维数组可以看成是由一系列数组元素组成的一个单列数据表。数组中每个元素的下标就确定了此元素在数据表中的位置。下标越小,在数据表中的位置就越靠前。在计算机内存中,一维数组占据一片连续的存储单元,单个元素在内存中的位置就是其逻辑结构中的位置。,9.3.2 数组存储结构的应用,目前的计算机硬件体系结构决定了在读取大批量数据时,如果这一批数据都位于临近的内存中时,读取操作

11、会执行得较快。在编写程序时,如果想要提高执行效率,就应该对数据在计算中的保存方式和读取方式有一定的了解。只有了解了数据在计算内的存储结构,才能在编写程序的时候做到有的放矢。这样编写出来的程序在数据的存取效率上才能较高。需要注意的是,尽管Fortran中的数组是按“列元素优先”的规则进行存储的,但是C语言中的数组则是按照“行元素优先”的原则进行存储,并且C语言中数组的下标下界固定是从0开始的。在编写相关的程序时,应该注意到这一差别。Fortran语言中,使用DO循环进行高效率数组操作的代码写法可能在C语言中恰恰是最低效的。比如下面的程序段在Fortran中能够得到较好的执行效率:DO J=1,5

12、 DO I=1,3 Sum=Sum+A(I,J)ENDDO,9.4 数组的类型,根据数组在定义时的特征,比如数组的秩、数组的形状和每一维的大小,可以将数组划分为好几种类型。这些不同类型的数组在程序单元中如何使用?在哪些程序单元中使用?有什么特点?本节将针对这些问题进行逐一介绍。,9.4.1 显形数组,显形(Explicit-shape)数组是Fortran中最简单、最容易理解的一种数组类型。顾名思义,这种类型的数组在定义阶段就通过数组定义语句明确的规定了所有特征,比如数组的秩、数组的维数、每一维的长度和上下界。通过这种方式定义的数组具有确定的形状和大小,在程序运行过程中不允许再对数组的任何特征

13、进行改变。需要注意的是,在显形数组的维说明中,还允许使用整型变量或整型表达式来定义维的上下界。这涉及到两种特殊的显形数组,会在随后的小节中进行介绍。,9.4.2 特殊的显形数组自动数组,自动数组(Automatic Array)是显形数组的一种特殊形式,这种形式的显形数组只能是过程中的局部变量。使用自动数组时最好在过程中加以声明,并且数组中至少有一维的上下界是不确定的整型变量或整型表达式。在调用过程时,自动数组中不确定的上下界首先通过整型变量或整型表达式求出。这样,整型变量或整型表达式的值在过程中发生的变化,就不会影响到数组中的上下界。,9.4.3 特殊的显形数组可调数组,可调数组(Adjus

14、table Array)也是显形数组的一种特殊形式,这种类型的显形数组只能是过程中的一个哑元。可调数组中至少有一维的上下界不是常数,这个维的上下界只有当过程被调用时才能最终确定。并且该维的上下界表达式中的整型变量可以是通过过程传递的哑元,也可以是通过COMMON语句中传递的整型常量或变量。和自动数组类似,过程内部对维界参数的赋值不会改变数组中该维的上下界。,9.4.4 显形数组的不足,显形数组是数组应用的基础,其中的自动数组和可调数组能够提供非常灵活的数组应用。比如自动数组在处理具体数量未知的大笔数组数据时,能够提供相当好的解决方案。但是有一点需要注意,由于自动数组和可调数组都是通过过程来使用

15、的,因此过程的一些特点也会影响到这两种数组的使用。比如使用自动数组时,过程在计算机中的堆栈限制会妨碍可使用的自动数组的大小。这种情况可以通过在执行TEST0906时,将变量I设置成一个大数(比如100000)来观察到,此时屏幕上的打印信息如下:Input the value of I:100000forrtl:severe(170):Program Exception-stack overflowImage PC Routine Line SourceTEST0307.exe 004011DB Unknown Unknown UnknownTEST0307.exe 0040110A Unkno

16、wn Unknown UnknownTEST0307.exe 0043FCD9 Unknown Unknown UnknownTEST0307.exe 00428FF9 Unknown Unknown Unknownkernel32.dll 7C816FD7 Unknown Unknown UnknownIncrementally linked image-PC correlation disabled.,9.4.5 假定形状数组,假定形状(Assumed-shape)数组是一种在过程中使用的特殊类型数组,这种类型的数组借助过程中的哑元从实际传递到过程中的数组获得自身的形状参数。假定形状数组的

17、秩由数组定义中冒号“:”的个数来决定,其一般形式如下:类型声明 数组名(下界:,下界:.)如果在定义时不指定维的下界值,则默认这一维的下界值为1。维的上界值等于过程调用中实参数组对应维的长度加上定义中规定的下界值再减去1。假定形状数组与可调数组的区别非常细微:可调数组是一种显型数组,在定义时必须指定维的上界(尽管这个上界可以是变量或表达式);而假定形状数组在定义时是不能指定维的上界的。来看这样一个代码段:SUBROUTINE ASSUMEDSHAPE(A)REAL A(:,:,:)END SUBROUTINE ASSUMEDSHAPE,9.4.6 假定大小数组,假定大小(Assumed-siz

18、e)数组也是一种在过程中使用的特殊类型数组的哑元,这种类型的数组借助过程中的哑元从实际传递到过程中的数组来获得自身的大小。1假定大小数组的定义:假定大小数组在声明时,除了最后一维的上界以外,其它所有特征(比如数组的秩、维的长度和维的上下界等)都必须明确指定。声明假定大小数组的一般形式如下:类型说明 数组名(维说明符,维说明符,.下界:*)2假定大小数组的应用,9.4.7 延迟形状数组,延迟形状(Deferred-shape)数组是Fortran 90/95标准中才开始引入的特殊类型数组,这种类型的数组在声明时并不制定数组的维界,具体的维界需要在程序执行过程中才能确定。延迟形状数组的典型代表就是

19、数组指针和可分配数组。声明延迟形状数组时,数组的秩由冒号“:”来确定,但每一维的长度是未知的。数组的维界和形状在程序执行过程中给延迟形状数组分配存储空间之后才能决定。可分配数组可以通过ALLOCATABLE语句、DIMENSION语句、TARGET语句或在类型声明中使用ALLOCATABLE属性来进行说明;而数组指针则由POINT语句或在类型声明中使用POINTER属性来进行说明。数组指针的边界和形状通过指针赋值语句指向目标之后进行确定,或者通过ALLOCATE语句直接进行指针的空间分配;而可分配数组的边界和形状则只能通过ALLOCATABEL语句来进行指定。,9.5 数组的动态分配,所谓数组

20、的动态分配就是指数组的大小、形状等特征是在程序运行中动态的确定,而不是在程序声明段就确定好了的。数组的动态分配能给程序设计提供更大的灵活性。本节就将介绍有关数组动态分配的有关内容。,9.5.1 自动数组与可分配数组,从存储状态来说,数组可以划分为静态数组和动态数组两种。如果数组是静态的,那么在编译阶段就会为数组分配好固定的储存空间,这些存储空间在程序执行过程中会一直保留的,直到程序退出时才会被释放。程序运行过程中,静态数组的大小不会发生改变。静态数组的一个主要缺陷在于,即使数组已经不再使用,仍然会占据分配给它的内存空间,这就造成了系统资源的浪费。如果计算机的内存资源有限,这会使得其他程序的可用

21、内存资源减少。最严重的情况是可用内存资源不足,这将导致程序执行错误。,9.5.2 可分配数组的分配与释放,在实际的程序中,往往会碰到这样的问题:一些数组的大小在程序执行之前并不知道具体的大小,只能在程序运行的过程中才能确定。那么如何解决这类问题呢?一个办法就是为程序声明一个足够大的数组,大到将数据一股脑全装进去后还有富裕。但是这又会造成存储空间的浪费,在过去386、486的时代,浪费宝贵的内存无疑就是犯罪。另一种办法就是前面提到过的自动数组,这需要用到过程的概念和良好的程序设计结构。如果碰到有些数组需要作为全局变量在不同的过程中进行处理的情况,就只好采用开一个大数组的办法来解决。为了更有效的利

22、用计算机中的内存,Fortran 90/95标准中正是引入了可分配数组的概念。通过ALLOCATE语句可以动态的创建可分配数组,使内存和对象可以在程序开始运行之后才建立起相互联系。,9.5.3 可分配数组的应用实例,下面的代码实例演示了可分配数组在程序中的应用,以加深对可分配数组的理解。(详细内容请参照本书),9.6 数组赋值,当数组配置好内存空间后,可以通过赋值语句或是数组构造器为数组中的元素进行赋值。Fortran语言中,数组的赋值可以通过赋值语句、DATA语句和数组构造器这三种手段来进行。,9.6.1 数组赋值语句,首先介绍数组赋值语句。数组赋值语句是Fortran 90/95标准中新增

23、加的数组赋值手段。数组赋值语句的基本形式为:数组对象=value其中,数组对象代表数组名或数组片段,value表示数组表达式或者标量。当value为数组表达式时,必须和数组对象具有相同的形状(即维数相同、每维长度相同,但上下界可以不同);当value大小为0或者是长度为0的字符型变量时,则没有值赋给数组对象;当value为标量时,会把value处理成与数组对象相同的形状,此时数组对象的每个元素均等于标量value的值。数组表达式中允许使用“+”、“-”、“*”、“/”、“*”等内部算术操作符。,9.6.2 数组构造器,数组构造器是由括号和斜线对之间的一系列数值组成,其一般形式为:数组名=(/取

24、值列表/)其中,取值列表可以是标量,隐式DO循环或者任意秩的数组。取值列表中所有数值的类型都应该相同,数值之间以逗号分隔。如果取值列表中出现了数组,则它的值是按“列元素优先”的规则来赋给目标数组变量。数组构造器的标识“(/”和“/)”在书写时要注意,括弧和撇号之间不能有空格。下面来看一些实例。MN=(/1,3,5,7,9/)!标量表示AB=(/B(2,1:5),B(3:7,7:9)/)!数组表示CC=(/(I,I=1,4)/)!隐DO循环DE=(/10,A(2:7),(I,I=1,4),7/)!混合表示,9.6.3 DATA语句,DATA语句从Fortran 77时代开始就已经用于数组的赋值,

25、只适用于数组初值的设置。本小节将介绍DATA语句进行数组赋值的基本用法。1DATA语句赋值的特点同前面所述的两种数组赋值语句不同的是,DATA语句允许直接对数组进行部分赋值,但此时编译器一般会给出警告信息,提示赋值数量不足。也就是说,在DATA语句中可以不要求数值的数量必须与被赋值数组的数组元素个数相同。被赋值数组中的数组元素按照“列元素优先”的原则“抢夺”数据段中的数据,一句话:先到先得。2DATA语句的特殊性DATA语句是一种特殊的说明语句,与普通的说明语句有很大的不同。普通的说明语句必须放在说明段中,也就是必须放在可执行语句之前。但是DATA语句允许出现在程序单元结束语句END前的任意位

26、置。由于DATA语句是在编译期间就会执行的语句,因此,不管程序中出现多少条DATA语句,也不管DATA语句出现在什么位置,同一个变量在程序执行前只允许有一个值。这个值以出现在程序中的最后一条DATA语句的赋值为准。这就是为什么在本小节开始说DATA只适用于设置初值的缘故。,9.7 数组的输入输出,在Fortran语言中,数组的操作方式非常丰富。其中,对数组的输入/输出操作即可以使用隐式DO循环来指定要进行输入/输出的每一维数组元素的起始位置、终止位置和步长增量,也可以直接给出要进行输入/输出的数组名、数组元素以及数组片段。下面将分别进行讲解。,9.7.1 一维数组的输入输出,一维数组的输入/输

27、出操作是数组操作中最简单的情况,也是二维、三维乃至更高维数组输入/输出操作的基础。只要掌握了一维数组的输入/输出操作方法,其他高维数组的输入/输出操作就很容易理解。由于一维数组在计算机内存中进行存储时是线性排列的,因此输入/输出操作时,数据是按照数组给出的下标值依次进行输入/输出的。在对一维数组进行输入/输出操作时,即可以将整个数组作为输入/输出操作的对象,也可以只输入/输出数组中的一个元素、一个片断。,9.7.2 二维数组的输入输出,二维数组输入/输出操作的基础就是一维数组的输入/输出操作,两者没有本质上的不同。数组元素输入/输出的顺序是按照前面提到过的数组在计算机内存中的存储顺序来进行的。

28、由于Fortran语言中数组的存放顺序采用“列元素优先”的原则,因此在对二维数组进行输入操作是,首先输入的数据被数组中的第一列元素接收。比如要对一个的数组Array进行输入,输入语句“READ*,A”按下列顺序将数据读入给数组中的每个元素:Array(1,1)Array(2,1)Array(3,1)Array(1,2)Array(2,2)Array(3,2)Array(1,3)Array(2,3)Array(3,3)按“列元素优先”的方式进行存贮的做法与数学上按行进行处理的习惯不太不一致,在进行输入操作应该引起足够的注意。给数组中各元素赋值时,应该先输入第一列元素的值,再输入第二列、第三列、上

29、元素的值,这样才能确保计算机内接收到的矩阵是正确的。,9.7.3 其它高维数组的输入输出,更高维数组的输入输出方式也是以一维数组的输入输出为基础的。在输入时,总是最低维上的下标值变化最快。例如一个2X2X2的三维数组Mx,在使用数组名进行系统默认的输入操作时,读入数据的先后次序如下:Mx(1,1,1)Mx(2,1,1)Mx(1,2,1)Mx(2,2,1)Mx(1,1,2)Mx(2,1,2)Mx(1,2,2)Mx(2,2,2)如果想要实现以“行元素优先”为规则进行输入,则需要在输入语句中交换隐式DO循环内外层循环变量的方法来实现。比如要实现数组Mx的“行元素优先”原则输入,则可以使用下面的输入语

30、句来实现:READ*,(Array(I,J,K),K=1,2),J=1,2),I=1,2),9.8 数组的运算,数组之间的运算是Fortran语言独步数值计算领域的一大绝活。当其他计算机语言还在使用DO循环、for循环或是其他形式的循环来为数组赋初值时,Fortran早已通过数组的整体赋值完成了这一工作,并开始了对数据的处理。当其他计算机语言好容易把一大票数据读入到计算机之后,又开始用DO循环、for循环或是其他形式的循环将刚读入的两个巨型数组相加、相减以得到结果时,Fortran早已通过数组的算术运算完成了这些工作开始输出结果了。数组间的运算是Fortran 90/95标准中有利于数值计算的

31、新手段。在Fortran 77时代,数组间的运算也只能通过循环的手段来实现。在新的Fortran标准中,允许把整个数组或数组的一部分(即数组片段)作为一个独立的对象进行相关的运算。前提是进行数组运算的两个独立对象应该是大小相同、形状一致。在Fortran语言中,允许将数组或数组片断作为运算对象的运算符包括:所有的算术运算符(包括“+”、“-”、“*”、“/”、“*”五种)所有的逻辑运算符(包括“.AND.”、“.OR.”、“.NOT.”、“.NEQV.”、“.EQV.”五种)所有的关系运算符(包括“.LT.()”、“.GE.(=)”六种),9.8.1 算术运算,在数组的算术运算表达式中,允许出

32、现的对象包括数组、数组片断、数组元素和标量。不同对象之间的运算有自身的特定规则和行为模式。1算术运算的规则如果算术运算符两侧的运算对象都是数组或数组片断,则要求两个数组或数组片断应该是大小相同、形状一致的。运算在两个数组或数组片断对应位置上的数组元素间进行,保存结果的数组或数组片断也应该和运算对象大小相同、形状一致。2算术运算的行为模式,9.8.2 逻辑运算,在数组的逻辑运算表达式中,允许出现的对象包括数组、数组片断、数组元素和标量。如果逻辑运算符两侧的运算对象都是数组或数组片断,则要求两个数组或数组片断应该是大小相同、形状一致的。运算在两个数组或数组片断对应位置上的数组元素间进行,保存结果的

33、数组或数组片断也应该和运算对象大小相同、形状一致。如果逻辑运算符两侧的运算对象一个是数组或数组片断,另一个是数组元素或标量,则运算在数组或数组片断与数组元素或标量之间进行。保存结果的数组或数组片断应该与参与运算的数组或数组片断大小相同、形状一致。,9.8.3 关系运算,数组之间的关系运算在运算对象、运算规律上与数组的算术运算和逻辑运算没什么两样。假设数组A用于保存运算结果,数组B是双目关系运算中的一个运算对象,C是另一个运算对象(可以是数组,也可以是可用于关系运算的其他标量),符号“&”表示任意一种关系运算符。则语句“A=B&C”类似于执行表所示的操作:,数组的关系运算操作,9.9 常用内在函

34、数,Fortran语言中的内在函数通常都可以接受数组作为参数来进行运算,此外还有一些专用的函数适用于处理数组所特有的运算。本节就将介绍这些内在函数在数组领域的应用。,9.9.1 内部基本函数,在Fortran语言的数组表达式中,允许将数组作为内部基本函数的参数。此时,内部基本函数的函数值就是一个同参数数组形状相同的数组,它的每个位置上的元素值就是被操作数组对应位置上的数组元素取该基本函数所得的值。例如数组A和B都是形状相同的一维数组,则语句B=SQRT(A)的执行结果可以表示如下:,9.9.2 矩阵乘积函数,该函数的作用是执行数值型或逻辑型数组A与B的矩阵乘法。函数的原型为:C=MATMUL(

35、A,B)使用时,数组A和B必须是秩为1或2(也就是一维或二维)的数值型或逻辑型的有值数组,且数组A和B中至少有一个的秩为2。传入矩阵乘积函数的数组A与B的类型必须相同。数组A与B的矩阵乘积规则和结果与数学上的矩阵乘法定义一致,也就是说数组A的最后一维的长度必须和数组B的第一维的长度相同。结果数组C的秩和形状取决于参数数组的秩和形状:如果A的形状为(n,m),B的形状为(m,k),则结果数组C的秩为2,形状为(n,k)。如果A的形状为(m),B的形状为(m,k),则结果数组C的秩为1,形状为(k)。如果A的形状为(n,m),B的形状为(m),则结果数组C的秩为1,形状为(n)。,9.9.3 向量

36、点乘函数,该函数的作用是执行数值型或逻辑型数组A与B的点积乘法。函数的原型为:C=DOT_PRODUCT(A,B)使用时,数组A和B必须是秩为1(即数学上所说的向量,也即一维数组)的数值型或逻辑型的有值数组,且数组A与B的类型必须相同。一维数组A与B点乘的结果是标量,函数的点乘规则和结果值与数学上的定义相同。如果一维数组A和B中有一个的长度为0,且数组为数值型数组,则结果为0;如果数组为逻辑型数组,则结果为.FALSE.。例如DOT_PRODUCT(/1,2,3/),(/3,4,5/)的结果为26,计算过程为(1 x 3)+(2 x 4)+(3 x 5)=26。,9.9.4 元素求和函数,元素

37、求和函数属于数组规约函数中的一种。数组规约函数是一组功能类似的数组函数的统称。这组函数的主要作用就是沿着数组中的某一维,对在屏蔽表达式中值为.TRUE.的所有数组元素进行某种操作。这组函数包括SUM、PRODUCT、MAXVAL、MINVAL、COUNT、ANY和ALL函数。本节将主要介绍其中的两种。元素求和函数的主要作用是沿着数组中的某一维,对在屏蔽表达式中值为.TRUE.的所有元素求和。函数的原型为:C=SUM(A,DIM,MASK),9.9.5 元素连乘求积函数,该函数的主要作用是沿着数组中的某一维,对在屏蔽表达式中值为.TRUE.的所有数组元素求连乘积。函数的原型为:C=PRODUCT

38、(A,DIM,MASK)其中的注意事项和说明同元素求和函数。下面是一些实例。比如数组A=(/2,4,6/),则PRODUCT(A)的值是48;又如PRODUCT(B,MASK=B0.0)表示对数组B中的所有小于0的元素求连乘积。同元素求和函数一样,结果C是数组还是标量也取决于函数中维的定义和被求积数组A的大小和形状。比如数组A(2,3)=(/2,3,4,5,6,7/),则PRODUCT(A,DIM=1)的值是(23=6),(45=20),(67=42);SUM(A,DIM=2)的值是(246=48),(357=105)。,9.9.6 数组大小查询函数,该函数是数组查询函数中的一种。数组查询函数

39、一组功能类似于数组函数的统称。这组函数包括:SIZE、SHAPE、ALLOCATED、LBOUND和UBOUND函数。这里只介绍其中的两种:数组大小查询函数和数组形状查询函数。数组大小查询函数的作用是求数组沿着某一维的长度或者数组元素的总数目。函数原型为:C=SIZE(A,DIM)其中A是被查询数组,可以是假定大小数组,但不能是未定义的指针数组或未分配空间的可分配数组。当DIM等于1时,表示查询数组有几行;当DIM等于2时,表示查询数组有几列;当DIM被省略时,表示查询数组有多大(即有多少个元素)。,9.9.7 数组形状查询函数,该函数的功能就是求数组或标量的形状。函数的原型为:C=SHAPE

40、(A)其中,A表示被查询对象,可以是标量或数组,但不能是假定大小数组、未定义的指针或未分配空间的可分配数组;C保存查询结果,是一个一维整型数组。比如SHAPE(2)将返回一个零长度一维数组;如果对数组B(-2:5,9:10)进行查询,则SHAPE(B)将返回一维数组(8,2)。,9.9.8 数组合并函数,数组合并函数是数组构造函数中的一种。数组构造函数也是一系列功能相似的函数的总称,它们用于从已有数组的元素构造出新数组。这组函数包括:MERGE、PACK,UNPACK和SPREAD函数。数组合并函数的只要用途就是在屏蔽表达式的控制下,对两个独立数组进行合并操作。该函数的原型为:C=MERGE(

41、TSOURCE,FSOURCE,MASK)其中,TSOURCE可以是任意类型的数组或标量,FSOURCE是必须与TSOURCE具有相同的类型和类型参数的数组或标量。屏蔽表达式MASK必须是逻辑型数组;若MASK值为真,则结果是TSOURCE,若MASK值为假,则结果是FSOURCE。,9.9.9 数组压缩函数:,该函数的作用就是在屏蔽表达式的控制下,将数组压缩成向量数组。数组的原型为:C=PACK(A,MASK,VECTOR)A表示被压缩对象,可是任意类型的数组;屏蔽表达式MASK必须是逻辑型数组,并且与数组A相容(也就是形状相同);VECTOR是可选参数,必须为向量数组,并且与数组A具有相同

42、的类型和类型参数。结果C是秩为1的数组(就是一维数组),其类型和类型参数与数组A相同。若VECTOR存在,则结果C的大小等于VECTOR的大小,否则其大小是使屏蔽表达式MASK值为真的元素的个数;若屏蔽表达式MASK为标量并且值为真,则结果C的大小与数组A相同。结果C中的值按数组中的元素位置排序,数组A中的第i个元素对应于屏蔽表达式MASK的第i个为真元素。若VECTOR存在,且大小大n于符合条件的数组A中的元素个数t,则结果C中第i个元素值为VECTOR(i),i=t+1,n。,9.9.10 数组形状扩展和重构形函数,这是一个由两个函数组成的函数族,包括SPREAD函数与RESHAPE函数,

43、用于完成数组形状重构和扩展的任务。SPREAD函数的主要功能就是将数组沿着某一维的方向拷贝规定次数后扩展成一个新的数组。函数的原型为:C=SPREAD(A,DIM,NCOPIES)其中,A为被拷贝对象,可以是标量或任意类型的数组。当DIM等于1时,表示沿着第一维下标变化的方向扩展,也称为向下扩展;当DIM等于2时,表示沿着第二维下标变化方向扩展,也称为向右扩展。NCOPIES用于指定拷贝的次数。,9.9.11 数组转置函数,数组转置函数是数组运算函数中的一种。数组运算函数是数组函数中同矩阵运算相关的一组函数的总称,这组函数包括:TRANSPOSE、EOSHIFT和CSHIFT三个函数。数组转置

44、函数的用途就是对秩为2的数组(就是二维数组)进行转置操作。函数的原型为:C=TRANSPOSE(MATRIX)其中,数组MATRIX必须是一个二维数组。转置后的结果数组C的形状正好与数组MATRIX的形状相反。也就是说MATRIX(n,m)转置后的结果为C(m,n)。,9.9.12 去端移动函数,该函数的作用是对秩为1的数组作去端移位处理,或沿着某一维对秩大于1的数组在所有秩为1的完整数组片段上作去端移位处理。函数的原型为:C=EOSHIFT(A,SHIFT,BOUNDARY,DIM)其中,A为被进行去端移位处理的数组。SHIFT表示移动的位数,必须为整数;当SHIFT为正时,表示去端左移,当

45、SHIFT为负时,表示去端右移。在数组或数组片段的一端被移出的元素被丢弃,并在另一端移入相同数量的BOUNDARY的值。DIM表示要进行去端移位处理的数组的维,默认为1。不同的片段可以有不同的BOUNDARY值,并可在不同的方向上移动不同的位数。,9.9.13 循环替换函数,该函数的作用是将秩为1的数组的所有元素或高维数组的指定维上的元素进行循环移动。在一端上移走的元素被插到另一端。函数的原型为:C=CSHIFT(A,SHIFT,DIM)其中,A为被操作数组。SHIFT为正值时被移向左端,负值时则移向右端。DIM可以指定要进行操作的数组的维,默认值为1。比如数组A=1,2,3,4,5,6,则C

46、SHIFT(A,SHIFT=2)的结果是3,4,5,6,1,2;而CSHIFT(A,SHIFT=-2)的结果则5,6,1,2,3,4。,9.9.14 最大值元素定位函数,该函数是两个数组定位函数之一,另一个不用说也知道是最小值元素定位函数(MINLOC)。函数的原型为:C=MAXLOC(A,DIM,MASK)函数根据屏蔽表达式MASK的真值条件确定数组A中的所有元素或沿某一维DIM所有元素中第一个最大值元素出现的位置。结果C的形式取决于数组A的秩:当秩为1时,C为标量;当秩不为1时,C为一维数组。例如MAXLOC(/1,8,8,7/)的值为2。再如数组A(3,4)的形式为:,9.10 Fort

47、ran90/95的数组操作语句,Fortran 90/95中提供了许多新的数组操作语句,例如FORALL、WHERE语句等。这些语句大大提高了Fortran语言中的数组操作特性,使其在数值计算领域的优势中得到进一步加强。本小节将介绍这两种新的数组操作语句的特性和用法。,9.10.1 WHERE语句和WHERE构造,在Fortran 90/95中提供了一种新的屏蔽数组操作语句WHERE,该语句可用于从数组中提取出部分内容进行设置。实质上,WHERE语句是一种带判断条件的数组操作语句,也就是说该语句只对那些符合条件要求的数组元素进行操作。在使用上,可以分为语句形式和构造形式两种。1WHERE语句W

48、HERE语句的一般形式为:WHERE(屏蔽表达式)赋值语句2WHERE构造除了上面这种语句声明形式的用法外,还可以使用WHERE构造。3WHERE构造的嵌套同IF构造相似,WHERE构造也允许进行嵌套。,9.10.2 FORALL语句,FORALL语句也是Fortran 90/95标准中新增的数组操作语句,是数组屏蔽赋值功能(WHERE语句和WHERE构造)的一对一元素的推广。从对数组的作用形式来看,该语句同隐式DO循环操作数组的过程类似,但在功能上更为强大。1FORALL语句FORALL语句的一般形式为:FORALL(循环三元下标,循环三元下标,屏蔽表达式)赋值语句2FORALL构造除了前面介绍的FORALL语句外,FORALL也能像IF构造和WHERE构造一样以构造的形式进行实用。FORALL构造的一般形式为:构造名:FORALL(循环三元下标,循环三元下标,屏蔽表达式)块END FORALL 构造名,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号