计算方法实验3:反幂法求按模最小特征值及特征向量

任务

在这里插入图片描述
在这里插入图片描述

算法

1.LU-Doolittle分解

A = L U \mathbf{A}=\mathbf{L}\mathbf{U} A=LU
其中 L \mathbf{L} L为单位下三角阵, U \mathbf{U} U为上三角阵.
A x = b \mathbf{A}\mathbf{x}=\mathbf{b} Ax=b可化为 L U x = L y = b \mathbf{L}\mathbf{U}\mathbf{x}=\mathbf{L}\mathbf{y}=\mathbf{b} LUx=Ly=b
只需解方程组
L y = b \mathbf{L}\mathbf{y}=\mathbf{b} Ly=b
U x = y \mathbf{U}\mathbf{x}=\mathbf{y} Ux=y

2. 规范化反幂法

{ Y ( k ) = X ( k ) / ∥ X ( k ) ∥ ∞ , A X ( k + 1 ) = Y ( k ) , k = 0 , 1 , … \begin{cases} \mathbf{Y^{(k)}} =\mathbf{X^{(k)}}/\|\mathbf{X^{(k)}}\|_{\infty}, \\ \mathbf{A}\mathbf{X^{(k+1)}}=\mathbf{Y^{(k)}}, \end{cases} k=0,1,… {Y(k)=X(k)/∥X(k),AX(k+1)=Y(k),k=0,1,
∥ X ( k + 1 ) ∥ − ∥ X ( k ) ∥ ∞ ≤ 1 0 − 5 \|\mathbf{X^{(k+1)}}\|-\|\mathbf{X^{(k)}}\|_{\infty}\leq10^{-5} X(k+1)X(k)105时停止迭代,则 A \mathbf{A} A的按模最小特征值 λ = 1 / ∥ X ( k + 1 ) ∥ \lambda=1/\|\mathbf{X^{(k+1)}}\| λ=1/∥X(k+1), λ \lambda λ对应的特征向量为 Y ( k ) \mathbf{Y^{(k)}} Y(k).

代码

#include<bits/stdc++.h>
using namespace std;

//计算向量的无穷范数,即找到向量中绝对值最大的元素
long double Norm(const vector<long double>& x1)
{
    long double norm = 0;
    int n = x1.size();
    for(int i = 0; i < n; i++)
        if(fabsl(x1[i]) > norm)
            norm = fabsl(x1[i]);
    return norm;
}

//Doolittle分解解线性方程组
vector<long double> Doolittle(vector<vector<long double>>& A, const vector<long double>& b)
{
    int n = A.size();
    vector<long double> x(n, 0);
    vector<long double> temp(n, 0);
    vector<vector<long double>> matrix1(n, vector<long double>(n+1, 0)); 
    vector<vector<long double>> matrix2(n, vector<long double>(n+1, 0)); 
    vector<vector<long double>> Lmatrix(n, vector<long double>(n, 0));
    vector<vector<long double>> Umatrix(n, vector<long double>(n, 0));
    for(int i = 0; i < n; i++)
    {
        Lmatrix[i][i] = 1;
        Umatrix[0][i] = A[0][i];
        Lmatrix[i][0] = A[i][0] / Umatrix[0][0];
    }
    for(int i = 1; i < n; i++)
    {
        for(int j = i; j < n; j++)
        {
            Umatrix[i][j] = A[i][j];
            for(int k = 0; k < i; k++)
                Umatrix[i][j] -= Lmatrix[i][k] * Umatrix[k][j];
        }
        for(int j = i + 1; j < n; j++)
        {
            Lmatrix[j][i] = A[j][i];
            for(int k = 0; k < i; k++)
                Lmatrix[j][i] -= Lmatrix[j][k] * Umatrix[k][i];
            Lmatrix[j][i] /= Umatrix[i][i];
        }
    }

    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++)
            matrix1[i][j] = Lmatrix[i][j];
    for(int i = 0; i < n; i++)
        matrix1[i][n] = b[i];
    for(int row = 0; row < n; row++)
    {
        for(int col = 0; col < row; col++)
        {
            matrix1[row][n] -= matrix1[col][n] * matrix1[row][col] / matrix1[col][col];
            matrix1[row][col] = 0;
        }
        matrix1[row][n] /= matrix1[row][row];
        matrix1[row][row] = 1;
    }
    for(int i = 0; i < n; i++)
        temp[i] = matrix1[i][n];
    
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++)
            matrix2[i][j] = Umatrix[i][j];
    for(int i = 0; i < n; i++)
        matrix2[i][n] = temp[i];
    for(int row = n - 1; row >= 0; row--)
    {
        for(int col = row + 1; col < n; col++)
        {
            matrix2[row][n] -= matrix2[col][n] * matrix2[row][col] / matrix2[col][col];
            matrix2[row][col] = 0;
        }
        matrix2[row][n] /= matrix2[row][row];
        matrix2[row][row] = 1;
    }
    for(int i = 0; i < n; i++)
        x[i] = matrix2[i][n];
    return x;
}

//迭代求解特征值和特征向量
void Iteration(vector<vector<long double>>& A, vector<long double> x)
{
    int n = A.size();
    vector<long double> xtemp = x;
    cout << "X(0):";
    for (int i = 0; i < n; i++)
        cout << x[i] << " ";
    cout << endl;
    long double norm1 = Norm(xtemp);
    cout << norm1 << endl;
    vector<long double> x1 = Doolittle(A, xtemp);
    cout << "X(1):";
    for (int i = 0; i < n; i++)
        cout << x1[i] << " ";
    cout << endl;
    long double norm2 = Norm(x1);
    cout << norm2 << endl;
    int k = 1;
    vector<long double> y(n, 0);
    
    while (fabsl(norm1 - norm2) > 1e-5)
    {
        for(int i = 0; i < n; i++)
            y[i] = x1[i] / norm2;
        cout << "Y(" << k << "):";
        for (int i = 0; i < n; i++)
            cout << y[i] << " ";
        cout << endl;
        xtemp = Doolittle(A, y);
        cout << "X(" << k + 1 << "):";
        for (int i = 0; i < n; i++)
            cout << xtemp[i] << " ";
        cout << endl;
        norm1 = norm2;
        norm2 = Norm(xtemp);
        cout << norm2 << endl;
        k++;
        x1 = xtemp;
    }
    cout << "lambda=" << 1 / Norm(x1) << endl;
    cout << "特征向量为:";
    for(int i = 0; i < n; i++)
        cout << y[i] << " ";
    cout << endl << "迭代次数为:" << k << endl << endl;
}

int main()
{
    int n = 5;
    vector<vector<long double>> A1(n, vector<long double>(n));
    for(int i = 0; i < 5; i++)
        for(int j = 0; j < 5; j++)
            A1[i][j] = 1.0 / (9 - i - j);
    vector<long double> b1 = {1, 1, 1, 1, 1};
    Iteration(A1, b1);

    n = 4;
    vector<vector<long double>> A2(n, vector<long double>(n));
    A2[0][0] = 4; A2[0][1] = -1; A2[0][2] = 1; A2[0][3] = 3;
    A2[1][0] = 16; A2[1][1] = -2; A2[1][2] = -2; A2[1][3] = 5;
    A2[2][0] = 16; A2[2][1] = -3; A2[2][2] = -1; A2[2][3] = 7;
    A2[3][0] = 6; A2[3][1] = -4; A2[3][2] = 2; A2[3][3] = 9;
    vector<long double> b2 = {1, 1, 1, 1};
    Iteration(A2, b2);
}

结果

在这里插入图片描述
在这里插入图片描述

  • 15
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里澄江

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值