私は演算子のオーバーロードを使用してFortranの自動微分ツールボックスに取り組んでいます。これまでC++で実装していましたが、実際にFortranで動作させる必要があります。パッシブ値または定数をユーザー定義型に割り当てる
Iは、Fortranで定義された以下のモジュールを有する:コンストラクタはインデックスの初期値を設定する場合にC++で
module adopov
integer :: indexcount
integer, parameter :: tape_size = 1000
!
!....... ADtype
public :: ADtype
type ADtype
integer :: index = -1
real :: v = 0.0
!
contains
procedure :: oo_asg
generic, public :: assignment(=) => oo_asg
end type ADtype
!
!....... class tape
public :: ADtape
type ADtape
real :: v = 0.0
end type ADtape
!
!....... interface(s)
interface assignment(=)
module procedure oo_asg
end interface
!
type (ADtape), dimension(tape_size) :: tape
!
!....... definitions
contains
!
!....... assignment
subroutine oo_asg (x,y)
implicit none
class(ADtype), intent(out) :: x
class(ADtype), intent(in) :: y
!
tape(indexcount)%v = y%v
indexcount = indexcount + 1
x%v = y%v
x%index = indexcount
end subroutine oo_asg
!
end module adopov
を、Iは
class ADType {
public:
int index;
double v;
ADType() : index(-1), v(0) {};
ADType(const double&);
ADType& operator=(const ADType&);
};
と同様のユーザー定義型を有し、かつ価値のある部品。次に、受動的な値または定数(double型)のコンストラクタを用意して、double変数を持つたびにクラス(ADType
)の新しい変数を定義できます。私が持っている場合、例えば、:
ADType x;
x = 2.0;
が最初タイプADType
の新しい変数が2.0に設定された値を使用して作成され、(クラスADType
で定義された代入演算子(=)による)のにvar1 = 2.0
と次を言わせてIその変数をxに代入します(x = var1
)。このプロセス全体が、操作を数え、値とインデックスを記録するテープに記録されています。
今、「なぜこれを行う必要がありますか」と言うかもしれません。オペレータのオーバーロードを使用する自動微分の随伴法の間、これは必要なステップです。
ADType:: ADType(const double& x): v(x) {
tape[indexcounter].v = x;
indexcounter++;
};
ADType& ADType::operator=(const ADType& x) {
if (this==&x) return *this;
tape[indexcounter].v = v = x.v;
indexcounter++;
return *this;
}
が、私はFortranで、受動的な値と定数のコンストラクタを実装する方法がわからない:
私はCでそれを行う方法は、++、私は単純に以下の2つのコンストラクタを持っていることです。
を生成するには、それはあなたのプログラムですが、あなたがC言語で小文字を使用する場合++理由だけでなくFortranでそれらを使用していませんか?彼らはもっと読みやすい。そして、 '= 0.D0'は必要なく、変数が倍になっても' = 0'は完璧です。あなたの変数はデフォルトの実数なので、Dの必要は全くありません。 –
@VladimirFヒントをありがとう。私はそれがちょうど古い習慣だと思う – FRJedi
@VladimirFはそれをより読みやすくするために質問を編集しました – FRJedi