【数值计算】householder矩阵的QR算法,求特征值

#include 
#include 
#include 
#include 
#include 

#define N 10

using namespace std;

class MT {
public:
    int x, y;
    double mt[N][N];

    MT() {}
    MT(int x, int y) {
        this->x = x;
        this->y = y;
        for (int i = 0; i < this->x; i++)
            for (int j = 0; j < this->y; j++)
                mt[i][j] = 0.0;
    }

    MT transpose() {
        MT c(this->y, this->x);
        for (int i = 0; i < c.x; i++)
            for (int j = 0; j < c.y; j++)
                c.mt[i][j] = this->mt[j][i];
        return c;
    }

    void print() {
        for (int i = 0; i < this->x; i++) {
            for (int j = 0; j < this->y; j++)
                printf("%.4lf    ", this->mt[i][j]);
            puts("");
        }
    }

    void shift(int num) {
        for (int i = this->x; i >= 0; i--)
            for (int j = this->y; j >= 0; j--)
                this->mt[i + num][j + num] = this->mt[i][j];
        for (int i = 0; i < num; i++)
            for (int j = 0; j < this->y + num; j++)
                this->mt[i][j] = 0;
        for (int i = 0; i < this->y + num; i++)
            for (int j = 0; j < num; j++)
                this->mt[i][j] = 0;
        for (int i = 0; i < num; i++) 
            this->mt[i][i] = 1;
        this->x += num;
        this->y += num;
    }
};

MT operator * (MT a, MT b) {
    MT c(a.x, b.y);
    for (int i = 0; i < c.x; i++)
        for (int j = 0; j < c.y; j++) {
            c.mt[i][j] = 0;
            for (int k = 0; k < a.y; k++)
                c.mt[i][j] += a.mt[i][k] * b.mt[k][j];
        }
    return c;
}

MT operator * (double a, MT b) {
    MT c(b.x, b.y);
    for (int i = 0; i < c.x; i++)
        for (int j = 0; j < c.y; j++) {
            c.mt[i][j] = a * b.mt[i][j];
        }
    return c;
}

MT operator + (MT a, MT b) {
    MT c(a.x, a.y);
    for (int i = 0; i < c.x; i++)
        for (int j = 0; j < c.y; j++) {
            c.mt[i][j] += a.mt[i][j] + b.mt[i][j];
        }
    return c;
}

MT x, H[N], I, u, e1, A;
double sita, beta;

int n;

void init() {
    n = 3;
    A.x = 3, A.y = 3;
    A.mt[0][0] = 2;A.mt[0][1] = -2;A.mt[0][2] = 3;
    A.mt[1][0] = 1;A.mt[1][1] = 1;A.mt[1][2] = 1;
    A.mt[2][0] = 1;A.mt[2][1] = 3;A.mt[2][2] = -1;
}

void transform(int num) {
    // initialize
    x.x = n - num + 1, x.y = 1;
    for (int i = num - 1; i < n; i++)
        x.mt[i - num + 1][0] = A.mt[i][num - 1];

    e1.x = x.x, e1.y = 1;
    e1.mt[0][0] = 1;
    for (int i = 1; i < e1.x; i++) {
        e1.mt[i][0] = 0;
    }

    I.x = I.y = x.x;
    for (int i = 0; i < I.x; i++)
        for (int j = 0; j < I.y; j++) {
            if (i == j) I.mt[i][j] = 1;
            else I.mt[i][j] = 0;
        }


    // run householder 
    sita = 0;
    for (int i = 0; i < x.x; i++) 
        sita += x.mt[i][0] * x.mt[i][0];
    sita = sqrt(sita);
    if (x.mt[0][0] < 0) sita = -sita;

    MT e1_t = sita * e1;

    u = x + e1_t;

    beta = sita * (sita + x.mt[0][0]);

    MT u_t = u.transpose();
    u_t = u * u_t;
    u_t = (-1.0 / beta) * u_t;

    H[num] = I + u_t;
    H[num].shift(num - 1);
    printf("H%d:\n", num);
    H[num].print();
    printf("sita: %.4lf\n\n", sita);

    A = H[num] * A;
}

int main() {
    init();
    int cnt = 0;
    while (1) {
        cnt++;
        for (int i = 1; i < n; i++) {
            transform(i);
        }
        MT R = A;

        MT Q = H[n - 1];
        for (int i = n - 2; i >= 1; i--)
            Q = Q * H[i];
        Q = Q.transpose();

        puts("Q:");
        Q.print();
        puts("R:");
        R.print();
        A = R * Q;
        printf("A%d:\n", cnt);
        A.print();
        system("pause");
    }

    return 0;
}

你可能感兴趣的:(NOTE,math,数值计算)