j3-fortran / fortran_proposals

Proposals for the Fortran Standard Committee
175 stars 14 forks source link

Extending the functionality of `conjg()` to arguments of type `real` and `integer` #313

Open shahmoradi opened 10 months ago

shahmoradi commented 10 months ago

The intrinsic conjg() accepts only arguments of type complex. However, there are numerous instances in linear algebra and machine learning where a generic algorithm must work for data types of real and complex (and possibly integer). This limited functionality of the current conjg() leads to the mushroom-like growth of non-standard preprocessor macro definitions in such generic algorithms. As an example, this conjg() functionality extension could reduce the size of the original BLAS/LAPACK codebase to almost half (by removing separate duplicated routines for complex and real data types (along with perhaps a few other algorithmic changes)). The proposed extension would lead to the following trivial behavior: conjg(x) := x if x is of type integer or real.

klausler commented 10 months ago

You can extend generic intrinsic functions to handle more types.

module m
  interface conjg
    module procedure rconjg
    module procedure iconjg
  end interface
 contains
  real elemental function rconjg(x)
    real, intent(in) :: x
    rconjg = x
  end
  integer elemental function iconjg(x)
    integer, intent(in) :: x
    iconjg = x
  end
end

use m
print *, conjg(1.), conjg(2), conjg((3.,4.))
end
shahmoradi commented 10 months ago

Why did the standard introduce conjg() in the first place when it can be so easily implemented as a user-defined function?

module m
 contains
  complex elemental function conjg(x)
    complex, intent(in) :: x
    conjg = cmplx(real(x), -aimag(x))
  end
end

print *, conjg((3.,4.))

block
    use m
    print *, conjg((3.,4.))
end block

end
klausler commented 10 months ago

CONJG dates back to the introduction of complex data in FORTRAN II, ca. 1957. User defined generic interfaces came along 33 years later in Fortran 90.