Не трать впустую (с)
Задача такая была: читать дальше
Спасибо  TigerCat, написал код - но у меня: во-первых, этот код не работает (почему-то), во-вторых - условие остановки цикла чуть другое. На основе этого кода и другой инфы попробовала написать более простой вариант, на корректность пока не проверяла, ибо выдает одну ошибку на этапе компиляции. Собственно, далее приведен код программы и выдаваемая ошибка - может кто-нибудь укажет ошибку и что с ней делать.
Код файла .срр
Код файла .h
C:\Documents and Settings\...\...\...\Makefile.win [Build Error] [Безымянный1.o] Error 1 - ошибка.
ЗЫ: за дибильные ошибки, просьба, тапки в меня не кидать - программист из меня убийственный.

@темы: Работа

Комментарии
02.09.2008 в 23:41

WAAAAAAAAAGH!!!!!!1111ONEONE
у меня валяется какая-то реализация этого зейделя, но там на классах и даже вроде с каким-то наследованием (уже не помню захер оно там могло понадобиться). Тот, кому эту работу я делал, успешно её сдал.
03.09.2008 в 11:28

Не трать впустую (с)
Vj_o-oy, как все сложно.. Вы не могли бы скинуть мне? Дальше уже сама попробую разобраться, мне ведь только методы нужны...
03.09.2008 в 12:54

Есть прога для решения систем линейных уравнений по методу Зейделя, сейчас попробую кинуть, сделана наспех, тем не менее она работает
03.09.2008 в 13:03

#include
#include

using namespace std;

int main()
{
int numberOfEq = 0;
int maxIter;
while(numberOfEq < 2)
{
cout << "Введите количество уравнений ";
cin >> numberOfEq;
if(numberOfEq < 2)
{
cout << "Количество уравнений должно быть больше 2-х" << endl;
}
}

double **mainMatrix;//---Главная матрица
double *rightMatrix;//---Массив чисел в правой части системы уравнений
double *res;//---Массив решений
double mNorma;//---m-норма
double lNorma;//---l-норма
double kNorma;//---k-норма
double value;//---Переменные, необходимая для обмена строк матрицы местами
double stringValue;//---Вычисленная строка матрицы на каждой итерации
double difference;//---Разность между векторами соседних итераций
double length;//---Длина вектора предыдущей итерации
double eps;
int s = 0;//---Индикатор перестановки
bool hasRes = true;
mainMatrix = new double *[numberOfEq];
rightMatrix = new double [numberOfEq];
res = new double [numberOfEq];
for(int i = 0; i < numberOfEq; i++)
{
mainMatrix[i] = new double [numberOfEq];
}

for(int i = 0; i < numberOfEq; i++)
{
cout << "Введите " << numberOfEq + 1 << " коэффициента(ов) " << i + 1 << "-го уравнения ";
for(int j = 0; j < numberOfEq; j++)
{
cin >> mainMatrix[i][j];
}
cin >> rightMatrix[i];
}

cout << "Введите " << numberOfEq << " начальных приближений ";
for(int i = 0; i < numberOfEq; i++)
{
cin >> res[i];
}

cout << "Введите максимальное количество итераций ";
cin >> maxIter;

//---Преобразуем главную матрицу так, чтобы можно было воспользоваться методом итераций
for(int i = 0; i < numberOfEq; i++)
{
//---В общем случае матрица может содержать нули, преобразуем ее так, чтобы диагональные элементы не содержали нулей
if(mainMatrix[i][i] == 0)
{
s = 0;
for(int i1 = 0; i1 < numberOfEq; i1++)
{
if(i1 == i)
{
continue;
}
if(mainMatrix[i1][i] != 0 && mainMatrix[i][i1] != 0)//---Перестановка возможна
{
//---Меняем строки i и i1 местами
s = 1;
for(int j = 0; j < numberOfEq; j++)
{
value = mainMatrix[i][j];
mainMatrix[i][j] = mainMatrix[i1][j];
mainMatrix[i1][j] = value;
}
value = rightMatrix[i];
rightMatrix[i] = rightMatrix[i1];
rightMatrix[i1] = value;
break;
}
}
if(s == 0)
{
cout << "Система уравнений не решается по методу Зейделя" << endl;
hasRes = false;
break;
}
}
}

if(!hasRes)
{
return 0;
}

//---Формируем рабочие массивы
for(int i = 0; i < numberOfEq; i++)
{
for(int j = 0; j < numberOfEq; j++)
{
if(i == j)
{
continue;
}
else
if(mainMatrix[i][j] != 0)
{
mainMatrix[i][j] = - mainMatrix[i][j] / mainMatrix[i][i];//---Приводим матрицу к нормальному виду
}
}
rightMatrix[i] = rightMatrix[i] / mainMatrix[i][i];
mainMatrix[i][i] = 0;
}

//---Находим m-норму
hasRes = false;
for(int i = 0; i < numberOfEq; i++)
{
mNorma = 0.;
for(int j = 0; j < numberOfEq; j++)
{
mNorma = mNorma + fabs(mainMatrix[i][j]);
}
if(mNorma < 1.)
{
hasRes = true;
break;
}
}

if(!hasRes)
{
//---Находим l-норму
for(int j = 0; j < numberOfEq; j++)
{
lNorma = 0.;
for(int i = 0; i < numberOfEq; i++)
{
lNorma = lNorma + fabs(mainMatrix[i][j]);
}
if(lNorma < 1.)
{
hasRes = true;
break;
}
}
}

if(!hasRes)
{
//---Находим k-норму
kNorma = 0.;
for(int i = 0; i < numberOfEq; i++)
{
for(int j = 0; j < numberOfEq; j++)
{
kNorma = mainMatrix[i][j] * mainMatrix[i][j];
}
}
kNorma = sqrt(kNorma);
if(kNorma < 1.)
{
hasRes = true;
}
}

if(!hasRes)
{
cout << "Итерационный процесс будет расходящимся, расчет прерван" << endl << "Выход из программы" << endl;
return 0;
}

//---Начинаем итерационный процесс
for(int iter = 0; iter < maxIter; iter++)
{
cout << endl << "Результаты " << iter + 1 << "-й итерации:" << endl;
difference = 0.;
length = 0.;
for(int i = 0; i < numberOfEq; i++)
{
stringValue = rightMatrix[i];
for(int j = 0; j < numberOfEq; j++)
{
stringValue = stringValue + mainMatrix[i][j] * res[j];
}
difference = difference + (res[i] - stringValue) * (res[i] - stringValue);
length = length + res[i] * res[i];
res[i] = stringValue;
//---Выводим результаты вычислений
cout << res[i] << endl;
}
//---Вычисляем погрешность (используется Евклидова норма вектора)
eps = sqrt(difference) / sqrt(length);
cout << "Погрешность вычислений: " << eps << endl;
cout << endl;
}

delete mainMatrix;
delete rightMatrix;
delete res;
return 0;
}
03.09.2008 в 13:05

Сейчас еще кину результат выполнения этой проги (тестировалась и запускалась в Linux)
03.09.2008 в 13:37

В предыдущем коде были некоторые неточности

#include
#include

using namespace std;

int main()
{
int numberOfEq = 0;
int maxIter;
while(numberOfEq < 2)
{
cout << "Введите количество уравнений ";
cin >> numberOfEq;
if(numberOfEq < 2)
{
cout << "Количество уравнений должно быть больше 2-х" << endl;
}
}

double **mainMatrix;//---Главная матрица
double *rightMatrix;//---Массив чисел в правой части системы уравнений
double *res;//---Массив решений
double mNormaMin, mNormaMax;//---m-норма
double lNormaMin, lNormaMax;//---l-норма
double kNorma;//---k-норма
double value;//---Переменные, необходимая для обмена строк матрицы местами
double stringValue;//---Вычисленная строка матрицы на каждой итерации
double difference;//---Разность между векторами соседних итераций
double length;//---Длина вектора предыдущей итерации
double eps;
int s = 0;//---Индикатор перестановки
bool hasRes = true;
mainMatrix = new double *[numberOfEq];
rightMatrix = new double [numberOfEq];
res = new double [numberOfEq];
for(int i = 0; i < numberOfEq; i++)
{
mainMatrix[i] = new double [numberOfEq];
}

for(int i = 0; i < numberOfEq; i++)
{
cout << "Введите " << numberOfEq + 1 << " коэффициента(ов) " << i + 1 << "-го уравнения ";
for(int j = 0; j < numberOfEq; j++)
{
cin >> mainMatrix[i][j];
}
cin >> rightMatrix[i];
}

cout << "Введите " << numberOfEq << " начальных приближений ";
for(int i = 0; i < numberOfEq; i++)
{
cin >> res[i];
}

cout << "Введите максимальное количество итераций ";
cin >> maxIter;

//---Преобразуем главную матрицу так, чтобы можно было воспользоваться методом итераций
for(int i = 0; i < numberOfEq; i++)
{
//---В общем случае матрица может содержать нули, преобразуем ее так, чтобы диагональные элементы не содержали нулей
if(mainMatrix[i][i] == 0)
{
s = 0;
for(int i1 = 0; i1 < numberOfEq; i1++)
{
if(i1 == i)
{
continue;
}
if(mainMatrix[i1][i] != 0 && mainMatrix[i][i1] != 0)//---Перестановка возможна
{
//---Меняем строки i и i1 местами
s = 1;
for(int j = 0; j < numberOfEq; j++)
{
value = mainMatrix[i][j];
mainMatrix[i][j] = mainMatrix[i1][j];
mainMatrix[i1][j] = value;
}
value = rightMatrix[i];
rightMatrix[i] = rightMatrix[i1];
rightMatrix[i1] = value;
break;
}
}
if(s == 0)
{
cout << "Система уравнений не решается по методу Зейделя" << endl;
hasRes = false;
break;
}
}
}

if(!hasRes)
{
return 0;
}

//---Формируем рабочие массивы
for(int i = 0; i < numberOfEq; i++)
{
for(int j = 0; j < numberOfEq; j++)
{
if(i == j)
{
continue;
}
else
if(mainMatrix[i][j] != 0)
{
mainMatrix[i][j] = - mainMatrix[i][j] / mainMatrix[i][i];//---Приводим матрицу к нормальному виду
}
}
rightMatrix[i] = rightMatrix[i] / mainMatrix[i][i];
mainMatrix[i][i] = 0;
}

//---Находим m-норму
hasRes = false;
mNormaMax = 0.;
mNormaMin = 0.;
for(int i = 0; i < numberOfEq; i++)
{
for(int j = 0; j < numberOfEq; j++)
{
mNormaMin = mNormaMin + fabs(mainMatrix[i][j]);
}
if(mNormaMin >= mNormaMax)
{
mNormaMax = mNormaMin;
mNormaMin = 0.;
}
}
if(mNormaMax < 1.)
{
hasRes = true;
}

if(!hasRes)
{
lNormaMax = 0.;
lNormaMin = 0.;
//---Находим l-норму
for(int j = 0; j < numberOfEq; j++)
{
for(int i = 0; i < numberOfEq; i++)
{
lNormaMin = lNormaMin + fabs(mainMatrix[i][j]);
}
if(lNormaMin >= lNormaMax)
{
lNormaMax = lNormaMin;
lNormaMin = 0.;
}
}
if(lNormaMax < 1.)
{
hasRes = true;
}
}

if(!hasRes)
{
//---Находим k-норму
kNorma = 0.;
for(int i = 0; i < numberOfEq; i++)
{
for(int j = 0; j < numberOfEq; j++)
{
kNorma = kNorma + mainMatrix[i][j] * mainMatrix[i][j];
}
}
kNorma = sqrt(kNorma);
if(kNorma < 1.)
{
hasRes = true;
}
}

if(!hasRes)
{
cout << "Итерационный процесс будет расходящимся, расчет прерван" << endl << "Выход из программы" << endl;
return 0;
}

//---Начинаем итерационный процесс
for(int iter = 0; iter < maxIter; iter++)
{
cout << endl << "Результаты " << iter + 1 << "-й итерации:" << endl;
difference = 0.;
length = 0.;
for(int i = 0; i < numberOfEq; i++)
{
stringValue = rightMatrix[i];
for(int j = 0; j < numberOfEq; j++)
{
stringValue = stringValue + mainMatrix[i][j] * res[j];
}
difference = difference + (res[i] - stringValue) * (res[i] - stringValue);
length = length + res[i] * res[i];
res[i] = stringValue;
//---Выводим результаты вычислений
cout << res[i] << endl;
}
//---Вычисляем погрешность (используется Евклидова норма вектора)
eps = sqrt(difference) / sqrt(length);
cout << "Погрешность вычислений: " << eps << endl;
cout << endl;
}

delete mainMatrix;
delete rightMatrix;
delete res;
return 0;
}
03.09.2008 в 13:37

Результат для указанного выше примера

03.09.2008 в 13:58

Результат для другого примера

03.09.2008 в 14:49

РЕШЕНИЕ ПО МЕТОДУ ЯКОБИ:

#include
#include

using namespace std;

int main()
{
int numberOfEq = 0;
int maxIter;
while(numberOfEq < 2)
{
cout << "Введите количество уравнений ";
cin >> numberOfEq;
if(numberOfEq < 2)
{
cout << "Количество уравнений должно быть больше 2-х" << endl;
}
}

double **mainMatrix;//---Главная матрица
double *rightMatrix;//---Массив чисел в правой части системы уравнений
double *res;//---Массив решений и
double *res1;//---второй массив решений
double mNormaMin, mNormaMax;//---m-норма
double lNormaMin, lNormaMax;//---l-норма
double kNorma;//---k-норма
double value;//---Переменные, необходимая для обмена строк матрицы местами
double stringValue;//---Вычисленная строка матрицы на каждой итерации
double difference;//---Разность между векторами соседних итераций
double length;//---Длина вектора предыдущей итерации
double eps;
int s = 0;//---Индикатор перестановки
bool hasRes = true;
int numberOfIter = 0;//---Номер итерации (если 0, то используется массив res1, если 1 - то res)
mainMatrix = new double *[numberOfEq];
rightMatrix = new double [numberOfEq];
res = new double [numberOfEq];
res1 = new double [numberOfEq];
for(int i = 0; i < numberOfEq; i++)
{
mainMatrix[i] = new double [numberOfEq];
}

for(int i = 0; i < numberOfEq; i++)
{
cout << "Введите " << numberOfEq + 1 << " коэффициента(ов) " << i + 1 << "-го уравнения ";
for(int j = 0; j < numberOfEq; j++)
{
cin >> mainMatrix[i][j];
}
cin >> rightMatrix[i];
}

/*cout << "Введите " << numberOfEq << " начальных приближений ";
for(int i = 0; i < numberOfEq; i++)
{
cin >> res[i];
}*/

cout << "Введите максимальное количество итераций ";
cin >> maxIter;

//---Преобразуем главную матрицу так, чтобы можно было воспользоваться методом итераций
for(int i = 0; i < numberOfEq; i++)
{
//---В общем случае матрица может содержать нули, преобразуем ее так, чтобы диагональные элементы не содержали нулей
if(mainMatrix[i][i] == 0)
{
s = 0;
for(int i1 = 0; i1 < numberOfEq; i1++)
{
if(i1 == i)
{
continue;
}
if(mainMatrix[i1][i] != 0 && mainMatrix[i][i1] != 0)//---Перестановка возможна
{
//---Меняем строки i и i1 местами
s = 1;
for(int j = 0; j < numberOfEq; j++)
{
value = mainMatrix[i][j];
mainMatrix[i][j] = mainMatrix[i1][j];
mainMatrix[i1][j] = value;
}
value = rightMatrix[i];
rightMatrix[i] = rightMatrix[i1];
rightMatrix[i1] = value;
break;
}
}
if(s == 0)
{
cout << "Система уравнений не решается по методу Якоби" << endl;
hasRes = false;
break;
}
}
}

if(!hasRes)
{
return 0;
}

//---Формируем рабочие массивы
for(int i = 0; i < numberOfEq; i++)
{
for(int j = 0; j < numberOfEq; j++)
{
if(i == j)
{
continue;
}
else
if(mainMatrix[i][j] != 0)
{
mainMatrix[i][j] = - mainMatrix[i][j] / mainMatrix[i][i];//---Приводим матрицу к нормальному виду
}
}
rightMatrix[i] = rightMatrix[i] / mainMatrix[i][i];
res[i] = rightMatrix[i];//---Формируем массив начальных приближений
mainMatrix[i][i] = 0;
}

//---Находим m-норму
hasRes = false;
mNormaMax = 0.;
mNormaMin = 0.;
for(int i = 0; i < numberOfEq; i++)
{
for(int j = 0; j < numberOfEq; j++)
{
mNormaMin = mNormaMin + fabs(mainMatrix[i][j]);
}
if(mNormaMin >= mNormaMax)
{
mNormaMax = mNormaMin;
mNormaMin = 0.;
}
}
if(mNormaMax < 1.)
{
hasRes = true;
}

if(!hasRes)
{
lNormaMax = 0.;
lNormaMin = 0.;
//---Находим l-норму
for(int j = 0; j < numberOfEq; j++)
{
for(int i = 0; i < numberOfEq; i++)
{
lNormaMin = lNormaMin + fabs(mainMatrix[i][j]);
}
if(lNormaMin >= lNormaMax)
{
lNormaMax = lNormaMin;
lNormaMin = 0.;
}
}
if(lNormaMax < 1.)
{
hasRes = true;
}
}

if(!hasRes)
{
//---Находим k-норму
kNorma = 0.;
for(int i = 0; i < numberOfEq; i++)
{
for(int j = 0; j < numberOfEq; j++)
{
kNorma = kNorma + mainMatrix[i][j] * mainMatrix[i][j];
}
}
kNorma = sqrt(kNorma);
if(kNorma < 1.)
{
hasRes = true;
}
}

if(!hasRes)
{
cout << "Итерационный процесс будет расходящимся, расчет прерван" << endl << "Выход из программы" << endl;
return 0;
}

//---Начинаем итерационный процесс
for(int iter = 0; iter < maxIter; iter++)
{
cout << endl << "Результаты " << iter + 1 << "-й итерации:" << endl;
difference = 0.;
length = 0.;
if(numberOfIter == 0)
{
numberOfIter = 1;
for(int i = 0; i < numberOfEq; i++)
{
stringValue = rightMatrix[i];
for(int j = 0; j < numberOfEq; j++)
{
stringValue = stringValue + mainMatrix[i][j] * res[j];
}
difference = difference + (res[i] - stringValue) * (res[i] - stringValue);
length = length + res[i] * res[i];
res1[i] = stringValue;
//---Выводим результаты вычислений
cout << res1[i] << endl;
}
}
else
{
numberOfIter = 0;
for(int i = 0; i < numberOfEq; i++)
{
stringValue = rightMatrix[i];
for(int j = 0; j < numberOfEq; j++)
{
stringValue = stringValue + mainMatrix[i][j] * res1[j];
}
difference = difference + (res1[i] - stringValue) * (res1[i] - stringValue);
length = length + res1[i] * res1[i];
res[i] = stringValue;
//---Выводим результаты вычислений
cout << res[i] << endl;
}
}
//---Вычисляем погрешность (используется Евклидова норма вектора)
eps = sqrt(difference) / sqrt(length);
cout << "Погрешность вычислений: " << eps << endl;
cout << endl;
}

delete mainMatrix;
delete rightMatrix;
delete res;
return 0;
}
03.09.2008 в 14:52

А вот результат выполнения программы

03.09.2008 в 16:18

Не трать впустую (с)
О... *в тихом ужасе* Спасибо огромное. Будем разбираться.
04.09.2008 в 13:33

Чукча не писатель, чукча - читатель.
Блин, может и мне кто-нибудь курсач по нейроинформатике играючи напишет, а?