24小时热门版块排行榜    

查看: 1691  |  回复: 5
当前只显示满足指定条件的回帖,点击这里查看本话题的所有回帖

ryan111a

新虫 (初入文坛)

[求助] 关于应用fortran编写高斯消去法程序来求解方程组的问题

关于应用fortran编写高斯消去法程序来求解方程组的问题。 应用高斯消去法来求解方程组的fortran编程,我自己可以编写,但如果方程的系数矩阵不便,而右边的解矩阵发生了同样的变化,怎样才能通过循环,来求这个方程组的所有解。
      我当时在高斯消去法上加了个循环,但是在变换右边解矩阵时,出现了如下错误,怎么解决?
      E:\machao reactor\assitance\restart\one.f90(399) : Error: A constant or named constant is required in this context.   [IM]
          ImCmplx(Row,j)=(Im(j),0)
      Im(j)我想表达的意思是每次循环对应的的右边的解矩阵。j是高斯消去法循环的次数。
回复此楼

» 猜你喜欢

» 本主题相关价值贴推荐,对您同样有帮助:

live as if you will die today
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

pippi6

铁杆木虫 (著名写手)

工程和科学数值计算咨询

引用回帖:
4楼: Originally posted by pippi6 at 2013-06-06 17:00:51
你这两句是想干什么?
                       ImCmplx(Row,j)=(Im(j),0)
                         ImCmplx(Row,j)=(0,0)
如果是想表示一个复数由实部和虚部构成,应这么写
                      ImCmplx(Row ...

sorry, (0,0) ok, 但  (Im(j),0) 不行
5楼2013-06-06 17:02:08
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
查看全部 6 个回答

pippi6

铁杆木虫 (著名写手)

工程和科学数值计算咨询

【答案】应助回帖

★ ★ ★ ★ ★
感谢参与,应助指数 +1
nono2009: 编辑内容 2013-06-05 22:01
ryan111a: 金币+5, ★★★很有帮助 2013-06-06 08:59:59
给你个程序
CODE:
! How to use
!  real*8 :: c(n_dim,n_dim),e(n_dim,n_dim)
!  integer :: n=4
!     n           size of the matrix to be inversed
!     n_dim       array size
!     e           unit matrix
!     c           matrix to be inversed
!     call gaussr_inverse(c,n,n_dim,e,n,n_dim)

!flag
subroutine gaussr_inverse(a,n,np,b,m,mp)
  !     Commented, reorganized and understood by xxxx, 1999-11-03
  !     1.   very good designed scheme.
  !          seems No room for performance improve
  !     2.   row normalization (implicite pivoting) has not much  effect
  !           for full pivoting procedure

  !     991112  ASY/FJT, xxxx
  !     Test again. even important for full pivoting procedure

  !     3.   row normalization (implicite pivoting) has significant
  !           accuracy enhancement on partial pivoting procedure
  !              7.e-5 -> 2.e-11

  !     000623  ASY/FJT, xxx
  !     Real version


  implicit none
  integer :: n,np,m,mp,i,j,k,irow,icol,l
  real*8 a(np,np),b(np,mp),pivinv,cc
  real*8, allocatable, dimension(:) :: dum
  real*8 big
  integer, allocatable, dimension(:) :: ipiv,indxr,indxc
  real*8, allocatable, dimension(:) :: c1

  allocate(ipiv(1:n),indxr(1:n),indxc(1:n),dum(1:max(n,m)),c1(1:n))
  ipiv=0

  !     row normalization (implicite pivoting)
  do i=1,n
     c1(i)=1/sqrt(sum(abs(a(i,1:n))**2))
     a(i,1:n)=a(i,1:n)*c1(i)
     b(i,1:m)=b(i,1:m)*c1(i)
  end do

  do i=1,n

     !     Full pivoting, however, not necessarily starting from 1st col
     big=0.d0
     do j=1,n
        if(ipiv(j)==1)cycle
        do k=1,n
           if (ipiv(k)==1) cycle
           if (abs(a(j,k)) <= big) cycle
           big=abs(a(j,k))
           irow=j
           icol=k
        end do
     end do

     !     ipiv(icol)=1 means the column icol has been selected once
     ipiv(icol)=ipiv(icol)+1
     if (irow.ne.icol) then

        !     exchange a(irow,:) with a(icol,:)
        !     so a(irow,irow) is the selected pivot
        dum(1:n)= a(irow,1:n)  
        a(irow,1:n)= a(icol,1:n)  
        a(icol,1:n)=dum(1:n)

        dum(1:m)= b(irow,1:m)  
        b(irow,1:m)= b(icol,1:m)  
        b(icol,1:m)=dum(1:m)
     endif

     !     bookkeeping row- and column-indices
     indxr(i)=irow
     indxc(i)=icol
     if (abs(a(icol,icol))==0.d0) pause 'singular matrix.'
     pivinv=1.d0/a(icol,icol)
     a(icol,icol)=1.d0
     a(icol,1:n)=a(icol,1:n)*pivinv
     b(icol,1:m)=b(icol,1:m)*pivinv

     do l=1,n
        if(l==icol)cycle  ! only for row l not equal to icol
        cc=a(l,icol)
        a(l,icol)=0.d0    ! clever design
        a(l,1:n)=a(l,1:n)-a(icol,1:n)*cc
        b(l,1:m)=b(l,1:m)-b(icol,1:m)*cc
     end do
  end do

  do l=1,n
     if(indxr(l) == indxc(l)) cycle
     dum(1:n)=a(1:n,indxr(l))
     a(1:n,indxr(l))=a(1:n,indxc(l))
     a(1:n,indxc(l))=dum(1:n)
  end do

  do i=1,n
     a(1:n,i)=a(1:n,i)*c1(i)
  end do

  deallocate(ipiv,indxr,indxc,dum,c1)
end subroutine gaussr_inverse

[ Last edited by nono2009 on 2013-6-5 at 22:01 ]
2楼2013-06-05 15:54:26
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

ryan111a

新虫 (初入文坛)

引用回帖:
2楼: Originally posted by pippi6 at 2013-06-05 15:54:26
给你个程序

! How to use
!  real*8 :: c(n_dim,n_dim),e(n_dim,n_dim)
!  integer :: n=4
!     n           size of the matrix to be inversed
!     n_dim       array size
!     e           unit ma ...

十分感谢您的回答,相信用您的程序肯定可以实现此功能,因为我只是注重fortran程序实现我的功能,不知您是否有时间,帮忙修改下我的这块程序。
      
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
SUBROUTINE ICGaussA(ICmplx,NumT,NumI,MInd,R,Im)        !复数的高斯消去法(用来求包封电流或层电流)       
        IMPLICIT NONE

        INTEGER        NumT,NumI        !总包封数或层数
        COMPLEX        ICmplx(NumT,NumI) !复数电流值,待输出量
        REAL        MInd(NumT,NumT)        !包封或层的互感矩阵
        REAL        R(NumT)        !包封或层的电阻向量
        REAL    Im(NumI)

        COMPLEX        MZ[ALLOCATABLE](:, !电压阻抗矩阵
        COMPLEX        TZ[ALLOCATABLE](:, !电流阻抗矩阵
        COMPLEX        ImCmplx[ALLOCATABLE](:, !右端复数电流向量

        COMPLEX        Temp,Sum !中间变量
        INTEGER        Row,Col,Num !行号和列号
        INTEGER        ME !主元
        INTEGER i
        INTEGER j

        REAL,PARAMETER:mga=314.159
        REAL,PARAMETER::pai=3.14159

        ALLOCATE(TZ(NumT,NumT))
        ALLOCATE(MZ(NumT,NumT))
        ALLOCATE(ImCmplx(NumT,NumT))
    DO j=1,NumI   
            DO        Row=1,NumT
                      DO Col=1,NumT
                                 IF(Row==Col) THEN
                                           MZ(Row,Col)=CMPLX(R(Row),omga*MInd(Row,Col))
                              ELSE
                                      MZ(Row,Col)=CMPLX(0,omga*MInd(Row,Col))
                              END IF
                      END DO
            END DO

            DO Row=1,NumT
              IF(Row==NumT) THEN
                          DO Col=1,NumT
                              TZ(Row,Col)=CMPLX(1,0)
                          END DO
              ELSE
                  DO Col=1,NumT
                      TZ(Row,Col)=MZ(Row,Col)-MZ(Row+1,Col)
                  END DO
                  END IF
        END DO
            DO Row=1,NumT
                IF(Row==NumT) THEN
                        ImCmplx(Row,j)=(Im(j),0)
                    ELSE
                        ImCmplx(Row,j)=(0,0)
                    END IF
            END DO            
            DO Row=1,NumT
                    ME=Row
                    DO i=Row+1,NumT
                            IF(ABS(TZ(i,Row))>ABS(TZ(ME,Row))) THEN
                                   ME=i
                            END IF
                    END DO
                    DO i=1,NumT
                            Temp=TZ(ME,i)
                            TZ(ME,i)=TZ(Row,i)
                            TZ(Row,i)=Temp
                    END DO
                    Temp=ImCmplx(Row,i)
                    ImCmplx(Row,i)=ImCmplx(ME,i)
                    ImCmplx(ME,i)=Temp
                    DO Col=Row+1,NumT
                            TZ(Col,Row)=TZ(Col,Row)/TZ(Row,Row)
                            DO i=Row+1,NumT
                                TZ(Col,i)=TZ(Col,i)-TZ(Col,Row)*TZ(Row,i)
                            END DO
                            ImCmplx(Col,j)=ImCmplx(Col,j)-TZ(Col,Row)*ImCmplx(Row,j)
                    END DO
            END DO
            ICmplx(NumT,j)=ImCmplx(NumT,j)/TZ(NumT,NumT)
            DO Row=NumT-1,1,-1
                     Sum=ImCmplx(Row,j)
                     DO Num=Row+1,NumT
                             Sum=Sum-TZ(Row,i)*ImCmplx(i,Num)
                     END DO
                     ICmplx(Row,j)=Sum/TZ(Row,Row)
            END DO
        END DO       
        DEALLOCATE(MZ)
        DEALLOCATE(TZ)
        DEALLOCATE(ImCmplx)
        RETURN
END SUBROUTINE
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
live as if you will die today
3楼2013-06-06 08:59:26
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

pippi6

铁杆木虫 (著名写手)

工程和科学数值计算咨询

你这两句是想干什么?
                       ImCmplx(Row,j)=(Im(j),0)
                         ImCmplx(Row,j)=(0,0)
如果是想表示一个复数由实部和虚部构成,应这么写
                      ImCmplx(Row,j)=cmplx(Im(j),0)
                         ImCmplx(Row,j)=cmplx(0,0)
anyway, (0,0) 这样的写法在fortran里没有意义
4楼2013-06-06 17:00:51
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
信息提示
请填处理意见