数值线性代数
——上机实习报告
学 号: 20121024211 姓 名: 衡春健
班 级: 计算122
联系电话: 183xxxxxxxx 任课老师: 郭双冰
二零一四年十二月
数值线性代数上机实习报告 第1页
1.第一题
1.1题目
写出QR分解求解最小二乘问题的通用程序,上机求解P99第
(2)与(3)题
1.2 QR分解求解最小二乘问题的原理和算法
(请写出具体步骤)
一. 原理
1. 设A?Rm?n,b?Rm,由于2范数具有正交不变性,则对任意的正交矩阵
Q?Rm?m有Ax?b2?QT?Ax?b?2,这样最小二乘问题
minQTAx?QTb2
就等价于b?Ax2?r?y?2?minr?y?2?minAy?b2. y?Ry?Rnn
2. A?Rm?n(m??n),则A有QR分解A=Q??,其中Q?Rm?m是具有 0???R?
非负对角元的上三角阵
3.将Q分块,A=Q=?Q1
4.计算c1?Q1Tb
5.计算上三角方程组Rx?c1.即可求得最小二乘问题
二.算法
function [Q,R]=qrhouse(A)
m=size(A,1);
n=size(A,2); ?Q1T??c?Q2?,令A=Qb??T?b??1? ?c2??Q2?T
数值线性代数上机实习报告 第2页 R=A;
Q=eye(m);
for i=1:n
if i<m
x=R(i:m,i);
Ht=householder(x);
H=blkdiag(eye(i-1),Ht);
Q=Q*H;
R=H*R;
else
disp('ok!');
end
end
Q*R-A
1.3利用Householder变换的QR分解的原理和算法 (请写出具体步骤)
一. 原理
数值线性代数上机实习报告 第3页
1. 选取A的列向量进行householder变换得到H1,H2
???n?H3?diag?I2,H3?……. Ak?Hk?1...H1A, R?A11,Q?H1...Hn ??
?R?则A?Q?? ?0?
二.算法
function [H,alpha,beta]=householder(x) n=length(x);
z=x(2:n);
sigma=z'*z;
v(2:n)=x(2:n);
v=v';
if sigma==0
beta=0;
else
alpha=sqrt(x(1)^2+sigma);
if x(1)<=0
v(1)=x(1)-alpha;
else
v(1)=-sigma/(x(1)+alpha); a=v(1);
end
beta=2/(v'*v)
数值线性代数上机实习报告 第4页
end
1.4利用MATLAB求解问题的过程及结果
(结果以图或表格形式列出)
A=[1 -1 1;0.5625 -0.75 1;0.25 -0.5 1;0 0 1;0.0625 0.25 1;0.25 0.5 1;0.5625 0.75 1];
b=[1.00;0.8125;0.75;1.00;1.3125;1.75;2.3125]; m=size(A,1);
n=size(A,2);
[Q1,R1]=qrhouse(A);
Q=Q1(1:m,1:n)
R=R1(1:n,1:n)
C=Q'*b
x=R\C
结果:
beta =
2.3019
数值线性代数上机实习报告 第5页
beta =
0.2575
beta =
0.5749
ans =
1.0e-15 *
0.2220
0.0555
0.0139
0 -0.2220 0 -0.1110 -0.0000 0.0555 0.1110 -0.1110 0.2220 0 -0.1110 0.2220 0
数值线性代数上机实习报告 第6页
0 0.4441 0 Q1 =
0.7534 0.3159
0.4238 -0.1075
0.1884 -0.6863
0 0.5221
0.0471 0.2764
0.1884 -0.2533
0.4238 -0.0671 R1 =
-0.3018 -0.2980 -0.2464 0 0.1949 0.4375 0.7280 -0.2281 0.1818 0.4591 0.6159 0.4955 0.2425 -0.1431 0.2109 -0.6114 0.3895 0.4251 -0.4284 -0.1740 0.1883 0.2512 -0.4707 0.2339 -0.4070 0.6669 -0.2167 -0.0576 0.2862 -0.3028 -0.1247 -0.0413 -0.0982 0.7569 -0.4761
数值线性代数上机实习报告 第7页
1.3273 -0.7416 2.0248
0.0000 1.4620 0.5141
0.0000 0.0000 1.6235
-0.0000 0.0000 0.0000
-0.0000
-0.0000
-0.0000
Q =
0.7534
0.4238
0.1884
0.0471
0.1884
0.4238
R = 0.0000 0.0000 -0.0000 0 -0.0000 -0.0000 -0.3018 -0.2281 -0.2980 0.1818 -0.2464 0.4591 0 0.6159 0.1949 0.4955 0.4375 0.2425 0.7280 -0.1431
数值线性代数上机实习报告 第8页
1.3273 -0.7416 2.0248
0.0000 1.4620 0.5141
0.0000 0.0000 1.6235
C =
2.6104
1.9761
1.6235
x =
1.0000
1.0000
1.0000
数值线性代数上机实习报告 第9页
1.5 方法总结及分析
1. QR分解提供了新的求最小二乘问题的算法
2.Householder变换又为QR分解做了基础
3. 要熟练掌握并应用去求解实际问题
4.可以与数值逼近相结合,比较算法的优越性
数值线性代数上机实习报告 第10页
附件程序
1
function [Q,R]=qrhouse(A)
m=size(A,1);
n=size(A,2);
R=A;
Q=eye(m);
for i=1:n
if i<m
x=R(i:m,i);
Ht=householder(x);
H=blkdiag(eye(i-1),Ht); Q=Q*H;
R=H*R;
else
disp('ok!');
end
end
Q*R-A
数值线性代数上机实习报告 第11页
2.
function [H,alpha,beta]=householder(x) n=length(x);
z=x(2:n);
sigma=z'*z;
v(2:n)=x(2:n);
v=v';
if sigma==0
beta=0;
else
alpha=sqrt(x(1)^2+sigma);
if x(1)<=0
v(1)=x(1)-alpha;
else
v(1)=-sigma/(x(1)+alpha);
结果
beta =
数值线性代数上机实习报告 第12页
2.3019
beta =
0.2575
beta =
0.5749
ans =
1.0e-15 *
0.2220
0.0555
0 -0.2220 0 -0.1110 -0.0000 -0.1110 0.2220 0 -0.1110
数值线性代数上机实习报告 第13页
0.0139 0.0555 0.2220 0 0.1110 0 0 0.4441 0 Q1 =
0.7534 0.3159
0.4238 -0.1075
0.1884 -0.6863
0 0.5221
0.0471 0.2764
0.1884 -0.2533
0.4238 -0.0671
-0.3018 -0.2980 -0.2464 0 0.1949 0.4375 0.7280 -0.2281 0.1818 0.4591 0.6159 0.4955 0.2425 -0.1431 0.2109 -0.6114 0.3895 0.4251 -0.4284 -0.1740 0.1883 0.2512 -0.4707 0.2339 -0.4070 0.6669 -0.2167 -0.0576 0.2862 -0.3028 -0.1247 -0.0413 -0.0982 0.7569 -0.4761
数值线性代数上机实习报告 第14页
R1 =
1.3273 -0.7416 2.0248
0.0000 1.4620 0.5141
0.0000
-0.0000
-0.0000
-0.0000
-0.0000
Q =
0.7534
0.4238
0.1884
0.0471
0.1884
0.4238
0.0000 1.6235 0.0000 0.0000 0.0000 0.0000 -0.0000 0 -0.0000 -0.0000 -0.3018 -0.2281 -0.2980 0.1818 -0.2464 0.4591 0 0.6159 0.1949 0.4955 0.4375 0.2425 0.7280 -0.1431
数值线性代数上机实习报告 第15页
R =
1.3273 -0.7416 2.0248
0.0000 1.4620 0.5141
0.0000
C =
2.6104
1.9761
1.6235
x =
1.0000
1.00000.0000 1.6235
数值线性代数上机实习报告 第16页
第二篇:上机实习报告示例
数算实习报告?
姓名:????????????????学号:????????????????完成日期:??????????????题目:编制一个求解迷宫通路的程序?
问题描述:以一个m*n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。??
?
一、需求分析?
1. 以而为数组Maze[m+2][n+2]表示迷宫,其中,Maze[0][j](0?j?n?1)及Maze[i][0]和Maze[i][n+1](0?i?m?1)为添加的一圈障碍。数组中以元素值为0表示通路,1表示障碍,限定迷宫的大小m,n?10。?
2. 用户以文件的形式输入迷宫的数据:文件中第一行的数据为迷宫的行数m和列数n;从第2行至第m+1行(每行n个数)为迷宫值,同一行中的两个数字用空格相隔。?
3. 迷宫的入口位置和出口位置可由用户随时设定。?
4. 若设定的迷宫存在通路,则以长方阵形式将迷宫及其通路输出到标准输出文件上,其中,字符“#”表示障碍,字符“*”表示路径上的位置,字符“@”表示“死胡同”,即曾经途径而不能到达出口的位置,余下的用空格符印出。若设定的迷宫不存在通路,则报告相应的信息。?
5. 本程序只求出一条成功的通路。然而,只需要对迷宫求解的函数作小量修改,便可求得全部路径。?
?
二、概要设计?
1. 设定栈的抽象数据类型定义:?
?
ADT?Stack?{?
?数据对象:D??a?|a??CharSet,i?1,2,…,n,n?0??
?数据关系:R1???a???,a??|a???,a??D,i?2,…,n??
?基本操作:?
InitS?tack(&S)???
?操作结果:构造一个空栈S。???
DestoryStack(&S)???
???初始条件:栈S已存在。?
???操作结果:销毁栈S。?
??ClearStack(&S)?
???初始条件:栈S已存在。?
???操作结果:将S清为空栈。?
??StackLength(&S)?
???初始条件:栈S已存在。?
???操作结果:返回栈S的长度。?
??StackEmpty(&S)?
???初始条件:栈S已存在。?
???操作结果:若S为空栈,则返回TRUE,否则返回FALSE。?
??GetTop(S,?&e)?
???初始条件:栈S已存在。?
???操作结果:若栈S不空,则以e返回栈顶元素。???Push(&S,?e)?
???初始条件:栈S已存在。?
???操作结果:在栈S的栈顶插入新的栈顶元素e。???Pop(&S,?e)?
???初始条件:栈S已存在。?
???操作结果:删除S的栈顶元素,并以e返回其值。???StackTraverse(S,?visit())?
???初始条件:栈S已存在。?
???操作结果:从栈底到栈顶依次对S中的每个元素调用函数visit()。?}?ADT?Stack?
?
2. 设定迷宫的抽象数据类型为:?
?
ADT?maze?{?
?数据对象:D??a?,??a?,???? ?,‘#’,?@?,????,0?i?m?1,0?j?n?1,m,n?10}?
数据关系:R??ROW,COL??
??????????ROW???a???,?,a?,??|a???,?,a?,??D,i?1,…,m?1,j?0,…,n?1????????????COL???a?,???,a?,??|a?,???,a?,??D,i?0,…,m?1,j?1,…,n?1??}??
?
?
?
?
?
?
?基本操作:??InitMaze(&M,?a,?row,?col)?初始条件:二维数组a[row+2][col+2]已存在,其中自第1行至第row+1行、每行中自第1列至第col+1列的元素已有值,并且以值0表示通路,以值1表示障碍。?操作结果:构成迷宫的字符型数组,以空白字符表示通路,以字符‘#’表示障碍,并在迷宫四周加上一圈障碍。???MazePath(&M)????初始条件:迷宫M以被赋值。?操作结果:若迷宫M中存在一条通路,则按如下规定改变迷宫M的状态:以字符“*”表示路径上的位置,字符“@”表示“死胡同”;否则迷宫的状态不变。???PrintMaze(M)????初始条件:迷宫M已存在。????操作结果:以字符形式输出迷宫。?}?ADT?maze???
3. 本程序包含三个模块?
?
a. 主程序模块?
?
?
Void?main(){?
?初始化;?
?Do{?
??接受命令;?
??处理命令;?
?}?while(命令?!=?“退出”);?
}?
b. 栈模块‐‐‐实现栈抽象数据类型?
c. 迷宫模块‐‐‐实现迷宫抽象数据类型?
各模块之间的调用关系如下:?
主程序模块?
迷宫模块
?
栈模块?
4. 求解迷宫中一条通路的伪码算法:?
设定当前位置的初值为入口位置;?
Do{?
??若当前位置可通,?
??则?{?将当前位置插入栈顶;?????????????????????//纳入路径?
????若该位置是出口位置,则结束;????????//求得路径已在栈中?????否则切换当前位置的东邻方块为新的位置;?
?????}?
??否则?{?
???若栈不空且栈顶位置尚有其他方向未被探索,?
????则设定新的当前位置为沿顺时针方向旋转找到的栈顶位置的下一相邻块;?
???若栈不空但栈顶位置的四周均不可通,?
????则?{?删去栈顶位置;??????????//后退一步,从路径中删去该通道块??????若栈不空,则重新测试新的栈顶位置,知道找到一个可通的相邻块或出栈至栈空;?
?????}?
???}?
}?while(栈不空)?
{栈空说明没有路径存在}?
?
三、详细设计
1. 坐标位置类型?
typedef?struct{?
??Int??r,?c;???????
}?PosType;?
?
2. 迷宫类型??//迷宫中r行c列的位置?
typedef?struct{?
??int??m,n;?
char??arr[RANGE][RANGE];????//各位置取值‘?’,‘#’,‘*’?}?MazeType;?
void?InitMaze(MazeType?&maze,?int?a[][],?int?row,?int?col)?
??//按照用户输入的row行和col列的二维数组(元素值为0或1)???//设置迷宫maze的初值,包括加上边缘一圈的值?
bool?MazePath(MazeType?&maze,?PosType?start,?PosType?end)?
??//求解迷宫maze中,从入口start到出口end的一条路径???//若存在,则返回TRUE;否则返回FALSE?
Void?PrintMaze(MazeType?maze)?
??//将迷宫以字符型方阵的形式输出到标准输出文件上?
?
3. 栈类型?
Typedef?struct?{?
??Int?step;??//当前位置在路径上的“序号”?
??PosType??seat;?//当前的坐标位置?
??directiveType??di;?//往下一坐标位置的方向?
}?ElemType;???//栈的元素类型?
Typedef?struct???NodeType?{?
??ElemType??data;?
??NodeType??*next;?
}?NodeType,?*LinkType;???//节点类型,指针类型?
Typedef?struct?{?
??LinkType??top;?
??Int???size;?
}?Stack;?????//栈类型?
?
其中部分操作的算法:?
Status??Push?(Stack?&S,?ElemType?e)?{?
??//若分配空间成功,则在S的栈顶插入新的栈顶元素e,并返回TRUE;???//否则栈不变,并返回FALSE?
??If(MakeNode(p,?e))?{?
???p.next?=?S.top;?
???S.top?=?p;?
???S.size++;?
???Return?TRUE;?
??}?
??else?return?FALSE;?
}?
?
Status??Pop?(Stack?&S,?ElemType?&e)?{?
??…?
??…?
??…?
}?
?
4. 求迷宫路径的伪码算法:?
Status?MazePath(MazeType?maze,?PosType?start,?PosType?endJ)?{?
??//若迷宫maze中存在从入口start到出口end的通道,则求出这条路径,并返???//回TRUE;否则返回FLASE?
??InitStack(S);?
??Curpos?=?start;?
??Curstep?=?1;?
??Found?=?FLASE;?
??do?{?
???if?(?Pass(maze,?curpos))?{?
????//当前位置可以通过,即是未曾走到过的通道块留下足迹?????FootPrint?(maze,?curpos);?
????e?=?(curstep,?curpos,?1);?
????Push?(S,?e);?
????If?(Same(curpos,?end))?found?=?TRUE;???//到达终点?????else?{?
?????curpos?=?NextPos(curpos,?1);??//下一位置是当前位置的东邻??????curstep++;?
????}?
???}?
???else???//当前位置不能通过?
????if?(?!StackEmpty(S))?{?
?????Pos(?S,?e);?
?????while?(?e.di?==?4?&&?!StackEmpty(S))?{?
??????MarkPrint(maze,?e.seat);?
??????Pop(S,?e);?
??????Curstep‐‐;?
?????}?
?????if?(e.di?<?4)?{?
??????e.di++;?
??????Push(S,?e);?????//换下一个方向搜索?
??????Curpos?=?NextPos?(?e.seat,?e.di);?//设定当前位置是该新方向上的相邻块?
?????}?
????}?
??}?while?(!StackEmpty(S)?&&?!found);?
??return?found;?
}?
?
?
5. 主函数和其他函数的伪码算法:?
void?main()?{?
??Initialization();?
??do?{?
???ReadCommand(?cmd);?//读入一个操作命令符?
???Interpret(?cmd?);??//解释执行操作命令符?
??}?while?(?cmd?!=?‘q’?&&?cmd!=?‘Q’);?
}?
?
void?Initialization()?{?
??clrscr();?
??在屏幕上显示操作命令清单:?
??CreatMaze—c??MazePath—m??PrintMaze—p??Quit—q?;?
??在屏幕下方显示操作命令提示框;?
}?
?
void?ReadCommand(char?&cmd)?{?
??…?
??…?
??}??
void?Interpret(?char?cmd)?{?
??//解释执行命令?
??Switch?(cmd)?{?
???Case?‘c’,’C’:?提示用户输入“迷宫文件名filename”,读入数据;???????InitMaze(ma,?filename);?
??????输出建立完毕信息;?
??????break;?
???case?‘m’,’M’:?提示用户输入入口from和出口term的坐标;???????if?(?MazePath(?ma,?from,?term);??
//存在路径
???
?????提示用户查看迷宫;?
??????else?输出不存在路径的信息;?
??????break;?
???case?‘p’,’P’:??PrintMaze(ma);?????//将迷宫打印到终端???}?
}?
?
6. 函数调用关系?
?
?????????????????
???????????????
?
?
四、调试分析
1. 本次作业比较简单,只有一个核心算法,即求迷宫的路径,所以总的调试比较顺利,只在调试MazePath算法时,遇到两个问题:首先是,起初输入的迷宫没有加上‘@’的记号,后发现是因为在MarkPrint函数中的迷宫参数丢失“变参”的原因;其次是,由于退回时没有将curpos减一,致使栈中路径上的序号有错。?
2. 栈的元素中的step域没有多大用处,可以省略。?
3. StackTravers在调试过程中很有用,它可以插入在MazePath算法中多处,以查看解迷宫过程中走的路径是否正确,但对最后的执行版本没什么用。?
InitMaze,?MazePath和PrintMaze的时间复杂度均为O(m×n),4. 本题中三个主要算法:
本题的空间复杂度为O(m×n)(栈所占最大空间)。?
5. 经验体会:借助DEBUG调试器和数据观察窗口,可以更快地找到程序中的错误。??
五、测试结果?
三组测试数据和输出结果分别如下:?
1. 输入文件名为:m1.dat,其中迷宫数据为:?
3???2?
0 0?
0 0?
0 0?
入口位置:1???1?
出口位置:3???2?
求解路径后输出的迷宫:?**
*
*
?
2. 输入文件名:m2.dat,其中迷宫数据:?
3???4?
0???0???0???0?
0???0???1???1?
0???0???0???0?
入口位置:1???1?
出口位置:3???4?
求解路径后输出的迷宫:?**
*
*@#*
?
3. 输入文件名:m3.dat,其中迷宫数据:?
4???9?
0 0??0??0??0??0??1??0??0?
0 1??0??0??0??1??0??0??0?@#*
0??0??1??1???1??0??0??1??1?
0??0??1??1???1??0??1??0??0?
入口位置:1??1?
出口位置:4??9?
输出信息:此迷宫从入口到出口没有路径。?
六、附录?
源文件清单:?
base.H?????????//共用的常量和类型?
stkpas.H???????//栈类型?
maze.H????????//迷宫类型?
testmaze.C??????//主程序?
?
?
?
?
?
作业提交邮箱:
dsaa2011@sina.com
?
?
?
?
?
?
?
?
?
?
?
?
?