数値解析講座
 科学技術者の技術の向上を支援することを目的として、基礎的な数値解析講座として Newton法、Runge-kutta 法、Euler法、Bisection法についての解法を解説するとともに、それらのソースプログラムを紹介した。また、流出解析手法として、広く活用されてきている貯留関数法についても、解説とソースプログラムを紹介した。

 

●数値解析法の説明(PDF)

Newton法 Runge-kutta 法 Euler法 Bisection法

●ソースプログラム(fortran言語)   

方程式X : f(x)=a+X**P (P=3、a=3)  
貯留関数法 : f(sq2)=r-(sq1+sq2)/2-k*sq2**p+k*sq1**p

●計算結果(貯留関数法)

out.csv


方程式X  ソースプログラム
c  program
	open(10,file='out.csv')
c    方程式 f(x)=a + x**p
	a=-3.0
	p=3.0
	eps=1.e-5
	call newton(a,p,eps)
	call runge(a,p,eps)
	call euler(a,p,eps)
	call bisection(a,p,eps)
	pause 'end'
	stop
	end
c-----------------------------------------------------
  	subroutine newton(a,p,eps)
        funk(x) = a + x**p
	funk2(x)=p*x**(p-1)
	write(10,*) 'newton'
	write(10,*) 'f(x),x'
        x = 3.0      !初期値
	do i=1,100
	ax=funk(x)/funk2(x)
	x=x-ax
	if(abs(funk(x)).le.eps) go to 1000
	write(10,9999) funk(x),x
 9999	format(f10.4,',',f10.4)
	enddo
 1000	continue
	write(*,*) 'newton ans= ',x
	write(10,'(a6,f10.3)') 'ans= ,',x
	return
	end
c-----------------------------------------------------
  	subroutine runge(a,p,eps)
       funk(x) = a + x**p
	write(10,*) 'runge'
	write(10,*) 'f(x),x'
       x = 0.1       !初期値
       h = 0.1       !刻み幅
       do i=1, 100              
            a1 = h * funk(x)   
            a2 = h * funk(x + a1/2.)
            a3 = h * funk(x + a2/2.)
            a4 = h * funk(x + a3)
            x = x - (a1 + 2.*a2 + 2.*a3 + a4)/6. 
	if(abs(funk(x)).le.eps) go to 1000
	write(10,9999) funk(x),x
 9999	format(f10.4,',',f10.4)      
      end do
 1000	continue
	write(*,*) 'runge ans= ',x
	write(10,'(a6,f10.3)') 'ans= ,',x
       return
      end
c-----------------------------------------------------
        subroutine euler(a,p,eps)
	funk(x)=a+x**p
	write(10,*) 'euler'
	write(10,*) 'f(x),x'
	x=0.1   !初期値
	h=0.1   !刻み幅
	do i=1,50
	x=x-funk(x)*h
	if(abs(funk(x)).le.eps) go to 1000
	write(10,9999) funk(x),x
 9999	format(f10.4,',',f10.4)
	enddo
 1000	continue
	write(*,*) 'euler ans= ',x
	write(10,'(a6,f10.3)') 'ans= ,',x
	return
	end
c-----------------------------------------------------
        subroutine bisection(a,p,eps)
	funk(x)=a+x**p
	write(10,*) 'bisection'
	write(10,*) 'f(x),x'
	dh=5.0      !上限値
	dl=-1.0     !下限値
	x=3.0       !初期値
 3000   continue
	write(10,9999) funk(x),x
 9999	format(f10.4,',',f10.4)
	if(abs(funk(x)).le.eps) go to 1000
	if(funk(x).gt.0.0) go to 2000
	dl=x
	x=(dh+dl)/2.0
	go to 3000
 2000	dh=x
        x=(dh+dl)/2.0
	go to 3000
c
 1000	continue
	write(*,*) 'bisection ans= ',x
	write(10,'(a6,f10.3)') 'ans= ,',x
        return
	end


貯留関数法 ソースプログラム

c  program
	dimension r(10)
	data r/3.0, 8.0,16.0,26.0,14.2,3.0,0.0,0.0,0.0,0.0/ ! 時間雨量
	open(10,file='out.csv')       !出力ファイル
       write(10,*) '方程式(貯留関数法)'
     + ,'f(sq2)=r-(sq1+sq2)/2-k*sq2**p+k*sq1**p  を解く  (Q=sq*A/3.6)'
	eps=1.e-5
        ak=8.0
	p=0.6
	a=10.8
	write(10,*) '○定数'
	write(10,*) 'k=,',ak
	write(10,*) 'p=,',p
	write(10,*) 'A=,',a,',km2'
	write(10,*) 'TL=,',' 0.0',',hr'
	write(10,*) 'f1=,',' 0.0'
	write(10,*) 'Rsa=,',' 0.0',',mm'
c
	write(10,*) '○計算結果'
c
	write(*,*) 'Newton'
	write(10,*) 'Newton,r(mm/hr),sq(mm/hr),Q(m3/s)'
	sq1=0.001
	do i=1,10
	call newton(ak,p,a,r(i),sq1,eps,x)
	sq1=x
	enddo
c
	write(*,*) 'Runge'
	write(10,*) 'Runge,r(mm/hr),sq(mm/hr),Q(m3/s)'
	sq1=0.001
	do i=1,10
	call runge(ak,p,a,r(i),sq1,eps,x)
	sq1=x
	enddo
c
	write(*,*) 'Euler'
	write(10,*) 'Euler,r(mm/hr),sq(mm/hr),Q(m3/s)'
	sq1=0.001
	do i=1,10
	call euler(ak,p,a,r(i),sq1,eps,x)
	sq1=x
	enddo
c
	write(*,*) 'Bisection'
	write(10,*) 'Bisection,r(mm/hr),sq(mm/hr),Q(m3/s)'
	sq1=0.001
	do i=1,10
	call bisection(ak,p,a,r(i),sq1,eps,x)
	sq1=x
	enddo
	pause 'end'
	stop
	end
c----------------------------------------------------------
  	subroutine newton(ak,p,a,r,sq1,eps,x)
	funk(sq2)=r-(sq1+sq2)/2-ak*sq2**p+ak*sq1**p
	funk2(sq2)=-ak*p*sq2**(p-1)-0.5       ! = f’(sq2)
        x = 0.0001      !初期値
	do i=1,100
	xn=funk(x)/funk2(x)
	x=x-xn
	if(abs(funk(x)).le.eps) go to 1000
	enddo
 1000	continue
	write(10,9000) r,x,x*a/3.6
 9000	format(3(',',f10.3))
	write(*,*) r,x,x*a/3.6
	end
c----------------------------------------------------------
  	subroutine runge(ak,p,a,r,sq1,eps,x)
       funk(sq2) = r-(sq1+sq2)/2-ak*sq2**p+ak*sq1**p
       x = 100.0       !初期値
       h = -0.1       !刻み幅
       do i=1, 100              
            a1 = h * funk(x)   
            a2 = h * funk(x + a1/2.)
            a3 = h * funk(x + a2/2.)
            a4 = h * funk(x + a3)
            x = x - (a1 + 2.*a2 + 2.*a3 + a4)/6. 
	if(abs(funk(x)).le.eps) go to 1000
       end do
 1000	continue
	write(10,9000) r,x,x*a/3.6
 9000	format(3(',',f10.3))
	write(*,*) r,x,x*a/3.6
       return
      end
c----------------------------------------------------------
        subroutine euler(ak,p,a,r,sq1,eps,x)
       funk(sq2) = r-(sq1+sq2)/2-ak*sq2**p+ak*sq1**p
	x=100.0   !初期値
	h=-0.1   !刻み幅
	do i=1,50
	x=x-funk(x)*h
	if(abs(funk(x)).le.eps) go to 1000
	enddo
 1000	continue
	write(10,9000) r,x,x*a/3.6
 9000	format(3(',',f10.3))
	write(*,*) r,x,x*a/3.6
	return
	end
c----------------------------------------------------------
        subroutine bisection(ak,p,a,r,sq1,eps,x)
        funk(sq2) = r-(sq1+sq2)/2-ak*sq2**p+ak*sq1**p
	dh=1000.0      !上限値
	dl=0.0         !下限値
	x=dh           !初期値
 3000   continue
	if(abs(funk(x)).le.eps) go to 1000
	if(funk(x).gt.0.0) go to 2000
	dh=x
	x=(dh+dl)/2.0
	go to 3000
 2000	dl=x
        x=(dh+dl)/2.0
	go to 3000
c
 1000	continue
	write(10,9000) r,x,x*a/3.6
 9000	format(3(',',f10.3))
	write(*,*) r,x,x*a/3.6
        return
	end
数値解析講座

TOP