Итак, я работаю над набором инструментов для автоматической дифференциации на Фортране, используя перегрузку операторов. Ранее я реализовал это на С++, но мне действительно нужно заставить его работать на Фортране.
У меня есть следующий модуль, определенный в Fortran:
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
В С++ у меня есть аналогичный определяемый пользователем тип, как
class ADType {
public:
int index;
double v;
ADType() : index(-1), v(0) {};
ADType(const double&);
ADType& operator=(const ADType&);
};
где конструктор устанавливает начальные значения для частей index и value. Затем у меня есть конструктор для пассивных значений или констант (типа double), так что я могу определить новую переменную класса (ADType
) всякий раз, когда у меня есть двойная переменная. Например, когда у меня есть:
ADType x;
x = 2.0;
сначала создается новая переменная типа ADType
со значением, установленным на 2.0, скажем, var1 = 2.0
, а затем (в соответствии с оператором присваивания (=), определенным в классе ADType
) я назначу эту переменную x, т. е. x = var1
. Весь этот процесс записывается на ленту, которая подсчитывает операции и записывает значения и индексы.
Теперь вы можете сказать: «Зачем вам это нужно?». Ну а при сопряженном методе автоматического дифференцирования с перегрузкой операторов это необходимый шаг.
То, как я делаю это на C++, заключается в том, что у меня просто есть два следующих конструктора:
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;
}
но я не знаю, как реализовать конструктор для пассивных значений и констант в Фортране.
= 0.D0
,= 0
прекрасно подойдет, даже если ваши переменные были двойными. И поскольку ваши переменные являются вещественными значениями по умолчанию, D вообще не нужен. - person Vladimir F   schedule 10.10.2016