Piecewise struct

提供: ComplexRI: Manual
ナビゲーションに移動 検索に移動

区分構造を扱う構造体。 ここで区分構造とは数直線の切り分け方を意味する。

例えば数直線を 0, 1 で切り分ける場合、 数直線は [-∞, 0]、[0, 1]、[1, ∞] の 3 つの区分領域に分けられる。 区分領域の境目となる 0, 1 は節点と呼ぶ。

piecewise_struct は、区分構造に対する操作として

  • 2 つの区分構造を合わせて、両方の区分を含む 1 つの区分構造を作る。つまり、両者の節点の中に同じ値が含まれている場合は一つにまとめ、それ以外の場合は節点を増やす。:演算子 +
  • 節点の間隔を c 倍に拡大(c < 1 で縮小)する:function zoom(c)
  • 節点全体を右に a だけシフトさせる:function shift(a)
  • 節点全体を原点に対して反転させる:function reflect()


実装する。 これらの関数の結果は全て piecewize_struct 型で返す。 また、区分構造の情報を調べる関数として、

  • x の値が入る区分領域の番号 n を返す。:function region_index(x) result(i)
  • i 番目の区分領域に含まれる変数の代表値を返す。: function repvalue(n) result(i)
  • 区分領域を表わす不等式を文字列として返す。i が指定された場合は i 番目の区分領域を表わす不等式、指定されない場合は不等式すべてを羅列して返す。: function string([i]) result(s)
  • 区分領域が pw と等しいかどうか判定する。: function equiv(pw) result(TF)

を実装する。 コンストラクタは区分点の配列を引数としており、

<source lang="fortran"> pw = piecewise([0.0d0,1.0d0]) </source>

のように宣言される。


拡張の際の注意点

piecewise_struct は piecewise_polynomial_struct の親構造体とすることを目的として作成されている。 そのため、

type(piecewise_polynoial_struct) :: pp
type(piecewise_struct) :: pw

とした際に、

pp = pw

のように型間の代入が可能であることが望ましい。 そこでこれを可能とするために、piecewise_struct 中にユーザー定義代入文

general :: assignmnt(=) => equal
procedure :: equal
subroutine equal(pw1,pw2)
  class(piecewise_struct),intent(inout) :: pw1
  type(piecewise_struct),intent(in) :: pw2

を定義することにする。 これにより、pp = pw とした場合に pp は class(piecewise_struct)、pw は type(piecewise_struct) に所属するため、 目的の代入が可能となる。 一方で、代入を自分で定義する必要が発生するため、メンバ変数を追加・変更した際などは equal サブルーチンの書き換えが必要とってしまう。 この仕様は拡張の際に面倒となるが、現状良い対策が見つからないためこの形で実装する。 拡張構造体を使ったプログラミングにおける問題と解決策 も参照すること。