北航研究生数值分析编程大作业1Word文件下载.docx
- 文档编号:21251777
- 上传时间:2023-01-28
- 格式:DOCX
- 页数:22
- 大小:165.47KB
北航研究生数值分析编程大作业1Word文件下载.docx
《北航研究生数值分析编程大作业1Word文件下载.docx》由会员分享,可在线阅读,更多相关《北航研究生数值分析编程大作业1Word文件下载.docx(22页珍藏版)》请在冰豆网上搜索。
最后通过反幂法计算出按模最小特征值
其中求解方程组计算向量
时,先利用已经编好的LU分解法进行分解,再编写回代过程得到u。
4、求A的与数
利用原点平移,设定每次的平移量为
,而后利用反幂法求出相应的
值。
5、求A的(谱范数)条件数
由于A为实对称矩阵,故
,
,所以
6、计算消息的激发
在窗体类中定义一个成员变量m_State,初始化窗体时将它设置为0。
当按下“计算”按钮时激发了按钮被按下的消息,程序开始计算,同时将m_State设为1。
此时再次按下“计算”按钮将弹出提示框“您已经计算过了!
”而不再进行计算了。
这样可以保证计算过程只进行一次。
当输入新的矩阵重新进行计算时,就再次初始化窗口,此时m_State又被初始化为0,可以再次进行计算。
三、源代码
在光盘中有全部的源代码,请用MicrosoftVisualStudio2008打开。
同时还有一个课执行文件可以直接执行。
由于有些程序段是MFC直接生成的,这里没有把那部分程序打出。
1、类的设计
类的头文件为:
#pragmaonce//使头文件只被编译一次
/*常量ROW_N表示压缩矩阵行的维数*/
#defineROW_N5
/*常量COL_N表示压缩矩阵列的维数*/
#defineCOL_N501
classArray//存放所求矩阵A的类。
类的成员函数中定义了对类的基本操作。
{
public:
//声明构造函数和析构函数
Array(void);
//默认的构造函数
Array(doublearray);
//重载构造函数,使其能对m_Array数组进行针对其他题目的初始化
~Array(void);
//默认的析构函数
//声明成员变量
//非零元素压缩存储矩阵
doublem_Array[ROW_N][COL_N];
//中间存储矩阵
doublem_Array_Change[ROW_N][COL_N];
//定义矩阵的上半带宽
intm_s;
//定义矩阵的下半带宽
intm_r;
//定义迭代精度
doublem_Accuracy;
//声明成员函数
//用Doolittle分解法求带状线性方程组的行列式的值
voidDoolittle_LU();
//求三个整形数的最大值
intmax_3(inta,intb,intc);
//对一个向量进行初始化
voidVector_Initialize(doublevector[COL_N]);
//将矩阵恢复到原来的数值
voidRestored();
//取向量的范数
doubleGet_Norm_of_Vector(doublevector[COL_N]);
//计算带状矩阵与列向量的乘积
voidArray_Mul_Vector(doublevector[COL_N],doubleu[COL_N]);
//计算行向量与列向量的乘积
doubleRVector_Mul_CVector(doubleRVector[COL_N],doubleCVector[COL_N]);
//幂法
doublePower_Method();
//原点平移函数
voidOriginMove(doublex);
//反幂法
doubleAntiPower_Method();
//求实对称矩阵的条件数
doubleGet_Spectral_norm(doubleeigenvalue[3]);
};
类的实现文件为:
#include"
StdAfx.h"
Array.h"
#include<
math.h>
//因为是C++系统提供的函数,所以这里用了“<
>
”而不是“"
"
”
Array:
:
Array(void)//默认构造函数,针对本问题对压缩数组进行初始化。
inti,j;
//for循环中用到的循环变量
//输入A的非零元素,存储于矩阵m_Array中,空位由c=0补齐
for(i=0;
i<
ROW_N;
i++)
for(j=0;
j<
COL_N;
j++)
{
if(((i==0)&
&
(j>
=2))||((i==4)&
(j<
=COL_N-3)))
//压缩矩阵的第行前面会有个空位,第行后面会有个空位
{
m_Array_Change[i][j]=m_Array[i][j]=-0.064;
}
elseif(((i==1)&
=1))||((i==3)&
=COL_N-2)))
m_Array_Change[i][j]=m_Array[i][j]=0.16;
}
elseif(i==2)//为主对角线上的元素赋值
m_Array_Change[i][j]=m_Array[i][j]=
(1.64-0.024*(j+1))*sin(0.2*(j+1))-0.64*exp(0.1/(j+1));
else
m_Array_Change[i][j]=m_Array[i][j]=0;
//压缩矩阵中的空位可以用零元素来填充,以免发生内存引用方面的错误
}
m_s=2;
//此矩阵的上半带宽为
m_r=2;
//此矩阵的下半带宽为
m_Accuracy=1.0e-12;
//计算精度
}
~Array(void)
Array(doublearray)//若问题改变可以扩充此重载的构造函数进行初始化
voidArray:
Doolittle_LU()//按照教材P26的算法进行计算
inti,j,k;
//循环中用到的循环变量
//做分解A=LU:
for(k=1;
k<
=COL_N;
k++)//对k=1,2,...,n执行
{
for(j=k;
=min(k+2,COL_N);
j++)//求两个数的最小值可调用已有的函数min
for(i=max_3(1,k-m_r,j-m_s);
=k-1;
i++)//此处的i为教材中的t
m_Array[k-j+m_s][j-1]-=m_Array[k-i+m_s][i-1]*m_Array[i-j+m_s][j-1];
for(j=k+1;
=min(k+2,COL_N))&
(k!
=COL_N);
j++)//此处的j为教材中的i
doublesum=0;
sum+=m_Array[j-i+m_s][i-1]*m_Array[i-k+m_s][k-1];
m_Array[j-k+m_s][k-1]=
(m_Array[j-k+m_s][k-1]-sum)/m_Array[m_s][k-1];
}
Restored()//将矩阵恢复到原来的数值
m_Array[i][j]=m_Array_Change[i][j];
intArray:
max_3(inta,intb,intc)//求三个数中的最大值
return(a>
max(b,c))?
a:
max(b,c);
doubleArray:
Get_Norm_of_Vector(doublevector[COL_N])//求向量的范数
doublesum=0.0;
for(inti=0;
sum+=vector[i]*vector[i];
}
returnsqrt(sum);
Array_Mul_Vector(doublevector[COL_N],doubleu[COL_N])
//计算带状矩阵与列向量的乘积
for(inti=1;
doublesum=0.0;
for(intj=max(1,i-m_r);
=min(COL_N,i+m_r);
sum=sum+m_Array[i-j+m_s][j-1]*vector[j-1];
//乘的过程中得把A的坐标转化为C的坐标
u[i-1]=sum;
RVector_Mul_CVector(doubleRVector[COL_N],doubleCVector[COL_N])
sum+=RVector[i]*CVector[i];
returnsum;
Vector_Initialize(doublevector[COL_N])
vector[i]=1;
Power_Method()//幂法
//u为特征向量,uni_u为u的单位化向量
doubleu[COL_N],uni_u[COL_N];
doubleEigenvalue=0.0;
//用于存储特征值
doubleEigenvalue_Temp=0.1;
//用于比较特征值的变化
doubleNorm_Value;
//向量范数的值
Vector_Initialize(u);
//对初始向量进行初始化
for(inti=0;
fabs(Eigenvalue_Temp-Eigenvalue)/fabs(Eigenvalue)>
=m_Accuracy;
Eigenvalue_Temp=Eigenvalue;
Norm_Value=Get_Norm_of_Vector(u);
//计算向量的范数
for(intj=0;
j++)//对向量进行单位化
uni_u[j]=u[j]/Norm_Value;
Array_Mul_Vector(uni_u,u);
//计算矩阵A与y[k-1]的乘积,得到u[k]存入u中
Eigenvalue=RVector_Mul_CVector(uni_u,u);
//计算特征值
returnEigenvalue;
OriginMove(doublex)//原点平移
for(inti=0;
m_Array[m_s][i]=m_Array[m_s][i]-x;
AntiPower_Method()//反幂法
//u为特征向量,uni_u为u的单位化向量,uni_u_copy为解方程组时用到的向量
doubleu[COL_N],uni_u[COL_N],uni_u_copy[COL_N];
doubleEigenvalue=0.1;
doubleEigenvalue_Temp=0.0;
fabs(1/Eigenvalue_Temp-1/Eigenvalue)
/fabs(1/Eigenvalue)>
Restored();
uni_u_copy[j]=uni_u[j];
Doolittle_LU();
//以下几行是P26页Doolittle分解法的回代过程求解向量u[k]
for(inti=2;
sum=0.0;
for(intt=max(i-m_r,1);
t<
=i-1;
t++)
sum+=m_Array[i-t+m_s][t-1]*uni_u_copy[t-1];
uni_u_copy[i-1]-=sum;
u[COL_N-1]=uni_u_copy[COL_N-1]/m_Array[m_s][COL_N-1];
for(inti=COL_N-1;
i>
=1;
i--)
for(intt=i+1;
=min(i+m_s,COL_N);
sum+=m_Array[i-t+m_s][t-1]*u[t-1];
u[i-1]=(uni_u_copy[i-1]-sum)/m_Array[m_s][i-1];
return1/Eigenvalue;
Get_Spectral_norm(doubleeigenvalue[3])//求对称矩阵的条件数
returnfabs(max(fabs(eigenvalue[0]),fabs(eigenvalue[1]))/eigenvalue[2]);
2、对话框类及算法的驱动函数
因为VC++程序是消息驱动的,真正的主函数是Windows调用的,它的功能是不断地从Windows系统的消息堆栈中读取消息并用消息驱动相应的消息响应函数。
所以在算法这一部分没有主函数,而消息响应函数起到了主函数的作用。
每当我们激发一个消息(比如按下一个按钮)激发的消息将使消息响应函数开始运行,从而进行计算。
窗体类的头文件:
//Try_4Dlg.h:
头文件
#pragmaonce
afxcmn.h"
//CTry_4Dlg对话框
classCTry_4Dlg:
publicCDialog
//构造
CTry_4Dlg(CWnd*pParent=NULL);
//标准构造函数
//对话框数据
enum{IDD=IDD_TRY_4_DIALOG};
protected:
virtualvoidDoDataExchange(CDataExchange*pDX);
//DDX/DDV支持
//实现
protected:
HICONm_hIcon;
//生成的消息映射函数
virtualBOOLOnInitDialog();
afx_msgvoidOnSysCommand(UINTnID,LPARAMlParam);
afx_msgvoidOnPaint();
afx_msgHCURSOROnQueryDragIcon();
DECLARE_MESSAGE_MAP()
CListCtrlm_ListCtrl_Result;
//显示结果的控件的对象
CListCtrlm_List_Array;
//显示矩阵的控件的对象
Arraym_arr;
//定义Array类的一个对象
CStringm_Change;
//字符转换控件的对象
afx_msgvoidOnBnClickedButtonCul();
//“计算”按钮发出的消息的消息响应函数
CStringm_Show_Det;
//显示特征值的控件的对象
CStringm_Max_Eigenvalue;
//显示最大特征值的控件的对象
CStringm_Show_Min;
//显示最小特征值的控件的对象
CStringm_Show_Min_Norm;
//显示按模最小特征值的对象
CStringm_Show_Cond;
//显示条件数的控件的对象
intm_State;
//判断用户是否计算过的记录变量
窗体类的实现文件:
//Try_4Dlg.cpp:
实现文件
stdafx.h"
Try_4.h"
Try_4Dlg.h"
iostream>
usingnamespacestd;
#ifdef_DEBUG
#definenewDEBUG_NEW
#endif
//用于应用程序“关于”菜单项的CAboutDlg对话框
classCAboutDlg:
CAboutDlg();
enum{IDD=IDD_ABOUTBOX};
CAboutDlg:
CAboutDlg():
CDialog(CAboutDlg:
IDD)
{}
voidCAboutDlg:
DoDataExchange(CDataExchange*pDX)
CDialog:
DoDataExchange(pDX);
BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)
END_MESSAGE_MAP()
CTry_4Dlg:
CTry_4Dlg(CWnd*pParent/*=NULL*/)//窗体的构造函数
:
CDialog(CTry_4Dlg:
IDD,pParent)
m_Change(_T("
))
m_Show_Det(_T("
m_Max_Eigenvalue(_T("
m_Show_Min(_T("
m_Show_Min_Norm(_T("
m_Show_Cond(_T("
m_State(0)
m_hIcon=AfxGetApp()->
LoadIcon(IDR_MAINFRAME);
voidCTry_4Dlg:
DDX_Control(pDX,IDC_LIST_RESULT,m_ListCtrl_Result);
DDX_Control(pDX,IDC_LIST_ARRAY,m_List_Array);
DDX_Text(pDX,IDC_EDIT1,m_Change);
DDX_Text(pDX,IDC_EDIT_DET,m_Show_Det);
DDX_Text(pDX,IDC_EDIT3,m_Max_Eigenvalue);
DDX_Text(pDX,IDC_EDIT2,m_Show_Min);
DDX_Text(pDX,IDC_EDIT4,m_Show_Min_Norm);
DDX_Text(pDX,IDC_EDIT5,m_Show_Cond);
BEGIN_MESSAGE_MAP(CTry_4Dlg,CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON_CUL,&
OnBnClickedButtonCul)
//CTry_4Dlg消息处理程序
BOOLCTry_4Dlg:
OnInitDialog()
OnInitDialog();
//将“关于...”菜单项添加到系统菜单中。
//IDM_ABOUTBOX必须在系统
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 北航 研究生 数值 分析 编程 作业