logo资料库

北航数值分析 大作业一.docx

第1页 / 共10页
第2页 / 共10页
第3页 / 共10页
第4页 / 共10页
第5页 / 共10页
第6页 / 共10页
第7页 / 共10页
第8页 / 共10页
资料共10页,剩余部分请下载后查看
1. 算法设计方案:
1. 求,
2. 求A的与数最接近的特征值
3. 求A的(谱范数)条件数和行列式
2. 源代码
北 京 航 空 航 天 大 学 数值分析大作业一 学院名称: 计算机学院 专业方向: 计算机技术 学 号: 学生姓名: 教 日 师: 朱立永 期: 2018 年 11 月 12 日
1. 算法设计方案: 1. 求 1 , 501 和 s的值。 1 , 501 是矩阵的最大特征值及最小特征值。可使用幂法求出 按模最大特征值,如结果为正,即为 501 ,结果为负,则为 1 。按平 移量进行原点平移可以求得另一特征值。 s 为按模最小特征值, |  s |  |min 1 501 i   i | 。可使用反幂法求得。 2. 求 A 的与数  1  k  k   501 1 40 最接近的特征值 ( kki ,...,2,1 )39 。 题目可看成求以 k 为偏移量后,按模最小的特征值。即以 k 为 偏移量做位移,使用反幂法求出按模最小特征值后,加上 k ,即为所 求。 3. 求 A 的(谱范数)条件数 cond (A 2) 和行列式det A。 det A可由 LU 分解得到。因 LU 均为三角阵,则其主对角线乘积即 为 A 的行列式。求得det A不等于 0,所以矩阵 A 为非奇异对称矩阵, 可知, cond )( | A  max 2  min | (1-1) 其中 max 为按模最大特征值, min 为按模最小特征值。
2. 源代码 #include #include #include "iostream" #include "algorithm" #include "iomanip" using namespace std; #define N 501 #define M 5 #define R 2 #define S 2 #define K 39 #define e 1.0e-12 //列 //行 //下带宽 //上带宽 //误差限 double A[M][N]; double u[N]; double t1[N], t[N]; double maximum, value1, value2, value_1, value_N, value_s, value_abs_max; //初始矩阵 //初始向量 int max_sign, max_position; void init_A();//初始化A void init_u();//初始化迭代向量 void get_max();//获得绝对值最大的数值的模 void get_t();//单位化迭代向量 void get_u();//获得新迭代向量 void getValue();//获得迭代后特征值 void checkValue();//幂法第二迭代格迭代 void getMaxValue();//获取绝对值最大的特征值λ_501 void getMinValue();//获取特征值λ_1 void resolve_LU();//LU分解 void backSubstitution();//方程组回代过程 double getDetValue();//求矩阵行列式值 double getNorm();//获得迭代向量模 void get_t(double);//迭代向量单位化 void getMinABSValue();//获得绝对值最小的特征值 void inversePower();//反幂法求绝对值最小的特征值 double getCond();//求矩阵条件数 void Value_translation_min();//偏移条件下反幂法求特征值
int main() { //初始化矩阵A //获取绝对值最大的特征值λ_501 //获取特征值λ_1 init_A(); getMaxValue(); getMinValue(); cout << setprecision(12) << scientific << "λ1 = " << value_1 << endl; cout << setprecision(12) << scientific << "λ501 = " << value_N << endl; double value_det = getDetValue(); inversePower(); cout << setprecision(12) << scientific << "λs = " << value_s << endl; double cond = getCond(); Value_translation_min();//偏移条件下反幂法求特征值 cout << setprecision(12) << scientific << "cond_A = " << cond << endl; cout << setprecision(12) << scientific << "det = " << value_det << endl; return 0; //求矩阵行列式值 //反幂法求绝对值最小的特征值 //求矩阵条件数 void init_A() { //初始化矩阵A for (int i = 0; i < 5; ++i) { if (i == 0 || i == 4) for (int j = 2; j < N; ++j) A[i][j] = -0.064; else if (i == 1 || i == 3) for (int j = 1; j < N; ++j) A[i][j] = 0.16; else for (int j = 0; j < N; ++j) exp(0.1 / (j + 1)); } } } } A[i][j] = (1.64 - 0.024 * (j + 1)) * sin(0.2 * (j + 1)) - 0.64 * void init_u() { //初始化迭代向量 for (int i = 0; i < N; i++) u[i] = 1.0; void get_max() { //获得绝对值最大的数值的模 max_position = 0; maximum = fabs(u[0]); for (int i = 1; i < N; i++) { if (maximum < fabs(u[i])) {
max_position = i; maximum = fabs(u[i]); } } if (u[max_position] < 0) max_sign = -1; else max_sign = 1; void get_t() { //单位化迭代向量 for (int i = 0; i < N; i++) t1[i] = u[i] / maximum; void get_u() { //获得新迭代向量 } } } } int i; u[0] = A[2][0] * t1[0] + A[1][1] * t1[1] + A[0][2] * t1[2]; u[1] = A[3][0] * t1[0] + A[2][1] * t1[1] + A[1][2] * t1[2] + A[0][3] * t1[3]; u[N - 2] = A[4][N - 4] * t1[N - 4] + A[3][N - 3] * t1[N - 3] + A[2][N - 2] * t1[N - u[N - 1] = A[4][N - 3] * t1[N - 3] + A[3][N - 2] * t1[N - 2] + A[2][N - 1] * t1[N - u[i] = A[4][i - 2] * t1[i - 2] + A[3][i - 1] * t1[i - 1] + A[2][i] * t1[i] + A[1][i 2] + A[1][N - 1] * t1[N - 1]; 1]; for (i = 2; i < N - 2; i++) + 1] * t1[i + 1] + A[0][i + 2] * t1[i + 2]; void getValue() { //获得迭代后特征值 value2 = value1; value1 = max_sign * u[max_position]; //幂法第二迭代格迭代 void checkValue() { init_u(); get_max(); get_t(); get_u(); getValue(); while (true) {
get_max(); get_t(); get_u(); getValue(); if (fabs((value2 - value1) / value1) < e) break; } } //获取绝对值最大的特征值λ_501 void getMaxValue() { checkValue(); value_abs_max = value1; } void getMinValue() { //获取特征值λ_1 double value_temp = value1; for (int i = 0; i < N; i++) { A[2][i] -= value_temp; } checkValue(); value1 += value_temp; if (value1 < value_temp) { value_1 = value1; value_N = value_temp; } else { value_N = value1; value_1 = value_temp; } } void resolve_LU() { double temp; for (int k = 1; k <= N; k++) { for (int j = k; j <= min(k + S, N); j++) { temp = 0; for (int t = max(max(1, k - R), j - S); t <= k - 1; t++) temp += A[k - t + S][t - 1] * A[t - j + S][j - 1]; A[k - j + S][j - 1] = A[k - j + S][j - 1] - temp; } for (int i = k + 1; i <= min(k + R, N); i++) { temp = 0;
for (int t = max(max(1, i - R), k - S); t <= k - 1; t++) temp += A[i - t + S][t - 1] * A[t - k + S][k - 1]; A[i - k + S][k - 1] = (A[i - k + S][k - 1] - temp) / A[S][k - 1]; } } } void backSubstitution()//方程组回代过程 { double temp = 0; for (int i = 2; i < N + 1; i++) { for (int t = max(1, i - R); t < i; t++) t1[i - 1] -= A[i - t + S][t - 1] * t1[t - 1]; } u[N - 1] = t1[N - 1] / A[S][N - 1]; for (int i = N - 1; i > 0; i--) { temp = 0; for (int t = i + 1; t <= min(i + S, N); t++) temp += A[i - t + S][t - 1] * u[t - 1]; u[i - 1] = (t1[i - 1] - temp) / A[S][i - 1]; double getDetValue() { //求矩阵行列式值 double det = 1; init_A(); resolve_LU(); for (int i = 0; i < N; i++) det = det * A[2][i]; return det; } } } } double getNorm() { //获得迭代向量模 double normal = 0; for (int i = 0; i < N; i++) normal += u[i] * u[i]; normal = sqrt(normal); return normal; void get_t(double normal) { //迭代向量单位化
for (int i = 0; i < N; i++) { t1[i] = u[i] / normal; t[i] = t1[i]; } } void getMinABSValue() { value2 = value1; value1 = 0; for (int i = 0; i < N; i++) value1 += t[i] * u[i]; value1 = 1 / value1; //获得绝对值最小的特征值 } } } //反幂法求绝对值最小的特征值 void inversePower() { double norm = 0; int count = 0; value1 = 0, value2 = 0; init_u(); norm = getNorm(); get_t(norm); backSubstitution(); getMinABSValue(); while (count < 10000) { count++; norm = getNorm(); get_t(norm); backSubstitution(); getMinABSValue(); if (fabs((value2 - value1) / value1) < e) break; } value_s = value1; double getCond() { //求矩阵条件数 return fabs(value_abs_max / value_s);
分享到:
收藏