Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Решатель системы лин. уравнений 
:(
    Опции темы
Anton Vatchenko
Дата 14.7.2004, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 21.5.2004

Репутация: нет
Всего: -1



Кто-нибудь таким маялся? Я, например, реализовал Гауссовский метод, но погрешности умножения и сложения double не дают нормально привести матрицу к треугольной. Вроде бы складываю и умножаю, а вначале 0 - это 0.0000000000000000000001, а через десяток операций это уже 10000000000000. Может кто-нибудь делал/видел алгоритмы. Мне надо решать систему уравнений, например 50х50 как можно быстрее. Причем могут быть нулевые строки. Помогите с алгоритмом...


--------------------
user posted image
PM MAIL   Вверх
yurgen20
Дата 14.7.2004, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 3.4.2003

Репутация: нет
Всего: нет



Как это "нулевые строки"? Такую систему не решить. Может нулевые диагональные элементы? Тогда придеться делать соответствующую проверку и менять строки местами. А вообще лучше использовать метод Ньютона или Зейделя. Имхо быстрее и проще.
PM MAIL   Вверх
Anton Vatchenko
Дата 14.7.2004, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 21.5.2004

Репутация: нет
Всего: -1



А исходники есть? Нулевые строки, я имел в виду, что есть 0 x1+0 x2+0 x3+0 x4=0. Я их могу вычеркнуть, но тогда матрица не будет квадратная


--------------------
user posted image
PM MAIL   Вверх
Kurt
Дата 14.7.2004, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Увлеченный
***


Профиль
Группа: Участник Клуба
Сообщений: 1662
Регистрация: 22.8.2003
Где: Краснодар

Репутация: нет
Всего: 36



Помню, я, учась в университете, реализовывал пару-тройку таких алгоритмов.
Даже сравнение количества операций было.
Вот тока не помню, остались ли у меня такие доки. По-моему, сами реализации где-то валялись.
Приду домой - гляну.
Тебе обязательно на С++? По-моему, там у меня Borland C++ && Delphi.
Накрайняк, если ничего хорошего не найдешь и я у себя в эл. виде не найду - напишу что-то типа "статьи" - хотя, вроде, в и-нете полно таких доков..
Кстати.. ИМХО, любой алгоритм будет работать с погрешностью - ведь комп обрабатывает числа с плавающей точкой с некоторой степенью точности.
Я реализовывал алгоритмы, к-е теоретически должны давать точный результат, но на практике появлялись погрешности.
Тебе что важнее? Скорость или точность?
Хорошую скорость дают методы Зейделя, метод какого-то-там ( smile.gif названия не помню, но маялся я с ним долго..) спуска... короче, надо добраться домой. smile.gif


--------------------
Для корабля, который не знает куда плыть, нет попутного ветра... ((С) Архимед)
...
Все знают, что это невозможно. Но случайно находится невежда, который этого не знает. Он-то и делает открытие.. ((С) А. Эйнштейн)
PM ICQ   Вверх
bilbobagginz
Дата 14.7.2004, 11:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Naughtius Maximus
****


Профиль
Группа: Экс. модератор
Сообщений: 8813
Регистрация: 2.3.2004
Где: Israel

Репутация: 3
Всего: 317



Если проблема - только с точностью, то используй библиотеки высокой точности для промеж. вычислений:
1) набирай коэфф. уравнений в форме double.
2) для вычислений переведи их в какой-нибудь более точный вид данных (в соответствии с библиотекой высокой точности),
3) считай что тебе нужно, а
4) результат обратно переводи ("downcast") в double

теперь вопрос какой метод решения выбирать и в какой форме хранить:
если твои матрицы будут очень жидконаселёнными, стоит хранить в форме
массив списков а не 2-х мерный массив.
а метод решения ты уж сам выбирай, хоть Kramer , хоть Gauss, хоть Seidel-Gauss... как тебе угодно.







--------------------
Я ещё не демон. Я только учусь.
PM WWW   Вверх
Kurt
Дата 14.7.2004, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Увлеченный
***


Профиль
Группа: Участник Клуба
Сообщений: 1662
Регистрация: 22.8.2003
Где: Краснодар

Репутация: нет
Всего: 36



Цитата
А исходники есть? Нулевые строки, я имел в виду, что есть 0 x1+0 x2+0 x3+0 x4=0. Я их могу вычеркнуть, но тогда матрица не будет квадратная

Эй-эй-эй!
а ты уверен, что твои системы разрешимы и меют тока ОДНО решение?
По-моему, все вышеназванные методы, тока для системы, у к-й одно и только одно решение!


--------------------
Для корабля, который не знает куда плыть, нет попутного ветра... ((С) Архимед)
...
Все знают, что это невозможно. Но случайно находится невежда, который этого не знает. Он-то и делает открытие.. ((С) А. Эйнштейн)
PM ICQ   Вверх
bilbobagginz
Дата 14.7.2004, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Naughtius Maximus
****


Профиль
Группа: Экс. модератор
Сообщений: 8813
Регистрация: 2.3.2004
Где: Israel

Репутация: 3
Всего: 317



Если проблема - только с точностью, то используй библиотеки высокой точности для промеж. вычислений:
1) набирай коэфф. уравнений в форме double.
2) для вычислений переведи их в какой-нибудь более точный вид данных (в соответствии с библиотекой высокой точности),
3) считай что тебе нужно, а
4) результат обратно переводи ("downcast") в double

теперь вопрос какой метод решения выбирать и в какой форме хранить:
если твои матрицы будут очень жидконаселёнными, стоит хранить в форме
массив списков а не 2-х мерный массив.
а метод решения ты уж сам выбирай, хоть Kramer , хоть Gauss, хоть Seidel-Gauss... как тебе угодно.







--------------------
Я ещё не демон. Я только учусь.
PM WWW   Вверх
yurgen20
Дата 14.7.2004, 12:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 3.4.2003

Репутация: нет
Всего: нет



Вот алгоритм приведения матрицы к диагональному виду(написано для вычисления определителя):

//Приведение матрицы к треугольному виду
int fn(double **a, int size)
{
for(int k=0; k<size-1; k++)//Прогон по диагонали
{
for(int j=k+1;j<size;j++)
{
double koef=(a[j][k]/a[k][k]);
a[j][k]=0;
for(int i=k+1;i<size;i++)
{
a[j][i]+=(-koef)*a[k][i];
}
}
}
}
Если вдруг будут нулевые диагональные элементы (a[k][k]=0), то алгоритм не прокатит, нужно ввести дополнительное условие типа:
if(a[k][k]==0){меняем местами текущую и следующую строки}

Проверял результат (определитель матрицы) в Матлабе - результаты идентичны до восьмого знака после запятой (дальше не смотрел). Так что дабл вроде канает. Считает правда дольше чем Матлаб. Матрицу 150х150 на 1500ГГц считает где-то пол минуты.

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

PM MAIL   Вверх
Anton Vatchenko
Дата 14.7.2004, 12:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 21.5.2004

Репутация: нет
Всего: -1



Мне советовали использовать метод Холецкого. Но у меня не симметричная матрица. Как он будет работать для таковой?


--------------------
user posted image
PM MAIL   Вверх
Underdark
  Дата 16.7.2004, 08:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 70
Регистрация: 12.7.2004
Где: Ульяновск

Репутация: нет
Всего: 2



Слушай, у меня есть моя отличная реализация этой задачи на Delphi.
Хочешь я тебе её подгоню, а ты там сам в коде поковыряешься - там отличные алгоритмы. tounge.gif
Ну так как?
PM MAIL   Вверх
np9mi7
Дата 17.7.2004, 21:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 553
Регистрация: 17.8.2003
Где: Volgograd, Russia

Репутация: 5
Всего: 10



Цитата
int gauss(double *aMatr,double *bMatr,double *vector,int razmer);
void copy_to_temp(double *pVar,double *pTemp,int n);
void umn_temp(double *pTemp,double x,int n);
void plus_temp(double *pVar,double *pTemp,int n);
int poisk_ne_null(int m,double *pVar,int n);
void zamena(double *pVar1,double *pVar2,int n);
void zamena(double *pVar1,double *pVar2,int n)
{
double t;
n++;
for(int i=0;i<n;i++)
{
  t=*(pVar1+i);
  *(pVar1+i)=*(pVar2+i);
  *(pVar2+i)=t;
}
}
int poisk_ne_null(int m,double *pVar,int n)
{
int k=0,i;
for(i=m;i<n;i++)
{
  if(*(pVar+k*100))
  return i;
  k++;
}
return -1;
}
void plus_temp(double *pVar,double *pTemp,int n)
{
n++;
for(int i=0;i<n;i++)
{
  *(pVar+i)+=*(pTemp+i);
}
}
void umn_temp(double *pTemp,double x,int n)
{
n++;
for(int i=0;i<n;i++)
{
  *(pTemp+i)=x*(*(pTemp+i));
}
}
int gauss(double *aMatr,double *bMatr,double *vector,int razmer)
{
double A[20][20],XX[20],temp[20];
int i,j;
//---------------------------------------------------------
for(i=0;i<razmer;i++)
{
  for(j=0;j<razmer;j++)
  {
  A[i][j]=*(aMatr+i*razmer+j);
  }
}
for(i=0;i<razmer;i++)
{
  A[i][razmer]=*(bMatr+i);
}
//-----------------------------------------------------------
for(i=0;i<razmer-1;i++)
{
  if(A[i][i]==0)
  {
  j=poisk_ne_null(i,&A[i][i],razmer);
  if(j==-1)
    return 0;
  else
    zamena(&A[i][0],&A[j][0],razmer);
  }
  for(j=i+1;j<razmer;j++)
  {
  copy_to_temp(&A[i][0],&temp[0],razmer);
  umn_temp(&temp[0],-A[j][i]/A[i][i],razmer);
  plus_temp(&A[j][0],&temp[0],razmer);
  }
}
for(i=razmer-1;i>0;i--)
{
  if(A[i][i]==0)
  return 0;
  for(j=i-1;j>=0;j--)
  {
  copy_to_temp(&A[i][0],&temp[0],razmer);
  umn_temp(&temp[0],-A[j][i]/A[i][i],razmer);
  plus_temp(&A[j][0],&temp[0],razmer);
  }
}
for(i=0;i<razmer;i++)
{
  XX[i]=A[i][razmer]/A[i][i];
}
//-----------------------------------------------------------
for(i=0;i<razmer;i++)
{
  *(vector+i)=XX[i];
}
//-----------------------------------------------------------
return 1;
}
void copy_to_temp(double *pVar,double *pTemp,int n)
{
n++;
for(int i=0;i<n;i++)
{
  *(pTemp+i)=*(pVar+i);
}
}

Можно многое оптимизировать, но это нормальная рабочая версия...


--------------------
"Я точно знаю то, что ничего не знаю..." Сократ.
evolution project
PM MAIL WWW ICQ MSN   Вверх
Anton Vatchenko
Дата 19.7.2004, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 21.5.2004

Репутация: нет
Всего: -1



Теперь проблем с точностью нет. Но возникла другая проблема: как решить систему, если у нее не одно решение? Что делать в таких случаях? Пусть, например, есть линейно зависимые строки. Если их менять местами, то ничего ж не улучшится!


--------------------
user posted image
PM MAIL   Вверх
np9mi7
Дата 19.7.2004, 21:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 553
Регистрация: 17.8.2003
Где: Volgograd, Russia

Репутация: 5
Всего: 10



Если решать систему с линейно зависимыми строками то в итоге придется вырпжать все через некоторые переменные

Пример:
Цитата

X1+X2=5;
2*X1+2*X2=10;

Тогда решение выглядит так:
Цитата

X1=5-X2;

Те все это придется выражать через X2...

Так у тебя что задача написать прогу которая решает любые системы??? Если так то давай займемся...Без б, помогу...


--------------------
"Я точно знаю то, что ничего не знаю..." Сократ.
evolution project
PM MAIL WWW ICQ MSN   Вверх
Николай Клевец
Дата 6.8.2004, 18:01 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Решение систем линейных алгебраических уравнений (СЛАУ) в общем виде непростая задача.
Похоже у Вас плохо обусловленная или вырожденная СЛАУ. Для ее решения надо применять специальные устойчивые методы регуляризации или сингулярного разложения.
Ощий подход сдедующий:
1) решаем методом Гаусса (он самый быстрый), если не решает, то
2) решаем либо методом сингулярного разложения (svd) (сложный, медленный, но надежный),
3) либо методом наискорейшего градиентного спуска (простой, надежный, но медленный).
Для более точных рекомендаций надо уточнить цель Ваших расчетов.
Если проблема еще не решена, то пишите, я вышлю нужные процедуры.
Н.И. Клевец
[email protected]
  Вверх
power
Дата 17.6.2006, 07:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 17.6.2006

Репутация: нет
Всего: нет



Ребят, я тут новенький!))) может у кого есть готовый алгоритм решения СЛАУ методом наискорейшего градиентного спуска?! Если есть и нетрудно - вышлите пожалуйста - он мне ну очень срочно нужен. Заранее спасибо!

[email protected]  
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0584 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.