Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Fortran > [General] Метод Гаусса


Автор: tatu 28.4.2010, 13:50
Ну в общем что-то я тыркался с Гауссом но нефига не понял этот фортран)))) даже хапустить не могу(((( все какие-то ошибки выдает.

суть в том чо нужно реализоваьт метод гаусса причем тарица вводиться из файла, и считаются невязки;)

Автор: kemiisto 28.4.2010, 14:15
Цитата(tatu @  28.4.2010,  14:50 Найти цитируемый пост)
Ну в общем что-то я тыркался с Гауссом но нефига не понял этот фортран)))) даже хапустить не могу(((( все какие-то ошибки выдает.

С чем Вы тыркались и с какой целью?


Цитата(tatu @  28.4.2010,  14:50 Найти цитируемый пост)
суть в том чо нужно реализоваьт метод гаусса причем тарица вводиться из файла, и считаются невязки;)

Задача учебная? Где код, что Вы написали?

Автор: tatu 9.5.2010, 11:21
Код

      program laba1
    integer raz
    real M(20,20), M1(20,20), x(20), nev(20), pog
     pause

      open(11,file='input.txt')
    read(11,*) raz
    do i=1,raz
       read(11,*)(M(i,j),j=1,raz+1)
       write(*,7) (M(i,j),j=1,raz+1)
     enddo 
    M1=M

      !priamoi hod
    do i=1,raz-1,1
     do j=(i+1),raz,1
      if (M(j,i).NE.0) then
       pog=-M(j,i)/M(i,i)
       do k=1,raz+1,1
        M(j,k)=M(j,k)+M(i,k)*pog
       end do
      end if
     end do
    end do


      write(*,*) "Stupen4atyi vid massiva"
      do i=1,raz,1
     write(*,7)    (M(i,j), j=1,raz+1,1)
7     format(14F9.5)
    end do



       !obratni hod
    do i=raz,1,-1
     pog=0
     do j=i+1,raz,1
      pog=pog+x(j)*M(i,j)
     end do
     if (M(i,i).NE.0) then
        x(i)=(M(i,raz+1)-pog)/M(i,i)
       end if
    end do
   
    do i=1,raz,1
      pog=0
      do j=1,raz,1
       pog=pog+M1(i,j)*x(j)
      end do
      M1(i,raz+1)=M1(i,raz+1)-pog
    end do

    do i=1,raz-1,1
     do j=(i+1),raz,1
      if (M1(j,i).NE.0) then
       pog=-M1(j,i)/M1(i,i)
       do k=1,raz+1,1
        M1(j,k)=M1(j,k)+M1(i,k)*pog
       end do
      end if
     end do
    end do

      write(*,*)' '
      write(*,*) "nevazki':"
      do i=raz,1,-1
     pog=0
     do j=i+1,raz,1
      pog=pog+nev(j)*M1(i,j)
     end do 
     nev(i)=(M1(i,raz+1)-pog)/M1(i,i)      
    end do

    do i=1,raz
      write(*,*)'nev=',nev(i)
    enddo

      write(*,*)' '
      write(*,*) "Otvet:"
    do i=1,raz,1
      write(*,*)'x=',x(i)
    end do
       
      write(*,*)' '
    write(*,*) ' proverka:'
    do i=1,raz,1
      write(*,*)'x+nev=',x(i)+nev(i)
    end do
    pause  'Vixod'
    end



вот код.....почему-то не считает массивы больше 7. точнее правильно не считает...до 7 нормально все а потом нет.

Автор: FCM 13.5.2010, 20:19
Может зависеть от конкретного вида матрицы. 
Профессиональные программы предусматривают всякие ухищрения в целях предварительного "улучшения" матрицы.
Но в ряде случаев достаточно перейти на двойную точность.
Покажи матрицу с которой проблемы.

Автор: tatu 26.5.2010, 20:42
двойную точност ставил, нефига не помагает((((
матрица любая

у нас 20 на 20 проверяет
в архиве есть все.

посмотрите, может что-то не так сделал при решении?

Автор: FCM 29.5.2010, 09:45
В целом в прямом и обратном ходе вроде все более менее, за исключением
проверки на неравенство нулю вещественных чисел, на которые происходит деление, которую лучше заменить на проверку превышения некоторого малого порога и, если модуль числа, на которое происходит деление, меньше его, останавливать вычисление с соответствующим сообщением.

(Расчет невязки я не смотрел)

Я взял твою программу, сделал массивы динамическими, ввод размера (т.е. raz) массива с клавиатуры и инициализацию M случайными числами.
Если нет элементов с малыми значениями, то все считает. Например,  для raz = 18 максимум невязки ~ 10^-5. 
Если же сделать двойную точность будет ~ 10^-14. ("Двойная точность - вежливость программистов"). 

Проблемы возникают, если есть элементы матрицы или промежуточных матриц с очень малыми (или очень большими) значениями. 
Тут уже надо менять алгоритм - т.е. делать перестановки строк или столбцов, чтобы избежать деления на малые числа (это называется методом Гаусса с выбором главного элемента - см., например, Рыжиков "Современный фортран"2004 или Вержбицкий "Основы численных методов" 2005 стр.58. ) .

(Еще в результате прямого хода последнее уравнение может принять вид 0=0, что означает бесконечное множество решений.)

Поэтому и предлагалось показать матрицу, с которой возникают проблемы (в выложенном архиве нашел только одну расширенную матрицу 4х5).

Возможна также проблема при считывании матрицы, т.е. соответствующие матрицы в файле некорректно записаны.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)