1. HOME
  2. ブログ
  3. Fortranでオブジェクト指向
  4. Fortranでオブジェクト指向(12)

ブログ

Fortranでオブジェクト指向

Fortranでオブジェクト指向(12)

今日のポイント 実数型と倍精度実数型の共存

数値解析は一般的に倍精度実数型変数で行うことが多く、
OpenGLなどのライブラリでは実数型が標準になっていることが多くあります。
この時、実数型と倍精度実数型の変換処理はシステムによっては
かなりのCPUリソースを消費するため、この二つの変換を極力
少なくするために明示的に別々の計算をしたい場合があります。
この時、interface文で多様性を利用して方法で実装することも出来ますが、
構造体の多様性を利用してシンプルに実装することもできます。
 

サンプルプログラム

以下のサンプルではif_normモジュールのrvec, dvecの定義がポイントです。
rvecは実数型でXYZベクトル成分を持ちます。またprocedure normをrnormに
割り当てることでrvec%norm()でその絶対値を求められます。
dvecは倍精度型で上記と同じ処理を行います。
両者ともに%norm()でnormが求められますが、内部の処理では単精度実数と
倍精度実数が明示的に区別されている点がポイントです。
勿論構造体を用いなくても明示的に型変換の発生しないプログラムを作成する
ことは難しくはありませんが、保守性は最悪です。


module if_norm
  type rvec
    real :: x, y, z
    contains
      procedure :: norm => rnorm  
  end type rvec
  
  type dvec
    double precision :: x, y, z   
    contains
      procedure :: norm => dnorm  
  end type dvec
  
  contains
  
  real function rnorm(this)
    class(rvec), INTENT(INOUT) :: this
    rnorm = sqrt(this%x * this%x + this%y * this%y + this%z * this%z)
    return
  end function rnorm
  
  double precision function dnorm(this)
    class(dvec), INTENT(INOUT) :: this  
    dnorm = sqrt(this%x * this%x + this%y * this%y + this%z * this%z)
    return
  end function dnorm  
end module if_norm
    
program main
  use if_norm
  implicit none
  class(rvec), allocatable :: vec1(:)
  class(dvec), allocatable :: vec2(:)
  
  allocate(vec1(1), vec2(1))
  
  vec1(1)%x = 1.0
  vec1(1)%y = 2.0
  vec1(1)%z = 2.0

  vec2(1)%x = 1.0d0
  vec2(1)%y = 2.0d0
  vec2(1)%z = 2.0d0  
  
  write(6,*) vec1(1)%norm()
  write(6,*) vec2(1)%norm()
  
  read(5,*)
  
  stop
end program main

実行結果
3.000000
3.0000000000000

因みに数値解析の結果をOpenGLで表示する場合には
・一度は型変換して単精度実数で処理する
・型変換せずにOpenGLの倍精度実数処理を利用する
のいずれかになります。

本日はこの辺で。

関連記事