итерационный метод Якоби имеет неправильный ответ в C ++ - PullRequest
0 голосов
/ 22 мая 2018

Я пишу Якоби итерационный метод для решения любой линейной системы уравнений.эта программа работает для некоторых примеров, но не работает для других.например, для

A=     and B=
7  3       5
2  3       4

это будет работать, и ответы верны, но для

A=     and B=
1  2       3
3  4       7

ответы неправильные и огромные числа.Я действительно не знаю, что мне делать, чтобы сделать правильный расчет.Я использовал некоторые другие коды, но все же у меня есть эта проблема с кодами.

#include <iostream>
using namespace std;

int main(){
    double A[10][10], alpha[10][10], B[10], betha[10], x[10][100], sum[10];
    int i, j, n, k, kmax;
    cout << "insert number of equations \n";
    cin >> n;
    cout << "insert LHS of equations (a11,a12,...,ann)\n";
    for (i = 1; i <= n; i++){
        for (j = 1; j <= n; j++){
            cin >> A[i][j];
        }
    }
    cout << "A=\n";
    for (i = 1; i <= n; i++){
        for (j = 1; j <= n; j++){
            cout << A[i][j] << "\t\t";
        }
        cout << "\n\n";
    }
    cout << "alpha=\n";
    for (i = 1; i <= n; i++){
        for (j = 1; j <= n; j++){
            if (i == j){
                alpha[i][j] = 0;
            }
            else{
                alpha[i][j] = -A[i][j] / A[i][i];
            }
        }
    }
    for (i = 1; i <= n; i++){
        for (j = 1; j <= n; j++){
            cout << alpha[i][j] << "\t\t";
        }
        cout << "\n\n";
    }
    cout << "insert RHS of equations";
    for (i = 1; i <= n; i++){
        cin >> B[i];
    }
    cout << "\nbetha=\n";
    for (i = 1; i <= n; i++){
        betha[i] = B[i] / A[i][i];
        cout << betha[i] << endl;
    }
    cout << "Enter the number of repetitions." << endl;
    cin >> kmax;
    k = 0;
    for (i = 1; i <= n; i++){
        sum[i] = 0;
        x[i][k] = betha[i];    //initial values 
    }
    for (k = 0; k <= kmax; k++){
        for (i = 1; i <= n; i++){
            for (j = 1; j <= n; j++){
                sum[i] += alpha[i][j] * x[j][k];
            }
            x[i][k] = betha[i] + sum[i];
            sum[i] = 0; 
        }
    }
    cout << "answers:\n\n";
    for (i = 1; i <= n; i++){
        cout << x[i][kmax] << endl;
    }
    return 0;
}

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

Ваша матрица в порядке строк: [{1, 2} {3, 4}]

Она имеет определитель, равный -2;очевидно, это не единственное число.

Имеет обратное: [{4, -2}, {-3, 1}] / (- 2)

Правильное решение: {1, 1}

Вы можете проверить это, подставив обратно в исходное уравнение и проверив, чтобы убедиться, что у вас есть тождество: [{1, 2} {3, 4}] {1, 1} = {3, 7}

Итерационные методы могут быть чувствительны к начальным условиям.

Правильная точка зрения по диагонали.Возможно, более разумный выбор начального условия, более близкий к правильному ответу, позволит вам сходиться.

Обновление:

Итерация Якоби разбивает матрицу на диагональные элементы D и недиагональные элементы R:

enter image description here

Якоби сойдет, если:

Convergence criteria

С тех порэто не относится к первой строке вашей примерной матрицы, у вас могут быть проблемы.

Вы все равно получите это за один шаг, если вы используете правильный ответ в качестве первоначального предположения.Это говорит о том, что даже Якоби будет работать с разумным выбором.

Если я начну с {1, 1}, я сойду с правильным ответом за одну итерацию.

0 голосов
/ 22 мая 2018

Вы должны снова проверить условие сходимости.Там вы найдете, что обычно метод сходится только для диагонально доминирующих матриц.Первый пример удовлетворяет этому условию, в то время как второй явно его нарушает.

Если сходимость не гарантируется, то, как вы обнаружили, может возникнуть дивергенция.


Более конкретно, итерация Якоби ввторой пример вычисляет

xnew[0] = (3 - 2*x[1])/1;
xnew[1] = (7 - 3*x[0])/4;

За две итерации композиция шагов дает

xtwo[0] = (3 - 2*xnew[1])/1 = -0.5 + 1.5*x[0];
xtwo[1] = (7 - 3*xnew[0])/4 = -0.5 + 1.5*x[1];

, что явно расширяет исходные ошибки с коэффициентом 1.5.

...