Traits ve Fortranu

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Traits ve Fortranu
« Odpověď #30 kdy: 10. 09. 2022, 18:04:58 »
ja bych si furt myslel, ze na numericke pocitani ol'good fortran a jeste mpi na cluster.
Pro paralelní zpracování (HPC clustery) má pěkná rozšíření Fortran 2018.


mikrom

  • ****
  • 321
    • Zobrazit profil
    • E-mail
Re:Traits ve Fortranu
« Odpověď #31 kdy: 10. 09. 2022, 19:36:04 »
Tak s tymi Quaternionmi to samozrejme vo Fortrane ide.
Nadefinujes si vlastny typ Queternion a k nemu overloadujes operatory + - *
To sa urobi zase cez moduly 8), ziadne traity nie su treba.

mikrom

  • ****
  • 321
    • Zobrazit profil
    • E-mail
Re:Traits ve Fortranu
« Odpověď #32 kdy: 10. 09. 2022, 19:43:18 »
Napriklad, takto to funguje s tymi quaternionmi:

quaternions.f95
Kód: [Vybrat]
module my_quaternions
  type quaternion
    real :: x, y, z, t
  end type quaternion

  interface assignment(=)
    module procedure quaternion_from_array
  end interface

  interface operator(+)
    module procedure add_quaternions
  end interface 

  interface operator(-)
    module procedure substract_quaternions
  end interface

  interface operator(*)
    module procedure hamilton_product
  end interface 

contains
  subroutine quaternion_from_array(q, v)
    ! construct quaternion Q from an array V
    ! Q = V
    real, dimension(4), intent(in) :: v
    type(quaternion), intent(out) :: q
    q%x = v(1)
    q%y = v(2)
    q%z = v(3)
    q%t = v(4)
  end subroutine quaternion_from_array

  subroutine print_quaternion(q, q_name)
    type(quaternion), intent(in) :: q
    character(*), intent(in) :: q_name
    write (*, 10) q_name,' = (', q%x, ', ', q%y, ', ', q%z, ', ', q%t, ')'
    write (*,*)
    10 format(a, a, f8.2, a, f8.2, a, f8.2, a, f8.2, a)
  end subroutine print_quaternion

  function add_quaternions(a, b) result(c)
    type(quaternion), intent(in) :: a
    type(quaternion), intent(in) :: b
    type(quaternion) :: c
    c%x = a%x + b%x
    c%y = a%y + b%y
    c%z = a%z + b%z
    c%t = a%t + b%t
  end function add_quaternions

  function substract_quaternions(a, b) result(c)
    type(quaternion), intent(in) :: a, b
    type(quaternion) :: c
    c%x = a%x - b%x
    c%y = a%y - b%y
    c%z = a%z - b%z
    c%t = a%t - b%t
  end function substract_quaternions

  function hamilton_product(a, b) result(c)
    type(quaternion), intent(in) :: a, b
    type(quaternion) :: c
    c%x = a%x*b%x - a%y*b%y - a%z*b%z - a%t*b%t
    c%y = a%x*b%y + a%y*b%x + a%z*b%t - a%t*b%z
    c%z = a%x*b%z - a%y*b%t + a%z*b%x - a%t*b%y
    c%t = a%x*b%t + a%y*b%z - a%z*b%y + a%t*b%x
  end function hamilton_product

end module my_quaternions

program quaternions
  use my_quaternions
  type(quaternion) :: a, b, c

  write (*,'(a)') 'Quaternions example:'
  b = (/1., 2., 3., 4./)
  a = (/5., 6., 7., 8./)
  call print_quaternion(a, 'a')
  call print_quaternion(b, 'b')

  write (*,'(a)') 'c = a + b'
  c = a + b
  call print_quaternion(c, 'c')
 
  write (*,'(a)') 'c = a - b'
  c = a - b
  call print_quaternion(c, 'c')

  write (*,'(a)') 'c = a * b'
  c = a * b
  call print_quaternion(c, 'c')
end program quaternions

Output:
Kód: [Vybrat]
$ gfortran quaternions.f95 -o quaternions
$ ./quaternions
Quaternions example:
a = (    5.00,     6.00,     7.00,     8.00)

b = (    1.00,     2.00,     3.00,     4.00)

c = a + b
c = (    6.00,     8.00,    10.00,    12.00)

c = a - b
c = (    4.00,     4.00,     4.00,     4.00)

c = a * b
c = (  -60.00,    20.00,   -18.00,    32.00)

mikrom

  • ****
  • 321
    • Zobrazit profil
    • E-mail
Re:Traits ve Fortranu
« Odpověď #33 kdy: 10. 09. 2022, 19:53:26 »
ja bych si furt myslel, ze na numericke pocitani ol'good fortran a jeste mpi na cluster.
Pro paralelní zpracování (HPC clustery) má pěkná rozšíření Fortran 2018.
a jak vies ze tie rozsirenia su pekne, ked si povedal ze vo fortrane neprogramujes  :)  btw. ja som asi iba raz v zivote experimentalne pouzil OpenMP

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Traits ve Fortranu
« Odpověď #34 kdy: 10. 09. 2022, 21:07:51 »
Tak s tymi Quaternionmi to samozrejme vo Fortrane ide.
  ::)


Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Traits ve Fortranu
« Odpověď #35 kdy: 10. 09. 2022, 21:09:47 »
a jak vies ze tie rozsirenia su pekne, ked si povedal ze vo fortrane neprogramujes
To jsem nikdy neřekl, jen že nepoužívám GNU Fortran a nepotřebuju v něm OOP, to je docela rozdíl.

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Traits ve Fortranu
« Odpověď #36 kdy: 10. 09. 2022, 22:00:23 »
něco jako rustí std::io::Read nebo io.Reader (Go)
K tomuto jsem zapomněl dodat, že zrovna pro read/write Fortran plnohodnotné “traity” má.

mikrom

  • ****
  • 321
    • Zobrazit profil
    • E-mail
Re:Traits ve Fortranu
« Odpověď #37 kdy: 11. 09. 2022, 00:00:21 »
Este som tie kvaterniony trochu zmenil, teraz nepouzivam overloading assignemt operatora = aby som naplnil kvaternion z pola
a = (/1., 2., 3., 4./)
ale vytvaram ho à la OOP takto:
a = Quaternion(1., 2., 3., 4.)
Takze modul mi sluzi ako class pre kvaternion, dodal som tam aj metodu print ktora sa pouzica tymto sposobom
a%print

quaternions_class.f95
Kód: [Vybrat]
module my_quaternions
  type :: Quaternion
    real :: x, y, z, t
    contains
      procedure :: print => print_quaternion
  end type quaternion

  interface operator(+)
    module procedure add_quaternions
  end interface

  interface operator(-)
    module procedure substract_quaternions
  end interface

  interface operator(*)
    module procedure hamilton_product
  end interface 

contains
  subroutine print_quaternion(this)
    class(Quaternion), intent(in) :: this
    write (*, 10) '(', this%x, ', ', this%y, ', ', this%z, ', ', this%t, ')'
    write (*,*)
    10 format(a, f8.2, a, f8.2, a, f8.2, a, f8.2, a)
  end subroutine print_quaternion

  function add_quaternions(a, b) result(c)
    type(Quaternion), intent(in) :: a
    type(Quaternion), intent(in) :: b
    type(quaternion) :: c
    c%x = a%x + b%x
    c%y = a%y + b%y
    c%z = a%z + b%z
    c%t = a%t + b%t
  end function add_quaternions
 
  function substract_quaternions(a, b) result(c)
    type(quaternion), intent(in) :: a, b
    type(quaternion) :: c
    c%x = a%x - b%x
    c%y = a%y - b%y
    c%z = a%z - b%z
    c%t = a%t - b%t
  end function substract_quaternions

  function hamilton_product(a, b) result(c)
    type(quaternion), intent(in) :: a, b
    type(quaternion) :: c
    c%x = a%x*b%x - a%y*b%y - a%z*b%z - a%t*b%t
    c%y = a%x*b%y + a%y*b%x + a%z*b%t - a%t*b%z
    c%z = a%x*b%z - a%y*b%t + a%z*b%x - a%t*b%y
    c%t = a%x*b%t + a%y*b%z - a%z*b%y + a%t*b%x
  end function hamilton_product

end module my_quaternions

program quaternions
  use my_quaternions
   
  type(Quaternion) :: a, b, c
  b = Quaternion(1., 2., 3., 4.)
  a = Quaternion(5., 6., 7., 8.)
  write(*, '(a)', advance="no") 'a = '
  call a%print()
  write(*, '(a)', advance="no") 'b = '
  call b%print()
 
  write (*,'(a)') 'c = a + b'
  c = a + b
  write(*, '(a)', advance="no") 'c = '
  call c%print

  write (*,'(a)') 'c = a - b'
  c = a - b
  call c%print

  write (*,'(a)') 'c = a * b'
  c = a * b
  call c%print
end program quaternions

Output:
Kód: [Vybrat]
$ gfortran quaternions_class.f95 -o quaternions_class
$ ./quaternions_class
a = (    5.00,     6.00,     7.00,     8.00)

b = (    1.00,     2.00,     3.00,     4.00)

c = a + b
c = (    6.00,     8.00,    10.00,    12.00)

c = a - b
(    4.00,     4.00,     4.00,     4.00)

c = a * b
(  -60.00,    20.00,   -18.00,    32.00)
« Poslední změna: 11. 09. 2022, 00:01:55 od mikrom »

mikrom

  • ****
  • 321
    • Zobrazit profil
    • E-mail
Re:Traits ve Fortranu
« Odpověď #38 kdy: 11. 09. 2022, 00:09:22 »
... viz co psal Ink. Moduly jsou jen jmenné prostory ...
Never nikomu, kym si to sam neoveris. Nie su to len name spaces - nainstaluj si gfortran a pozri si moj predosly priklad quaternions_class.f95. Modul tu robi taku istu pracu ako class a ma aj metodu print.

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Traits ve Fortranu
« Odpověď #39 kdy: 11. 09. 2022, 00:25:31 »
... viz co psal Ink. Moduly jsou jen jmenné prostory ...
Never nikomu, kym si to sam neoveris.
Dobrá rada, ale vzhledem k tomu, že znám Fortran i ostatní věci, o kterých Ink psal, můžu z fleku říct, že on má pravdu a ty se ukrutně pleteš.

Jo a v tom příkladu chybí právě ty “generic bindings” aka traity.

Re:Traits ve Fortranu
« Odpověď #40 kdy: 11. 09. 2022, 08:20:48 »
Tak nestíhám zdejší diskuzi a nechci se tedy klonit na žádnou stranu. Podle mne je OOP i ve Fortranu, pokud se používá jen v nějakých částech aplikace, akceptovatelné. Možná poslouží i na nějaký převod původně OOP designu z C++ do Fortranu. Ale moduly jak ukazuje mikrom jsou dobrá cesta. Tak kéž by aspoň lidi ve Fortranu psali jako mikrom :D. Za každého Fortranistu jsem rád. Jinak co se týká teorie Idris má většinou pravdu. Proč se s ním hádat  ;)

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Traits ve Fortranu
« Odpověď #41 kdy: 11. 09. 2022, 08:27:52 »
moduly jsou dobrá cesta
To tady nikdo nerozporuje, a týká se to asi všech jazyků.

A ano, buďme rádi za každého fortranistu, naprostý souhlas :)

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Traits ve Fortranu
« Odpověď #42 kdy: 11. 09. 2022, 09:55:37 »
Podle mne je OOP i ve Fortranu, pokud se používá jen v nějakých částech aplikace, akceptovatelné. Možná poslouží i na nějaký převod původně OOP designu z C++ do Fortranu.
Taky souhlas (když se používá rozumně). Ono v době přidání OOP do Fortranu zrovna letěl styl Java, bylo do dávno před (typovými systémy) Rustu, Julie či Go.

BTW co se mi z nových návrhů hodně líbí jsou šablony: https://everythingfunctional.wordpress.com/2022/07/24/the-state-of-fortran-generics/
Trochu se tváří jako ty v C++, ale s těmi omezeními (restriction) to bude super, pokud to takto projde. Kdo má furt používat m4, že?

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Traits ve Fortranu
« Odpověď #43 kdy: 11. 09. 2022, 09:57:14 »
ja bych si furt myslel, ze na numericke pocitani ol'good fortran
Ono to tak většinou je. Ostatně, jak jednou napsal zdejší plodný autor p. Tišnovský, Fortran je v podstatě jen DSL.

mikrom

  • ****
  • 321
    • Zobrazit profil
    • E-mail
Re:Traits ve Fortranu
« Odpověď #44 kdy: 11. 09. 2022, 11:25:10 »
... viz co psal Ink. Moduly jsou jen jmenné prostory ...
Never nikomu, kym si to sam neoveris.
Dobrá rada, ale vzhledem k tomu, že znám Fortran i ostatní věci, o kterých Ink psal, můžu z fleku říct, že on má pravdu a ty se ukrutně pleteš.
Zial neni to tak, dajme k tomu maly dokaz sporom  ;)
Nech teda su moduly name spaces. Potom ale, ked mam 2 rozne moduly, ktore obsahuju premennu s rovnakym menom, viem jej pouzitie rozlisit na zaklade mena modulu, t.j. takto:
Kód: [Vybrat]
module MA
    character(20) :: foo = 'foo from module A'
end module MA

module MB
    character(20) :: foo = 'foo from module B'
end module MB

program namespaces
    use MA
    use MB
    write(*,*) MA%foo
    write(*,*) MB%foo
end program namespaces
Ked sa vsak pokusim skompilovat to dostanem chybu
Kód: [Vybrat]
$ gfortran namespaces.f95 -o namespaces
namespaces.f95:12:17:

     write(*,*) MA%foo
                 1
Error: Symbol at (1) is not appropriate for an expression
namespaces.f95:13:17:

     write(*,*) MB%foo
                 1
Error: Symbol at (1) is not appropriate for an expression
 
Takuto chybu dostanem aj ked namiesto % pouzijem . alebo => atd.
To znamena, ze na zaklade mena modulu sa neda rozlisit, z ktoreho modulu rovnomenna premenna je.
Z toho vyplyva, ze moduly nie su menne priestory a ty nemas pravdu  8)

Jinak co se týká teorie Idris má většinou pravdu. Proč se s ním hádat  ;)
Ako som hore ukazal - je mi luto ale tentoraz pravdu nema.
Idris nam tu sice dava sebavedome a silne tvrdenia a po teoretickej stranke ma toho iste velmi vela precitane. Ale pripada mi to ako ked studuje v matematike definicie a vety bez praktickych cviceni. Moze sice ostatnych ohurovat ake je v tom eso, ale hlbsie pochopenie prichadza az pri rieseni praktickych uloh.

Moduly vo fortrane nie su namespaces. Fortran nema name spaces.
Namespaces si ale mozes v moduloch vytvorit pomocou derived data types a to takto:
Kód: [Vybrat]
module MA
    type MA_T
        character(20) :: foo = 'foo from module A'
    end type

    type(MA_T) :: A
end module MA

module MB
    type MB_T
        character(20) :: foo = 'foo from module B'
    end type

    type(MB_T) :: B
end module MB

program namespaces
    use MA
    use MB
    write(*,*) A%foo
    write(*,*) B%foo
end program namespaces

Output:
Kód: [Vybrat]
$ gfortran namespaces.f95 -o namespaces
$ ./namespaces
 foo from module A
 foo from module B