当前位置:文档之家› 二维数组

二维数组

二维数组
二维数组

Perl二维数组用法全程剖析

本文和大家重点讨论一下PerlPerl二维数组的概念,PerlPerl二维数组简单说就是数组的数组,创建一个数组的数组(有时也可以叫“列表的列表”,不过不太准确)真是再简单也不过了。请看下面详细介绍。

Perl二维数组

非常简短的一个Perl二维数组教程,由鄙人翻译完成。

最新版本可以从这里获取(POD格式):

https://www.doczj.com/doc/1415303198.html,/trunk/POD2-CN/lib/POD2/CN/perllol.pod

NAME

perllol-操作数组的数组(Perl二维数组)

说明

Perl二维数组中声明和访问数组的数组

创建一个数组的数组(有时也可以叫“列表的列表”,不过不太准确)真是再简单也不过了。它相当容易理解,并且本文中出现的每个例子都有可能在实际应用中出现。

数组的数组就是一个普通的数组(@AoA),不过可以接受两个下标("$AoA[3][2])。

下面先定义一个这样的数组:

1"#一个包含有“指向数组的引用”的数组

2@AoA=(

3["fred","barney"],

4["george","jane","elroy"],

5["homer","marge","bart"],

6);

7

8print$AoA[2][2];

9bart

10

你可能已经注意到,外面的括号是圆括号,这是因为我们想要给数组赋值,所以需要圆括号。如果你*不*希望这里是@AoA,而是一个指向它的引用,那么就得这样:11#一个指向“包含有数组引用的数组”的引用

12$ref_to_AoA=[

13["fred","barney","pebbles","bambam","dino",],

14["homer","bart","marge","maggie",],

15["george","jane","elroy","judy",],

16];

17

18print$ref_to_AoA->[2][2];

19

注意外面的括号现在变成了方括号,并且我们的访问语法也有所改变。这时因为和C 不同,在Perl中你不能自由地交换数组和引用(在C中,数组和指针在很多地方可以互相代替使用)。$ref_to_AoA是一个数组引用,而@AoA是一个数组。同样地,$AoA[2]也不是一个数组,而是一个数组引用。所以下面这两行:

$AoA[2][2]

$ref_to_AoA->[2][2]

也可以用这两行来代替:

$AoA[2]->[2]

$ref_to_AoA->[2]->[2]

这是因为这里有两个相邻的括号(不管是方括号还是花括号),所以你可以随意地省略箭头符号。但是如果$ref_to_AoA后面的那个箭头不能省略,因为省略了就没法知道$ref_to_AoA到底是引用还是数组了^_^。

修改Perl二维数组

前面的例子里我们创建了包含有固定数据的Perl二维数组,但是如何往其中添加新元素呢?再或者如何从零开始创建一个Perl二维数组呢?

首先,让我们试着从一个文件中读取Perl二维数组。首先我们演示如何一次性添加一行。首先我们假设有这样一个文本文件:每一行代表了Perl二维数组的行,而每一个单词代表了Perl二维数组的一个元素。下面的代码可以把它们储存到@AoA:

while(<>){

@tmp=split;

push@AoA,[@tmp }

你也可以用一个函数来一次读取一行:

for$i(1..10){

$AoA[$i]=[somefunc($i)];

}

或者也可以用一个临时变量来中转一下,这样看起来更清楚些:

for$i(1..10){

@tmp=somefunc($i);

$AoA[$i]=[@tmp];

}

注意方括号"[]"在这里非常重要。方括号实际上是数组引用的构造器。如果不用方括号而直接写,那就犯了很严重的错误:$AoA[$i]=@tmp;

你看,把一个数组赋值给了一个标量,那么其结果只是计算了@tmp数组的元素个数,我想这肯定不是你希望的。

如果你打开了"usestrict",那么你就得先定义一些变量然后才能避免警告:

1usestrict;

2my(@AoA,@tmp);

3while(<>){

4@tmp=split;

5push@AoA,[@tmp];

6}

7

当然,你也可以不要临时变量:

while(<>){

push@AoA,[split];

}

如果你知道想要放在什么地方的话,你也可以不要push(),而是直接进行赋值:

8my(@AoA,$i,$line);

9for$i(0..10){

10$line=<>;

11$AoA[$i]=[split'',$line];

12}

13

甚至是这样:

14my(@AoA,$i);

15for$i(0..10){

16$AoA[$i]=[split'',<>];

17}

18

你可能生怕<>在列表上下文会出差错,所以想要明确地声明要在标量上下文中对<>求值,这样可读性会更好一些:(译者注:列表上下文中,<>返回所有的行,标量上下文中<>只返回一行。)

19my(@AoA,$i);

20for$i(0..10){

21$AoA[$i]=[split'',<>];

22}

23

如果你想用$ref_to_AoA这样的一个引用来代替数组,那你就得这么写:

while(<>){

push@$ref_to_AoA,[split];

}

现在你已经知道如何添加新行了。那么如何添加新列呢?Perl二维数组中如果你正在做数学中的矩阵运算,那么要完成类似的任务:

24for$x(1..10){

25for$y(1..10){

26$AoA[$x][$y]=func($x,$y);

27}

28}

29

30for$x(3,7,9){

31$AoA[$x][20]+=func2($x);

32}

33

想要访问的某个元素是不是存在是无关紧要的:因为如果不存在那么Perl会给你自动创建!新创建的元素的值是"undef"。

如果你想添加到一行的末尾,你可以这么做:

#添加新列到已存在的行

push@{$AoA[0]},"wilma","betty";

注意我*没有*这么写:

push$AoA[0],"wilma","betty";#错误!

事实上,上面这句根本就没法通过编译!为什么?因为push()的第一个参数必须是一个真实的数组,不能是引用。

访问和打印

现在是打印Perl二维数组的时候了。那么怎么打印?很简单,如果你只想打印一个元素,那么就这么来一下:

print$AoA[0][0];

如果你想打印整个数组,那你可不能这样:print@AoA;#错误!

因为你这么做只能得到一列引用,Perl从来都不会自动地为你解引用。作为替代,你必须得弄个循环或者是双重循环。用shell风格的for()语句就可以打印整个Perl二维数组:

for$aref(@AoA){

print"\t[@$aref],\n";

}

如果你要用下标来遍历的话,你得这么做:

for$i(0..$#AoA){

print"\telt$iis[@{$AoA[$i]}],\n";

}

或者这样用双重循环(注意内循环):

for$i(0..$#AoA){

for$j(0..$#{$AoA[$i]}){

print"elt$i$jis$AoA[$i][$j]\n";

}

}

如同你看到的一样,它有点儿复杂。这就是为什么有时候用临时变量能够看起来更简单一些的原因:

1for$i(0..$#AoA){

2$aref=$AoA[$i];

3for$j(0..$#{$aref}){

4print"elt$i$jis$AoA[$i][$j]\n";

5}

6}

哦,好像还有点复杂,那么试试这样:

7for$i(0..$#AoA){

8$aref=$AoA[$i];

9$n=@$aref-1;

10for$j(0..$n){

11print"elt$i$jis$AoA[$i][$j]\n";

12}

13}

14

切片

切片是指Perl二维数组的一部分。如果你想要得到多维数组的一个切片,那你得进行一些下标运算。通过箭头可以方便地为单个元素解引用,但是访问切片就没有这么好的事了。当然,我们可以通过循环来取切片。

我们先演示如何用循环来获取切片。我们假设@AoA变量的值和前面一样。

@part=();

$x=4;

for($y=7;$y<13;$y++){

push@part,$AoA[$x][$y];

}

这个循环其实可以用一个切片操作来代替:

@part=@{$AoA[4]}[7..12];

不过这个看上去似乎略微有些复杂。

下面再教你Perl二维数组中如何才能得到一个*二维切片*,比如$x从4到8,$y从7到12,应该怎么写?

@newAoA=();

for($startx=$x=4;$x<=8;$x++){

for($starty=$y=7;$y<=12;$y++){

$newAoA[$x-$startx][$y-$starty]=$AoA[$x][$y];

}

}

也可以省略掉中间的那层循环:

for($x=4;$x<=8;$x++){

push@newAoA,[@{$AoA[$x]}[7..12]];

}

其实用map函数可以更加简练:

@newAoA=map{[@{$AoA[$_]}[7..12]]}4..8;

虽然你的经理也许会抱怨这种难以理解的代码可能会带来安全隐患,然而这种观点还是颇有争议的(兴许还可以更加安全也说不定^_^)。换了是我,我会把它们放进一个函数中实现:

@newAoA=splice_2D(\@AoA,4=>8,7=>12);

subsplice_2D{

my$lrr=shift;#指向Perl二维数组的引用

my($x_lo,$x_hi,

$y_lo,$y_hi)=@_;

returnmap{

[@{$lrr->[$_]}[$y_lo..$y_hi]]

}$x_lo..$x_hi;

}

二维数组和指针

要用指针处理二维数组,首先要解决从存储的角度对二维数组的认识问题。我们知道,一个二维数组在计算机中存储时,是按照先行后列的顺序依次存储的,当把每一行看作一个整体,即视为一个大的数组元素时,这个存储的二维数组也就变成了一个一维数组了。而每个大数组元素对应二维数组的一行,我们就称之为行数组元素,显然每个行数组元素都是一个一维数组 下面我们讨论指针和二维数组元素的对应关系,清楚了二者之间的关系,就能用指针处理二维数组了。 设p是指向数组a的指针变量,若有: p=a[0]; 则p+j将指向a[0]数组中的元素a[0][j]。 由于a[0]、a[1]┅a[M-1]等各个行数组依次连续存储,则对于a数组中的任一元素a[i][j],指针的一般形式如下: p+i*N+j 元素a[i][j]相应的指针表示为: *( p+i*N+j) 同样,a[i][j]也可使用指针下标法表示,如下: p[i*N+j] 例如,有如下定义: int a[3][4]={{10,20,30,40,},{50,60,70,80},{90,91,92,93}}; 则数组a有3个元素,分别为a[0]、a[1]、a[2]。而每个元素都是一个一维数组,各包含4个元素,如a[1]的4个元素是a[1][0]、a[1][1]、a[1]2]、a[1][3]。 若有: int *p=a[0]; 则数组a的元素a[1][2]对应的指针为:p+1*4+2 元素a[1][2]也就可以表示为:*( p+1*4+2) 用下标表示法,a[1][2]表示为:p[1*4+2] 特别说明: 对上述二维数组a,虽然a[0]、a都是数组首地址,但二者指向的对象不同,a[0]是一维数组的名字,它指向的是a[0]数组的首元素,对其进行“*”运算,得到的是一个数组元素值,即a[0]数组首元素值,*a等价于a[0] a[0]等价于&a[0][0],因此,*a[0]与a[0][0]是同一个值;

数据结构实验五矩阵的压缩存储与运算学习资料

数据结构实验五矩阵的压缩存储与运算

第五章矩阵的压缩存储与运算 【实验目的】 1. 熟练掌握稀疏矩阵的两种存储结构(三元组表和十字链表)的实现; 2. 掌握稀疏矩阵的加法、转置、乘法等基本运算; 3. 加深对线性表的顺序存储和链式结构的理解。 第一节知识准备 矩阵是由两个关系(行关系和列关系)组成的二维数组,因此对每一个关系上都可以用线性表进行处理;考虑到两个关系的先后,在存储上就有按行优先和按列优先两种存储方式,所谓按行优先,是指将矩阵的每一行看成一个元素进行存储;所谓按列优先,是指将矩阵的每一列看成一个元素进行存储;这是矩阵在计算机中用一个连续存储区域存放的一般情形,对特殊矩阵还有特殊的存储方式。 一、特殊矩阵的压缩存储 1. 对称矩阵和上、下三角阵 若n阶矩阵A中的元素满足= (0≤i,j≤n-1 )则称为n阶对称矩阵。对n阶对称矩阵,我们只需要存储下三角元素就可以了。事实上对上三角矩阵(下三角部分为零)和下三角矩阵(上三角部分为零),都可以用一维数组ma[0.. ]来存储A的下三角元素(对上三角矩阵做转置存储),称ma为矩阵A的压缩存储结构,现在我们来分析以下,A和ma之间的元素对应放置关系。 问题已经转化为:已知二维矩阵A[i,j],如图5-1, 我们将A用一个一维数组ma[k]来存储,它们之间存在着如图5-2所示的一一对应关系。 任意一组下标(i,j)都可在ma中的位置k中找到元素m[k]= ;这里: k=i(i+1)/2+j (i≥j) 图5-1 下三角矩阵 a00 a10 a11 a20 … an-1,0 … an-1,n-1

k= 0 1 2 3 …n(n- 1)/2 …n(n+1)/2-1 图5-2下三角矩阵的压缩存储 反之,对所有的k=0,1,2,…,n(n+1)/2-1,都能确定ma[k]中的元素在矩阵A中的位置(i,j)。这里,i=d-1,(d是使sum= > k的最小整数),j= 。 2. 三对角矩阵 在三对角矩阵中,所有的非零元素集中在以主对角线为中心的带内状区域中,除了主对角线上和直接在对角线上、下方对角线上的元素之外,所有其它的元素皆为零,见图5-3。 图5-3 三对角矩阵A 与下三角矩阵的存储一样,我们也可以用一个一维数组ma[0..3n-2]来存放三对角矩阵A,其对应关系见图5-4。 a00 a01 a10 a11 a12 … an-1,n-2 an-1,n-1 k= 0 1 2 3 4 … 3n-3 3n-2 图5-4下三角矩阵的压缩存储 A中的一对下标(i,j)与ma中的下标k之间有如下的关系: 公式中采用了C语言的符号,int()表示取整,‘%’表示求余。

矩阵方程求解方法

矩阵方程求解方法 本文所述的矩阵方程是指形如Ax=b的方程,其中A是一个mxn的矩阵,称为方程的系数 矩阵。x和b是mx1的矩阵。特别的,当b=0时,这种方程又称为其次方程。本文将讨论 这种矩阵的有解条件和求解方法。 矩阵方程的有解条件 为了解释矩阵方程的有解条件,我们首先要熟悉一些概念。 一个矩阵方程的增广矩阵是系数矩阵A和b并在一起构成的矩阵,记作(A,b)。 假定 , ,则矩阵方程的增广矩阵就是 矩阵的秩定义为其行向量中极大线性无关组中包含向量的个数,等价的说法是,矩阵的秩 是r,则矩阵通过行列初等变换,变换成左上角是一个r阶单位矩阵,其他都是0的矩阵。矩阵A的秩记作r(A),其中r是英文单词rank的缩写。 有了这两个基本概念,我们就可以准确描述矩阵方程的有解条件了:矩阵方程Ax=b的有 解条件是矩阵A的秩等于增广矩阵(A,b)的秩,也就是r(A)=r(A,b)。 证明很简单,既然矩阵A的秩是r,那么肯定可以找到两个可逆的矩阵P,Q,满足 --1) 其中I r表示r阶单位矩阵。 应用到原来的方程,可以得到: --2) 我们把Q-1x当作一个未知的变量,PAQ当作系数,这就构成一个新的矩阵方程。而这个矩 阵方程的左侧系数除了前r行是有1的之外,其余行是0。为了它有解,Pb的后m-r行必 须也是0。这样(A,b)的秩必然是r。 必须注意到Q-1是可逆的,因此以Q-1x为未知变量的方程有解意味着以x为未知变量的原 方程也是有解的。

矩阵方程的解 对于矩阵方程Ax=b,如果满足r(A)=r(A,b),则矩阵方程是有解的。为了求它的解,我们首先把矩阵方程通过行列初等变换变化成前文2)式的形式,代入1)式后得到: --3) 其中Q-1x和Pb是一个列向量,我们可以把它们分割成rx1和(n-r)x1的两个矩阵,分别记作x’1和x’2,及b’1和b’2。则很显然我们可以得到: --4) 很显然,b’2必须为0,因为展开后b’2等于0 x’1 +0 x’2 =0 而由4式可以看出,x’1= b’1,x’2可以为任意向量。 所以方程最后的解为: --5) 从解的形式可以看出解空间有如下特性: 1.方程Ax=b的解空间的秩是n=r(A) 2.如果A是满秩的,则方程的解唯一。

矩阵的运算及其运算规则

矩阵基本运算及应用 牛晨晖 在数学中,矩阵是一个按照长方阵列排列的或集合。矩阵是高等代中的常见工具,也常见于统计分析等应用数学学科中。在物理学中,矩阵于电路学、、光学和中都有应用;中,制作也需要用到矩阵。矩阵的运算是领域的重要问题。将为简单矩阵的组合可以在理论和实际应用上简化矩阵的运算。在电力系统方面,矩阵知识已有广泛深入的应用,本文将在介绍矩阵基本运算和运算规则的基础上,简要介绍其在电力系统新能源领域建模方面的应用情况,并展望随机矩阵理论等相关知识与人工智能电力系统的紧密结合。 1矩阵的运算及其运算规则 1.1矩阵的加法与减法 1.1.1运算规则 设矩阵,, 则 简言之,两个矩阵相加减,即它们相同位置的元素相加减! 注意:只有对于两个行数、列数分别相等的矩阵(即同型矩阵),加减法运算才有意义,即加减运算是可行的.

1.1.2运算性质 满足交换律和结合律 交换律; 结合律. 1.2矩阵与数的乘法 1.2.1运算规则 数乘矩阵A,就是将数乘矩阵A中的每一个元素,记为或.特别地,称称为的负矩阵. 1.2.2运算性质 满足结合律和分配律 结合律:(λμ)A=λ(μA);(λ+μ)A =λA+μA. 分配律:λ(A+B)=λA+λB. 1.2.3典型举例 已知两个矩阵 满足矩阵方程,求未知矩阵. 解由已知条件知

? 1.3矩阵与矩阵的乘法 1.3.1运算规则 设,,则A与B的乘积是这样一个矩阵: (1) 行数与(左矩阵)A相同,列数与(右矩阵)B相同,即. (2) C的第行第列的元素由A的第行元素与B的第列元素对应相乘,再取乘积之和. 1.3.2典型例题 设矩阵 计算 解是的矩阵.设它为

关于二维数组地址和指针之间的赋值

在开发工业以太网项目的时候经常遇到一些小细节问题,在建立数据报进行传输的过程中传递txbuf缓冲区的地址的时候就遇到类似下面的问题。 一.简单说明1 定义一个2X3的int型的二维数组int array[2][3];并且给这个二维数组赋值1,2,3,4,5,6;array[0][0]=1 array[0][1]=2 array[0][2]=3 array[1][0]=4 array[1][1]=5 array[1][2]=6 输出结果 1 2 3 4 5 6 array[0]表示第一行的首地址,也就是第一行第一个数的地址,也就是&array[0][0] So array[0]==&array[0][0];其实&array[0]还==array[0]==&array[0][0],都表示第一行的首地址。 array[1]是第二行的首地址,也就是第二行第一个数的地址,也就是&array[1][0] so array[1]=&array[1][0];试试&array[1]还==array[1]==&array[1][0] 定义一个指针变量int *p;将第一行的首地址赋给p有3种方式。 1. p=array[0]; 2. p=&array[0]; 3. p=&array[0][0]; p[0]就等同于array[0][0],也就是p[0]==1;(为了形象记忆,可以用替换的角度去记忆和理解。因为之前说过p=array[0], so, p[0]就把p换成array[0]再加上[0]就是arary[0][0]) p[1]等于array[0][1]等于2 p[2]等于array[0][2]等于3

图的邻接矩阵存储结构建立汇总

课程名称: 《数据结构》课程设计课程设计题目:图的邻接矩阵存储结构建立 姓名:XXX 院系:计算机学院 专业:计算机科学技术 年级:11级 学号:XXXXXXXX 指导教师:XXX 2013年9月28日

目录 1 课程设计的目的 (3) 2需求分析 (3) 3 课程设计报告内容 (3) 3.1 概要设计 (3) 3.2 详细设计 (4) 3.3 调试分析 (5) 3.4 用户手册 (5) 3.5 程序清单 (5) 3.6 测试结果 (10) 4 小结 (12) 5 参考文献 (12)

1.课程设计的目的 (1) 熟练使用 C 语言编写程序,解决实际问题; (2) 了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力; (3) 初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能; (4) 提高综合运用所学的理论知识和方法独立分析和解决问题的能力; 2.需求分析 问题描述:建立图的邻接矩阵存储结构(图的类型可以是有向图或有向网、无向图或无向网,学生可以任选一种类型),能够输入图的顶点和边的信息,并存储到相应存储结构中,而后给出图的DFS,BFS次序。 要求: ①先任意创建一个图; ②图的DFS,BFS的递归和非递归算法的实现。 3.课程设计报告内容 3.1概要设计 1.函数 ①主函数:main( ) ②创建无向图:CreateGraph( )

③深度优先遍历图:DFS( ) ④广度优先遍历图:BFS( ) 3.2详细设计 1.使用邻接矩阵作为图的存储结构,程序中主要用到的抽象数据类型: typedef struct { char vexs[MAX]; //顶点向量 int arcs[MAX][MAX]; //邻接矩阵 int vexnum,arcnum; //图的当前顶点数和弧数}Graph; 2.程序流程图:

第3章 矩阵及其运算

第3章 矩阵及其运算 3.1 基本要求、重点难点 基本要求: 1.1.掌握矩阵的定义. 2.2.掌握矩阵的运算法则. 3.3.掌握伴随矩阵的概念及利用伴随矩阵求逆矩阵的方法. 4.4.掌握矩阵秩的概念及求矩阵秩的方法. 5.5. 掌握初等变换和初等矩阵的概念,能够利用初等变换计算矩阵的秩,求可逆矩阵的逆矩阵. 6.6.掌握线形方程组有解得判定定理及其初等变换解线形方程组的方法. 重点难点:重点是矩阵定义,矩阵乘法运算,逆矩阵的求法,矩阵的秩,初等 变换及线性方程组的解. 难点是矩阵乘法,求逆矩阵的伴随矩阵方法. 3.2 基本内容 3.2.1 3.2.1 重要定义 定义3.1 由n m ?个数)2,1;,2,1(n j m i a ij ==组成的m 行n 列的数表成为一个m 行n 列矩阵,记为 ????????????mn m m n n a a a a a a a a a 2122221 11211 简记为A n m ij a ?=)(,或A )(ij a =,n m A ?,mn A 注意行列式与矩阵的区别: (1) (1) 行列式是一个数,而矩阵是一个数表. (2) (2) 行列式的行数、列数一定相同,但矩阵的行数、列数不一定相 同. (3) (3) 一个数乘以行列式,等于这个数乘以行列式的某行(或列)的所有元素,而一个数乘以矩阵等于这个数乘以矩阵的所有元素. (4) (4) 两个行列式相等只要它们表示的数值相等即可,而两个矩阵相等则要求两个矩阵对应元素相等. (5) (5) 当0||≠A 时,||1A 有意义,而A 1 无意义.

n m =的矩阵叫做阶方阵或m 阶方阵.一阶方阵在书写时不写括号,它在 运算中可看做一个数. 对角线以下(上)元素都是0的矩阵叫上(下)三角矩阵,既是上三角阵, 又是下三角的矩阵,也就是除对角线以外的元素全是0的矩阵叫对角矩阵.在对角矩阵中,对角线上元素全一样的矩阵叫数量矩阵;数量矩阵中,对角线元素全是1的n 阶矩阵叫n 阶单位矩阵,常记为n E (或n I ),简记为E (或I ),元素都是0的矩阵叫零矩阵,记为n m 0?,或简记为0. 行和列分别相等的两个矩阵叫做同型矩阵,两个同型矩阵的且对应位置上的 元素分别相等的矩阵叫做相等矩阵. 设有矩阵A =n m ij a ?)(,则A -n m ij a ?-=)(称为A 的负矩阵. 若A 是方阵,则保持相对元素不变而得到的行列式称为方针A 的行列式,记 为||A 或A Det . 将矩阵A 的行列式互换所得到的矩阵为A 的转置矩阵,记为T A 或A '. 若方阵A 满足A A T =,则称A 为对称矩阵,若方阵A 满足A A T -=,则称A 为反对称矩阵. 若矩阵的元素都是实数,则矩阵称为实矩阵.若矩阵的元素含有复数,则称矩 阵为复矩阵,若A =n m ij a ?)(是复矩阵,则称矩阵n m ij a ?)((其中ij a 为ij a 的共轭矩阵,记为A n m ij a ?=)(. 定义3.2 对于n 阶矩阵A ,如果存在n 阶矩阵B ,使得E BA AB ==,则 称方阵A 可逆,B 称为A 的逆矩阵,记做1-=A B . 对于方阵A n m ij a ?=)(,设ij a 的代数余子式为ij A ,则矩阵 *A ????????????=nm n n n n A A A A A A A A A 2122212 12111 称为A 的伴随矩阵,要注意伴随矩阵中元素的位置. 定义3.3 设有矩阵A ,如果: (1) (1) 在A 中有一个r 阶子式D 不为零.

指向二维数组的指针

指向二维数组的指针 一. 二维数组元素的地址 为了说明问题, 我们定义以下二维数组: int a[3][4]={{0,1,2,3}, {4,5,6,7}, {8,9,10,11}}; a为二维数组名, 此数组有3行4列, 共12个元素。但也可这样来理解, 数组a由三个元素组成: a[0], a[1], a[2]。而它中每个元素又是一个一维数组, 且都含有4个元素(相当于4列), 例如, a[0]所代表的一维数组所包含的4 个元素为a[0][0], a[0][1], a[0][2], a[0][3]。如图5.所示: ┏━━━━┓┏━┳━┳━┳━┓ a─→┃a[0] ┃─→┃0 ┃1 ┃2 ┃3 ┃ ┣━━━━┫┣━╋━╋━╋━┫ ┃a[1] ┃─→┃4 ┃5 ┃6 ┃7 ┃ ┣━━━━┫┣━╋━╋━╋━┫ ┃a[2] ┃─→┃8 ┃9 ┃10┃11┃ ┗━━━━┛┗━┻━┻━┻━┛ 图5. 但从二维数组的角度来看, a代表二维数组的首地址, 当然也可看成是二维数组第0行的首地址。a+1就代表第1行的首地址, a+2就代表第2行的首地址。如果此二维数组的首地址为1000, 由于第0行有4个整型元素, 所以a+1为1008, a+2 也就为1016。如图6.所示 a[3][4] a ┏━┳━┳━┳━┓ (1000)─→┃0 ┃1 ┃2 ┃3 ┃ a+1 ┣━╋━╋━╋━┫ (1008)─→┃4 ┃5 ┃6 ┃7 ┃ a+2 ┣━╋━╋━╋━┫ (1016)─→┃8 ┃9 ┃10┃11┃ ┗━┻━┻━┻━┛ 图6. 既然我们把a[0], a[1], a[2]看成是一维数组名, 可以认为它们分别代表它们所对应的数组的首地址, 也就是讲, a[0]代表第0 行中第0 列元素的地址, 即&a[0][0], a[1]是第1行中第0列元素的地址, 即&a[1][0], 根据地址运算规则, a[0]+1即代表第0行第1列元素的地址, 即&a[0][1], 一般而言, a[i]+j即代表第i行第j列元素的地址, 即&a[i][j]。 另外, 在二维数组中, 我们还可用指针的形式来表示各元素的地址。如前所述, a[0]与*(a+0)等价, a[1]与*(a+1)等价, 因此a[i]+j就与*(a+i)+j等价, 它表示数组元素a[i][j]的地址。 因此, 二维数组元素a[i][j]可表示成*(a[i]+j)或*(*(a+i)+j), 它们都与a[i][j]等价, 或者还可写成(*(a+i))[j]。 另外, 要补充说明一下, 如果你编写一个程序输出打印a和*a, 你可发现它们的值是相同的, 这是为什么呢? 我们可这样来理解: 首先, 为了说明问题, 我们把二维数组人为地看成由三个数组元素a[0], a[1], a[2]组成, 将a[0], a[1], a[2]看成是数组名它们又分别是由4个元素组成的一维数组。因此, a表示数组第0行的地址, 而*a即为a[0], 它是数组名, 当然还是地址, 它就是数组第0 行第0 列元素的地址。

实现图的邻接矩阵和邻接表存储

实现图的邻接矩阵和邻接表存储 1.需求分析 对于下图所示的有向图G,编写一个程序完成如下功能: 1.建立G的邻接矩阵并输出之 2.由G的邻接矩阵产生邻接表并输出之 3.再由2的邻接表产生对应的邻接矩阵并输出之 2.系统设计 1.图的抽象数据类型定义: ADT Graph{ 数据对象V:V是具有相同特性的数据元素的集合,称为顶点集 数据关系R: R={VR} VR={|v,w∈V且P(v,w),表示从v到w的弧, 谓词P(v,w)定义了弧的意义或信息} 基本操作P: CreatGraph(&G,V,VR) 初始条件:V是图的顶点集,VR是图中弧的集合 操作结果:按V和VR的定义构造图G DestroyGraph(&G) 初始条件:图G存在 操作结果:销毁图G InsertVex(&G,v) 初始条件:图G存在,v和图中顶点有相同特征 操作结果:在图G中增添新顶点v …… InsertArc(&G,v,w) 初始条件:图G存在,v和w是G中两个顶点 操作结果:在G中增添弧,若G是无向的则还增添对称弧 …… DFSTraverse(G,Visit()) 初始条件:图G存在,Visit是顶点的应用函数 操作结果:对图进行深度优先遍历,在遍历过程中对每个顶点调用函数Visit一次且仅一次。

一旦Visit()失败,则操作失败 BFSTraverse(G,Visit()) 初始条件:图G存在,Visit是顶点的应用函数 操作结果:对图进行广度优先遍历,在遍历过程中对每个顶点调用函数Visit一次且仅一次。一旦Visit()失败,则操作失败 }ADT Graph 2.主程序的流程: 调用CreateMG函数创建邻接矩阵M; 调用PrintMatrix函数输出邻接矩阵M 调用CreateMGtoDN函数,由邻接矩阵M创建邻接表G 调用PrintDN函数输出邻接表G 调用CreateDNtoMG函数,由邻接表M创建邻接矩阵N 调用PrintMatrix函数输出邻接矩阵N 3.函数关系调用图: 3.调试分析 (1)在MGraph的定义中有枚举类型 typedef enum{DG,DN,UDG,UDN}GraphKind;//{有向图,有向网,无向图,无向网} 赋值语句G.kind(int)=M.kind(GraphKind);是正确的,而反过来M.kind=G.kind则是错误的,要加上那个强制转换M.kind=GraphKind(G.kind);枚举类型enum{DG,DN,UDG,UDN} 会自动赋值DG=0;DN=1,UDG=2,UDN=3;可以自动从GraphKind类型转换到int型,但不会自动从int型转换到GraphKind类型

矩阵的各种运算详解.

一、矩阵的线性运算 定义1 设有两个矩阵和,矩阵与的和记作, 规定为 注:只有两个矩阵是同型矩阵时,才能进行矩阵的加法运算. 两个同型矩阵的和,即为两个矩阵对应位置元素相加得到的矩阵. 设矩阵记 , 称为矩阵的负矩阵, 显然有 . 由此规定矩阵的减法为 . 定义2 数与矩阵A的乘积记作或, 规定为 数与矩阵的乘积运算称为数乘运算. 矩阵的加法与矩阵的数乘两种运算统称为矩阵的线性运算. 它满足下列运算规律:设都是同型矩阵,是常数,则 (1) (2) ; (3) (4) (5) (6) (7) (8) 注:在数学中,把满足上述八条规律的运算称为线性运算. 二、矩阵的相乘 定义3设 矩阵与矩阵的乘积记作, 规定为

其中,( 记号常读作左乘或右乘. 注: 只有当左边矩阵的列数等于右边矩阵的行数时, 两个矩阵才能进行乘法运算. 若,则矩阵的元素即为矩阵的第行元素与矩阵的第列对应元素乘积的和. 即 . 矩阵的乘法满足下列运算规律(假定运算都是可行的): (1) (2) (3) (4) 注: 矩阵的乘法一般不满足交换律, 即 例如, 设则 而 于是且 从上例还可看出: 两个非零矩阵相乘, 可能是零矩阵, 故不能从必然推出 或 此外, 矩阵乘法一般也不满足消去律,即不能从必然推出例如, 设 则 但 定义4如果两矩阵相乘, 有 则称矩阵A与矩阵B可交换.简称A与B可换. 注:对于单位矩阵, 容易证明 或简写成 可见单位矩阵在矩阵的乘法中的作用类似于数1. 更进一步我们有 命题1设是一个n阶矩阵,则是一个数量矩阵的充分必要条件是与任何n阶矩阵可换。

命题2设均为n阶矩阵,则下列命题等价: (1) (2) (3) (4) 三、线性方程组的矩阵表示 设有线性方程组 若记 则利用矩阵的乘法, 线性方程组(1)可表示为矩阵形式: (2) 其中矩阵称为线性方程组(1)的系数矩阵. 方程(2)又称为矩阵方程. 如果是方程组(1)的解, 记列矩阵 则 , 这时也称是矩阵方程(2)的解; 反之, 如果列矩阵是矩阵方程(2)的解, 即有矩阵等式 成立, 则即也是线性方程组(1)的解. 这样, 对线性方程组(1)的讨论便等价于对矩阵方程(2)的讨论. 特别地, 齐次线性方程组可以表示为 将线性方程组写成矩阵方程的形式,不仅书写方便,而且可以把线性方程组的理论与矩阵理论联系起来,这给线性方程组的讨论带来很大的便利. 四、矩阵的转置 定义6把矩阵的行换成同序数的列得到的新矩阵, 称为的转置矩阵, 记作(或 ). 即若 则

图采用邻接矩阵存储结构

图采用邻接矩阵存储结构 #define TRUE 1 #define FALSE 0 #define MAXV 20 typedef int V ertexType; //用顶点编号表示顶点 typedef struct { // 图的定义 int edges[MAXV][MAXV] ; // 边数组 int n, e; //顶点数,弧数 V ertexType vexs[MAXV]; // 顶点信息 } MGraph; 1、创建具有n个顶点e条边的无向图 void CreateUDG(MGraph &G,int n,int e) { int i,j,u,v; G.n=n;G.e=e; /* printf("请输入%d个顶点的编号:\n",n); for(i=0;i

void CreateDG(MGraph &G,int n,int e) { int i,j,u,v; G.n=n;G.e=e; /* printf("请输入%d个顶点的编号:\n",n); for(i=0;i

计算方法_矩阵LU分解法

clear all; %A=LU矩阵三角分解法 n=input('输入方矩阵的维数: '); for i=1:n for j=1:n A(i,j)=input('依次输入矩阵元素:'); end end %输入一个n阶方形矩阵 for j=1:n L(j,j)=1; %Doolittle分解,L对角元素全为1 end for j=1:n U(1,j)=A(1,j); end %U的第一行 for i=2:n L(i,1)=A(i,1)/U(1,1); end %L的第一列 for k=2:n for j=k:n sum1=0; for m=1:k-1 sum1=sum1+L(k,m)*U(m,j); end %求和 U(k,j)=A(k,j)-sum1; end for i=k+1:n sum2=0; for m=1:k-1 sum2=sum2+L(i,m)*U(m,k); end %求和 L(i,k)=(A(i,k)-sum2)/U(k,k); end end L %输出下三角矩阵L U %输出上三角矩阵U

运行结果:(示例) 输入方矩阵的维数: 4 依次输入矩阵元素: 1 依次输入矩阵元素: 1 依次输入矩阵元素: 2 依次输入矩阵元素: 3 依次输入矩阵元素:0 依次输入矩阵元素: 2 依次输入矩阵元素: 1 依次输入矩阵元素: 2 依次输入矩阵元素: 1 依次输入矩阵元素:-1 依次输入矩阵元素: 2 依次输入矩阵元素: 2 依次输入矩阵元素: 2 依次输入矩阵元素: 2 依次输入矩阵元素: 5 依次输入矩阵元素:9 A=LU分解后则可以求解Ax=b线性方程组,相关计算参考计算方法,这里不再详细介绍。

矩阵的运算及其运算规则

矩阵基本运算及应用 201700060牛晨晖 在数学中,矩阵是一个按照长方阵列排列的或集合。矩阵是高等代中的常见工具,也常见于统计分析等应用数学学科中。在物理学中,矩阵于电路学、、光学和中都有应用;中,制作也需要用到矩阵。矩阵的运算是领域的重要问题。将为简单矩阵的组合可以在理论和实际应用上简化矩阵的运算。在电力系统方面,矩阵知识已有广泛深入的应用,本文将在介绍矩阵基本运算和运算规则的基础上,简要介绍其在电力系统新能源领域建模方面的应用情况,并展望随机矩阵理论等相关知识与人工智能电力系统的紧密结合。 1矩阵的运算及其运算规则 1.1矩阵的加法与减法 1.1.1运算规则 设矩阵,, 则

简言之,两个矩阵相加减,即它们相同位置的元素相加减! 注意:只有对于两个行数、列数分别相等的矩阵(即同型矩阵),加减法运算才有意义,即加减运算是可行的. 1.1.2运算性质 满足交换律和结合律 交换律; 结合律. 1.2矩阵与数的乘法 1.2.1运算规则 数乘矩阵A,就是将数乘矩阵A中的每一个元素,记为或. 特别地,称称为的负矩阵. 1.2.2运算性质 满足结合律和分配律

结合律:(λμ)A=λ(μA);(λ+μ)A =λA+μA. 分配律:λ(A+B)=λA+λB. 1.2.3典型举例 已知两个矩阵 满足矩阵方程,求未知矩阵. 解由已知条件知 1.3矩阵与矩阵的乘法 1.3.1运算规则 设,,则A与B的乘积是这样一个矩阵: (1) 行数与(左矩阵)A相同,列数与(右矩阵)B相同,即 .

(2) C的第行第列的元素由A的第行元素与B的第列元素对应相乘,再取乘积之和. 1.3.2典型例题 设矩阵 计算 解是的矩阵.设它为 可得结论1:只有在下列情况下,两个矩阵的乘法才有意义,或说乘法运算是可行的:左矩阵的列数=右矩阵的行数;结论2在矩阵的乘法中,必须注意相乘的顺序.即使在与均有意义时,也未必有=成立.可见矩阵乘法不满足交换律;结论3方阵A和它同阶的单位阵作乘积,结果仍为A,即. 1.3.3运算性质(假设运算都是可行的)

关于二维数组和指向指针的指针

以前一直有种误解: 二维数组的是数组的数组,所以数组的首地址是指向第一个元素指针,而这个元素又是一个数组,所以把数组首地址理解为指向指针的指针。 如int a[3][2];,以前一直认为a是一个指向int指针的指针,即是一个int**。最近发现这是错的。 如果int **p=a; 编译就会报错。如果强制转换int **p=(int **)a,则使用p[i][j]访问数组元素时出错。 首先,因为a的定义为int a[3][2];则a的类型是int* [3][2]数组类型,或者int* [][2],即指向大小为2的数组的指针,类型与int **不同,所以int **p=a;出错。 其次,考虑p[i][j]访问a的数组元素时出错的问题。当我们使用指向二维数组的指针的下标运算来访问数组元素时,如a[i][j],它等同于*(a+i*2+j);即必须要知道第二维的大小才能访问。考虑我使用p[i][j]的后果:p是int**,所以p[i]为*(p+i),而这个结果被视作一个指针,在这里记做pp=*(p+i),所以p[i][j]等同于pp[j]。最终的结果为*(pp+j),并将这个结果解释为一个int值。 int a[3][2]; int val=0; for(int i=0;i<3;++i) { for(int j=0;j<2;++j) { a[i][j]=val++; } } /*使用a[i][j]的方式显然可以正常访问该二维数组*/ /*下面使用指针直接访问,当然是不是int**了……*/ int *p=&a[0][0];/*注意,此处使用int *p=a;或者int *p=a[0];是不对的,p的类型是int型指针,*a或者a[0]是int (*)[2]类型,编译会报错的,* *尽管&a[0][0]、a、a[0]的数值相同……*/ for(int i=0;i<6;++i) { p[i];/*这样可以遍历所有元素*/ }

矩阵的定义及其运算规则

矩阵的定义及其运算规则 1、矩阵的定义 一般而言,所谓矩阵就是由一组数的全体,在括号()内排列成m行n 列(横的称行,纵的称列)的一个数表,并称它为m×n阵。 矩阵通常是用大写字母 A 、B …来表示。例如一个m 行n 列的矩阵可以简记为: ,或 。即: (2-3) 我们称(2-3)式中的为矩阵A的元素,a的第一个注脚字母,表示矩阵的行数,第二个注脚字母j(j=1,2,…,n)表示矩阵的列数。 当m=n时,则称为n阶方阵,并用表示。当矩阵(a ij)的元素仅有一行或一列时,则称它为行矩阵或列矩阵。设两个矩阵,有相同的行数和相同的列数,而且它们的对应元素一一相等,即,则称该两矩阵相等,记为A=B。 2、三角形矩阵 由i=j的元素组成的对角线为主对角线,构成这个主对角线的元素称为主对角线元素。 如果在方阵中主对角线一侧的元素全为零,而另外一侧的元素不为零或不全为零,则该矩阵叫做三角形矩阵。例如,以下矩阵都是三角形矩阵: ,,,。 3、单位矩阵与零矩阵 在方阵中,如果只有的元素不等于零,而其他元素全为零,如: 则称为对角矩阵,可记为。如果在对角矩阵中所有的彼此

都相等且均为1,如:,则称为单位矩阵。单位矩阵常用E来表示,即: 当矩阵中所有的元素都等于零时,叫做零矩阵,并用符号“0”来表示。 4、矩阵的加法 矩阵A=(a ij)m×n和B=(b ij)m×n相加时,必须要有相同的行数和列数。如以C=(c ij)表示矩阵A及B的和,则有: m ×n 式中:。即矩阵C的元素等于矩阵A和B的对应元素之和。 由上述定义可知,矩阵的加法具有下列性质(设A、B、C都是m×n矩阵): (1)交换律:A+B=B+A (2)结合律:(A+B)+C=A+(B+C) 5、数与矩阵的乘法 我们定义用k右乘矩阵A或左乘矩阵A,其积均等于矩阵中的所有元素都乘上k之后所得的矩阵。如: 由上述定义可知,数与矩阵相乘具有下列性质:设A、B都是m×n矩阵,k、h为任意常数,则: (1)k(A+B)=kA+kB (2)(k+h)A=kA+hA (3)k(hA)=khA

矩阵

特殊矩阵的压缩存储 对称矩阵中的元素关于主对角线对称,因此,让每一对对称元素a ij和a ji(i≠j)分配一个存储空间,则n2个元素压缩存储到n(n+1)/2个存储空间,能节约近一半的存储空间。 不失一般性,假设按“行优先顺序”存储下三角形(包括对角线)中的元素。 设用一维数组(向量)sa[0…n(n+1)/2]存储n阶对称矩阵,如图5-4所示。为了便于访问,必须找出矩阵A中的元素的下标值(i,j)和向量sa[k]的下标值k之间的对应关系。 若i≧j:a i j在下三角形中,直接保存在sa中。a i j之前的i-1行共有元素个数:1+2+…+(i-1)=i?(i-1)/2 而在第i行上,a i j之前恰有j-1个元素,因此,元素a i j保存在向量sa中时的下标值k之间的对应关系是: k=i?(i-1)/2+j-1 i≧j 若i

以主对角线划分,三角矩阵有上三角和下三角两种。 上三角矩阵的下三角(不包括主对角线)中的元素均为常数c(一般为0)。下三角矩阵正好相反,它的主对角线上方均为常数,如图5-5所示。 三角矩阵中的重复元素c可共享一个存储空间,其余的元素正好有n(n+1)/2个,因此,三角矩阵可压缩存储到向量sa[0…n(n+1)/2]中,其中c存放在向量的第1个分量中。 上三角矩阵元素a i j保存在向量sa中时的下标值k与(i,j)之间的对应关系是:下三角矩阵元素a i j保存在向量sa中时的下标值k与(i,j)之间的对应关系是: 3 对角矩阵 矩阵中,除了主对角线和主对角线上或下方若干条对角线上的元素之外,其余元素皆为零。即所有的非零元素集中在以主对角线为了中心的带状区域中,如图5-6所示。 如上图三对角矩阵,非零元素仅出现在主对角(a i i,1≦i≦n)上、主对角线上的那条对角线(a i i+1,1≦i≦n-1) 、主对角线下的那条对角线上(a i+1 i,1≦i≦n-1)。显然,当| i-j |>1时,元素a ij=0。

图的矩阵表示及习题-答案汇总

177 图的矩阵表示 图是用三重组定义的,可以用图形表示。此外,还可以用矩阵表示。使用矩阵表示图,有利于用代数的方法研究图的性质,也有利于使用计算机对图进行处理。矩阵是研究图的重要工具之一。本节主要讨论无向图和有向图的邻接矩阵、有向图的可达性矩阵、无向图的连通矩阵、无向图和有向图的完全关联矩阵。 定义9.4.1 设 G =是一个简单图,V =?v 1,v 2,…,v n ? A (G )=(ij a ) n ×n 其中: 1j i v v v v a j i j i ij =???=无边或到有边到 i ,j =1,…,n 称A (G )为G 的邻接矩阵。简记为A 。 例如图9.22的邻接矩阵为: ?????? ? ? ?=011110101101 1010)(G A 又如图9.23(a)的邻接矩阵为: ?????? ? ? ?=0001101111000010 )(G A 由定义和以上两个例子容易看出邻接矩阵具有以下性质: ①邻接矩阵的元素全是0或1。这样的矩阵叫布尔矩阵。邻接矩阵是布尔矩阵。 ②无向图的邻接矩阵是对称阵,有向图的邻接矩阵不一定是对称阵。

178 ③邻接矩阵与结点在图中标定次序有关。例如图9.23(a)的邻接矩阵是A (G ),若将图9.23(a)中的接点v 1和v 2的标定次序调换,得到图9.23(b),图9.23(b)的邻接矩阵是A ′(G )。 ?????? ? ? ?='001010110001 1100)(G A 考察A (G )和A ′(G )发现,先将A (G )的第一行与第二行对调,再将第一列与第二列对调可 得到A ′(G )。称A ′(G )与A (G )是置换等价的。 一般地说,把n 阶方阵A 的某些行对调,再把相应的列做同样的对调,得到一个新的n 阶方阵A ′,则称A ′与A 是置换等价的。可以证明置换等价是n 阶布尔方阵集合上的等价关系。 虽然,对于同一个图,由于结点的标定次序不同,而得到不同的邻接矩阵,但是这些邻接矩阵是置换等价的。今后略去结点标定次序的任意性,取任意一个邻接矩阵表示该图。 ④对有向图来说,邻接矩阵A (G )的第i 行1的个数是v i 的出度, 第j 列1的个数是v j 的入度。 ⑤零图的邻接矩阵的元素全为零,叫做零矩阵。反过来,如果一个图的邻接矩阵是零矩阵,则此图一定是零图。 设G =为有向图,V =?v 1,v 2,…,v n ?,邻接矩阵为A =(a ij )n ×n 若a ij =1,由邻接矩阵的定义知,v i 到v j 有一条边,即v i 到v j 有一条长度为1的路;若a ij =0,则v i 到v j 无边,即v i 到v j 无长度为1的路。故a ij 表示从v i 到v j 长度为1的路的条数。 设A 2=AA ,A 2=(2 ij a )n ×n ,按照矩阵乘法的定义, nj in j i j i ij a a a a a a a +++= 22112 若a ik a kj =1,则a ik =1且a kj =1,v i 到v k 有边且v k 到v j 有边,从而v i 到v j 通过v k 有一条长 度为2的路;若 kj ik a a =0,则a ik =0或a kj =0,v i 到v k 无边或v k 到v j 无边,因而v i 到v j 通过 v k 无长度为2的路,k =1,…,n 。故2 ij a 表示从v i 到v j 长度为2的路的条数。 设A 3=AA 2,A 3=(3 ij a ) n ×n ,按照矩阵乘法的定义, 22222113nj in j i j i ij a a a a a a a +++= 若2kj ik a a ≠0,则ik a =1且2kj a ≠0,v i 到v k 有边且v k 到v j 有路,由于2kj a 是v k 到v j 长度为2 的路的条数,因而2kj ik a a 表示v i 到v j 通过v k 长度为3的路的条数;若2kj ik a a =0, ik a =0或2kj a =0, 则v i 到v k 无边或v k 到v j 无长度为2的路,所以v i 到v j 通过v k 无路,k =1,…,n 。故3 ij a 表示从v i 到v j 长度为3的路的条数。 …… 可以证明,这个结论对无向图也成立。因此有下列定理成立。 定理9.4.1 设A (G )是图G 的邻接矩阵,A (G )k =A (G )A (G )k-1,A (G )k 的第i 行,第j 列元素 k ij a 等于从v i 到v j 长度为k 的路的条数。其中k ii a 为v i 到自身长度为k 的回路数。 推论 设G =是n 阶简单有向图,A 是有向图G 的邻接矩阵,B k =A +A 2+…+A k ,

几何光学中的矩阵方法

几何光学中的矩阵方法 几何光学是基于几何学研究光学的基本方法。几何光学,尤其是矩阵方法在研究光学系统成像时有着巨大的优势。本文通过论述矩阵方法在几何光学中的应用,介绍描述傍轴光线成像的光学ABCD矩阵。同时进一步将矩阵方法拓展至非傍轴光线,得到描述任意光线成像的严格ABCD矩阵。 在光学研究中,当光波长远小于研究对象的尺寸时,通常会利用几何光学方法来研究光线的传播。几何光学中光线的传播遵循三个基本定律:1. 光在自由空间中沿直线独立传播;2. 光的折射定律;3. 光的反射定律。虽然几何光学忽略了光的波动性,无法解释干涉、衍射等物理现象,但是其在光学系统成像性质的研究中有着巨大的优势。 光学系统成像的核心是光学系统变换。1840年C. Gauss建立了高斯光学,用来研究理想光学系统傍轴成像(即满足傍轴近似的光线的成像)性质。傍轴近似下,光线与光学系统中心轴的夹角很小,可以使用小角近似关系,。在这种近似下,光学系统变换退化为线性变换,因此可以用矩阵方法来进行描述。矩阵方法最初是由R. A. Sampson引入几何光学,用来处理几何像差等问题错误!未找到引用源。。之后矩阵方法拓展至研究非傍轴成像,为非傍轴成像的研究提供了新的方法。 本文分为两部分,第一部分着重于傍轴近似下的矩阵方法,介绍ABCD矩阵对光学系统变换的描述。第二部分拓展至包括非傍轴光线的任意光线的传播,介绍并推导严格ABCD矩阵。 一傍轴光线成像与矩阵 上述结论基于傍轴近似,研究的是理想光学系统的傍轴成像。然而实际成像系统中,非傍轴光线成像造成的影响往往是不可忽略的。非傍轴光线与傍轴光线往往不是成像于同一点,即非傍轴光线与傍轴光线成像之间存在差异,称之为几何像差。实际成像中,我们需要关注成像质量,即需要去衡量几何像差的大小。这种情况下,傍轴ABCD矩阵是无法解决的。我们需要引入可以描述非傍轴光线的ABCD矩阵,即严格ABCD矩阵。 二任意光线成像与严格ABCD矩阵 对于任意光线的成像,我们希望同样能够用矩阵进行描述,同时能够保持与傍轴ABCD矩阵相似的形式。因此我们尝试去除傍轴近似,来得到严格的变换关系,即严格ABCD矩阵错误!未找到引用源。。 对于共轴光学系统,光线成像依旧可以分成自由空间传播、折射与反射三种情况。首先我们讨论折射情况。从几何学的角度,我们首先作出入射光线与折射光线所在直线。设折射点为,在入射光线所在的直线上作,在折射光线所在直

相关主题
文本预览
相关文档 最新文档