2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки


Правила форума


В этом разделе нельзя создавать новые темы.



Начать новую тему Ответить на тему
 
 Сложность метода отражений для решения СЛАУ
Сообщение24.04.2012, 19:44 


20/04/12
7
Добрый день.
Возникли некоторые сложности с реализацией или пониманием метода отражений для решений СЛАУ.
Реализую так.
1. Осуществляю QR-разложение.
На k-этапе этапе:
1) строю матрицу Хасухолдера.
H_k = E - 2w_kw_k^T,
где
w_k = \mu_k(a_{1k} - \beta_k; a_{2k}; ...; a_{nk})^T, \beta_k = sgn(-a_{1k}) \sqrt{\sum^n_{i=1} a_{ik}^2}, \mu_k = \frac{1}{2 \beta_k^2 - 2 \beta_k a_{kk}}
2) далее оперирую k-подматрицей (в которой вычеркнуты k строк и столбцов), получаю подматрицу A_k = H_kA, в которой обнулен 1 столбец подматрицы (без первого элемента).
2. Полученную на первом шаге треугольную матрицу использую для обратного хода.

Код функции:
код: [ скачать ] [ спрятать ]
Используется синтаксис C
double * solveSluUsingReflection(Slu slu) {

    size_t i,j,m,k;
    size_t n = slu.n;
    double ** a = malloc((n)*sizeof(double*));
    for (i = 0; i < n; i++) {
        a[i] = malloc((n+1)*sizeof(double));
        memcpy(a[i], slu.a[i], n*sizeof(double));
        a[i][n] = slu.b[i];
    }

    double ** h = getUnitMatrix(n);
    double ** e = getUnitMatrix(n);
    double * w = malloc(n * sizeof(double));
    double ** aa = allocMatrix(n,n);
    for (i = 0; i < n-1; i++) {
        double s = 0;
        for (k = i; k < n; k++) {
            s += a[k][i]*a[k][i];
        }
        if (fabs(s) < EPS) continue;
        double beta = (a[i][i] < 0) ? sqrt(s) : - sqrt(s);
        double mu = 1 / sqrt(2 * beta * beta - 2 * beta * a[i][i]);
        w[i] = mu * (a[i][i] - beta);
        for (j = i+1; j < n; j++) {
            w[j] = mu*a[j][i];
        }
        for (j = i; j < n; j++) {
            for (k = i; k < n; k++) {
                h[j][k] = e[j][k] - 2 * w[j] * w[k]; //ww[j][k];
            }
        }
        for (m = i; m < n; m++) {
            for (j = i; j < n+1; j++) {
                aa[m][j] = 0;
                for (k = i; k < n; k++) {
                    aa[m][j] += h[m][k] * a[k][j];
                }
            }
        }
        for (j = i; j < n; j++) {
            for (k = i; k < n+1; k++) {
                a[j][k] = aa[j][k];
            }
        }
    }

    // обратный ход
    double s;
    double * c = (double *)malloc(n * sizeof(double));
    for (i = n-1; i < n; i--) {
        s = a[i][n]; // b[i]
        for (j = i+1; j < n; j++) {
            s -= a[i][j] * c[j];
        }
        c[i] = s / a[i][i];
    }

    printf("\n");
    return c;

}
 


И вроде бы все отлично, но: получается сложность O(n^4); для СЛУ с 500 ур-ями, этот метод работает около 5 минут, в отличие от Гаусса, который работает около 1 секунды.
В книге Бахвалова и Амосова речь идет о O(n^3), и вообще, о том, что этот метод один из самых быстрых. В чем моя ошибка? Заранее благодарен.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ 1 сообщение ] 

Модераторы: Модераторы Математики, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group