fortran66のブログ

fortran について書きます。

Microsoft Fortran Powerstation 4.0 (FPS4)

Windows95 で動作する Fortran90 対応のコンパイラでした。バージョンが 4.0 に飛んだのは、Visual C++ と開発環境統合が統合できたので Visual C++ のバージョンに合わせたからだったと記憶しています。Win32 API 呼び出しなども出来るようになっており、その基本的な記述様式は現在の Intel Visual Fortran に至るまで引き継がれています。

Professional 版には IMSL ライブラリが付属しており、見栄えも他社の Fortran コンパイラに比べると洗練されていて、お得感もありました。またインストーラでは表示されませんが Numerical Recipesソースコードも CD 中に収められていました。(ただし、update 出来ない仕様。)

しかし当時、インターネットブラウザ戦争が勃発し、MS がリソースを IE 開発に振り向ける決定をしたため、VisualC++ 以外の言語開発部門が見捨てられてしまい、バグ対応などがちゃんとなされませんでした。ユーザーが騒いだ結果 4.0a への非公式パッチが出て、MSに電話をするとフロッピーが貰えましたが、I/O 時のメモリーリークなどは完全に直りませんでした。

MS は一応筋をとおして DEC への引継ぎを行ってくれたので、結果的にはよかったような気がしないでもないです。

  • 計算例

CG 法によって 1000 * 1000 の線型方程式を解く。


VMWare 上の Win98 にて

MODULE m_cg
IMPLICIT NONE
INTEGER, PARAMETER :: kd = SELECTED_REAL_KIND(12) !double precision
CONTAINS
!---------------------------------------------------
SUBROUTINE cg(a, b, x) ! Conjugate Gradient method
REAL(kd), INTENT(IN) :: a(:, :), b(:)
REAL(kd), INTENT(IN OUT) :: x(:)
REAL(kd) :: alpha, beta, r2n, r2d, eb2, p(SIZE(b)), q(SIZE(b)), r(SIZE(b))
INTEGER :: i
r = b - MATMUL(a, x) 
p = r
r2n = DOT_PRODUCT(r, r)
eb2 = EPSILON(b) * DOT_PRODUCT(b, b)
DO i = 1, SIZE(b)
 IF ( r2n < eb2 ) EXIT
 r2d = r2n
 q = MATMUL(a, p)
 alpha = DOT_PRODUCT(p, r) / DOT_PRODUCT(p, q)
 x = x + alpha * p
 r = r - alpha * q
 r2n = DOT_PRODUCT(r, r)
 beta = r2n / r2d
 p = r + beta * p			   
END DO
RETURN
END SUBROUTINE cg
END MODULE m_cg
!===================================================
PROGRAM cg_main
USE m_cg
IMPLICIT NONE
INTEGER, PARAMETER :: ns = 1000 
REAL(kd) :: a(ns, ns), b(ns), x(ns)
INTEGER :: i, j
! Make matrix 
DO i = 1, ns
 b(i) = 1.0_kd
 DO j = i, ns ! Givens Matrix,  x = (1, 0, 0, ... , 0)t
  a(i, j) = REAL( 2 * MIN(i, j) - 1, kd )  
  a(j, i) = a(i, j)
 END DO
END DO
! SOLVE Ax = b
CALL RANDOM_SEED() 
CALL RANDOM_NUMBER(x) ! starting vector
CALL cg(a, b, x)     
x = MATMUL(a, x) - b
PRINT *, 'difference (RMS) =', SQRT( DOT_PRODUCT(x, x) )
STOP
END PROGRAM cg_main


反復法なので出発ベクトルやオプティマイズで微妙に誤差が変わるw