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