Constant's value given by a non-intrinsic function - function

In Fortran, is there a way to initialize my named constant at compilation time using a function of other constants, other than the intrinsic functions?
I want to calculate a value using my own function and then use this value to declare the size of an array, such as in my attempt below.
integer function factorial(n)
implicit none
integer, intent(in) :: n
integer :: i, ans
ans=1
do i=1,n
ans=ans*i
end do
factorial = ans
end function Factorial
integer function binomial(n,k)
implicit none
integer, intent(in) :: n, k
integer :: factorial
binomial = Factorial(n)/factorial(n-k)/factorial(k)
end function binomial
program main
implicit none
integer, parameter :: m=10, n=3
integer :: binomial
integer, parameter :: sz=binomial(m,n)
complex, dimension(sz) :: hamiltonian
...
end program main
Or do I have have to calculate this value myself and write it explicitly in the code ?

As you seem to know, the Fortran standard prohibits calculations, at compile time, beyond what intrinsic routines are capable of. If you really must make those calculations at compile time then a hack like this might appeal to you:
INTEGER, DIMENSION(20), PARAMETER :: ints = [1,2,3,4,5,6,7,8,9,10, &
11,12,13,14,15,16,17,18,19,20]
INTEGER, PARAMETER :: m=10, n=3
INTEGER, PARAMETER :: sz = PRODUCT(ints(1:m))/PRODUCT(ints(1:m-n))/&
PRODUCT(ints(1:n))
COMPLEX, DIMENSION(sz) :: hamiltonian
This compiles, and executes, correctly. If you confine yourself to 64-bit integers the array ints doesn't need to go larger than 20.
Oh, in passing, don't use size as the name of a parameter, it's already the name of a useful intrinsic function.
Then again, you could just compute the factorials yourself and write:
INTEGER, DIMENSION(20), PARAMETER :: factorial = [1,2,6,24,...]
INTEGER, PARAMETER :: m=10, n=3
INTEGER, PARAMETER :: sz = factorial(m)/factorial(m-n)/factorial(n)
COMPLEX, DIMENSION(sz) :: hamiltonian
and be done with it.

Related

Haskell Complex Function Types

A Haskell function I am struggling with has the following type
func1 :: (Integer -> Integer -> Integer) -> Integer -> Integer -> Integer
I am unsure of how to handle the Parenthesis piece in the actual implementation. I know that a function should be passed into the input in this scenario.
(Integer -> Integer -> Integer)
When a function is passed to you as a parameter, the only useful thing you can do with it in the end is to call it. That's what functions are for. That's what they do.
For example, in this case it may look something like this:
func1 :: (Integer -> Integer -> Integer) -> Integer -> Integer -> Integer
func1 f a b = f (a*2) (b+5)
Here, the first parameter is named f and it's a function that takes two parameters, both Integer, and returns another Integer - that much is conveyed by its type (Integer -> Integer -> Integer).
The second and third parameters are named a and b respectively, and they're both Integer.
The body of function func1 consists of calling its function-parameter f, passing it (a*2) and (b+5) as parameters.

Difference in Function typing in Haskell

I've been playing around with basic functions in Haskell, and am a little confused with the difference between the following type declarations for the function f
f :: Integer -> Integer
versus
f :: Integral n => n -> n
So far, I've treated both of these as identical, but I'm sure this isn't true. What is the difference?
Edit: As a response to the first answer, I wanna propose a similar example which more is along the lines of the question I hold.
Consider the following declarations
f :: Num n => n -> n
or
f :: Num -> Num
What functionality does each offer?
Let's rename:
f :: Integer -> Integer
g :: (Integral n) => n -> n
I like to follow a fairly common practice of adding parentheses to the constraint section of the signature. It helps it stand out as different.
f :: Integer -> Integer is simple, it takes an integer and returns another integer.
As for g :: (Integral n) => n -> n: Integral is not a type itself, rather it's more like a predicate. Some types are Integral, others aren't. For example, Int is an Integral type, Double is not.
Here n is a type variable, and it can refer to any type. (Integral n) is a constraint on the type variable, which restricts what types it can refer to. So you could read it like this:
g takes a value of any type n and returns a value of that same type, provided that it is an Integral type.
If we examine the Integral typeclass:
ghci> :info Integral
class (Real a, Enum a) => Integral a where
quot :: a -> a -> a
rem :: a -> a -> a
div :: a -> a -> a
mod :: a -> a -> a
quotRem :: a -> a -> (a, a)
divMod :: a -> a -> (a, a)
toInteger :: a -> Integer
{-# MINIMAL quotRem, toInteger #-}
-- Defined in ‘GHC.Real’
instance Integral Word -- Defined in ‘GHC.Real’
instance Integral Integer -- Defined in ‘GHC.Real’
instance Integral Int -- Defined in ‘GHC.Real’
We can see 3 builtin types which are Integral. Which means that g simultaneously has three different types, depending on how it is used.
g :: Word -> Word
g :: Integer -> Integer
g :: Int -> Int
(And if you define another Integral type in the future, g will automatically work with that as well)
The Word -> Word variant is a good example, since Words cannot be negative. g, when given a positive machine-sized number, returns another positive machine-sized number, whereas f could return any integer, including negative ones or gigantic ones.
Integral is a rather specific class. It's easier to see with Num, which has fewer methods and thus can represent more types:
h :: (Num a) => a -> a
This is also a generalization of f, that is, you could use h where something with f's type is expected. But h can also take a complex number, and it would then return a complex number.
The key with signatures like g's and h's is that they work on multiple types, as long as the return type is the same as the input type.
According to this link the standard instances of the Integral type class are Integer and Int. Integer is a primitive type, and it acts like an unbounded mathematical integer. So given:
f :: Integral n => n -> n
n could be Int or Integer or any "custom" type that you define that is an instance of Integral. The use of type classes allows for type polymorphism.
f :: Num -> Num WILL NOT COMPILE because Num is not a type. Num has kind * -> Constraint and is thus a type constructor whereas f requires an ordinary type or monotype which has kind *, such as Int or Integer (also known as type system primitives). See the haskell wiki for a brief reference/jumping off point about kinds. Haskell has a rich type system with higher-order types, if used correctly it can be an extremely powerful tool i.e. type polymorphism.
f :: Integer -> Integer
f is a function from arbitrary sized integers to arbitrary sized integers.
f' :: Integral n => n -> n
f' is a polymorphic function from type n to type n. Any type n that is member of the class Integral is allowed. Examples for types in Integral are Integer and Int (the integer type with fixed precision).
f'' :: Num n => n -> n
f'' is also a polymorphic function, but this time for class Num. Num is a more generic number type that has more members than Integral, but all types in Integral are also in contained in Num. For f'' n can also be Double.
TL;DR
f :: Integer -> Integer works for one type: Integer.
f :: Integral n => n -> n works for Integer, Int, Word, Int32, Int64, Word8, and any arbitrary user-defined types that implement the Integral type class.
That's the short version. If you only care about one type, it's easier to type-check and more efficient to execute if you specify that one type. If you want multiple types, then the second way is probably the way to do.

Fortran function returning unallocated array causes segmentation fault

I'm struggling with some Modern Fortran wrappers to some MPI scatter/gather routines. I am trying to have a wrapper interface that only has an array on input and returns the MPI-operated result on output, for several derived types, doing something like this:
type(mytype), allocatable :: chunk(:),whole(:)
! [...] chunk descends from previous parts of the code
! Get global array
whole = gatherv(array=chunk,receiver_node=cpuid)
I'm doing this using functions that return allocatable arrays. However, I'm getting segmentation fault on both gcc 6.2.0 and gcc 7.1.0 whenever I return a non-allocated result.
The reason I need a non-allocated result is that sometimes I need to gather the whole array only on a specified CPU, so I don't want to waste memory on all other nodes: the receiver node returns an allocated array with the data, and all other nodes receive an empty and deallocated array.
This is sample code that reproduces the issue:
program test_allocatable_fun
implicit none
integer, allocatable :: my_array(:)
integer :: n
n = 3; my_array = unallocated_array(n); print *, 'n=',n,' allocated(array)=',allocated(my_array)
n =-3; my_array = unallocated_array(n); print *, 'n=',n,' allocated(array)=',allocated(my_array)
n = 5; my_array = unallocated_array(n); print *, 'n=',n,' allocated(array)=',allocated(my_array)
n = 0; my_array = unallocated_array(n); print *, 'n=',n,' allocated(array)=',allocated(my_array)
return
contains
function unallocated_array(n) result(array)
integer, intent(in) :: n
integer, allocatable :: array(:)
integer :: j
if (n>0) then
allocate(array(n))
array(:) = [(j,j=1,n)]
else
if (allocated(array)) deallocate(array)
end if
end function unallocated_array
end program test_allocatable_fun
The segmentation fault happens at the assignment line, i.e.:
my_array = unallocated_array(n)
Has any of you had the same issue before? Or, am I violating anything in the standard? I can't see why a function returning an allocatable array should be forced to have the return value allocated. Isn't it the same as having an intent(out) dummy variable in a subroutine?
A function result is not the same as a dummy argument with the intent(out) attribute. It differs in a significant way here in that a non-pointer function result must always be defined when execution of the function terminates. This is covered by Fortran 2008 12.6.2.2 p4.
It is necessary, but not sufficient, for an allocatable function result (any object) to be allocated to be defined.
To some extent you can consider this in the way that a function result is always referenced (otherwise the function wouldn't be executed). An actual argument not defined may also not be referenced, but such referencing wouldn't be "automatic".
As mentioned in comments, the function result may be allocated to be an array of size zero. Zero-sized arrays are always of defined value.
You can see some comparison of zero-sized arrays and not-allocated arrays in this other question.
I suspect any allocatable array in a main program contains data of a global nature. I usually put such variables in a module. This way this variable does not need to be passed around and can be allocated and deallocated in the main program, subroutines, and/or functions.
Since the array is the only return value, I changed it to a subroutine. How does this work for you? P.S. 'implicit none' should be in every module, program, function, and subroutine.
module fun
implicit none
integer, allocatable :: my_array(:)
end module fun
program test_allocatable_fun
use fun
implicit none
integer :: n
n = 3; call unallocated_array(n); print *, 'n=',n,' allocated(array)=',allocated(my_array)
n =-3; call unallocated_array(n); print *, 'n=',n,' allocated(array)=',allocated(my_array)
n = 5; call unallocated_array(n); print *, 'n=',n,' allocated(array)=',allocated(my_array)
n = 0; call unallocated_array(n); print *, 'n=',n,' allocated(array)=',allocated(my_array)
return
contains
subroutine unallocated_array(n)
use fun
implicit none
integer, intent(in) :: n
integer :: j
if (n>0) then
allocate(my_array(n))
my_array(:) = [(j,j=1,n)]
else
if (allocated(my_array)) deallocate(my_array)
end if
end subroutine unallocated_array
end program test_allocatable_fun

User defined constructor for Fortran derived type instance

This is my second question related to Fortran (I use C++, so forgive me my way of thinking).
I want to use OOP, to say, derived type in Fortran whenever appropriate.
In C++, you can use user defined constructor such as https://msdn.microsoft.com/en-us/library/s16xw1a8.aspx
Here in Fortran, things are different.
The first thing I tried is from here:
https://www.ibm.com/developerworks/community/blogs/b10932b4-0edd-4e61-89f2-6e478ccba9aa/entry/object_oriented_fortran_user_defined_constructors2?lang=en
Link is broken, so I pasted it here:
module m
!...
interface base
module procedure new_base
end interface
contains
!...
function new_base(I)
integer, intent(in) :: I
type(base) new_base
allocate(new_base%data(I))
new_base%data = I
end function
!...
end module
The interface above defines a user-defined constructor for type base. It is used in a similar way to a structure constructor. It can even take argument keywords.
Then I found some other ways to do it.
Here I listed a few approaches seemly to work but I only tested the first and second:
generic interface with the same name as the derived type they're supposed to construct, see link above;
use type-bound procedure (This is not even a "traditional" constructor)
MODULE mymod
TYPE mytype
Private
INTEGER :: x
CONTAINS
PROCEDURE, PASS :: init
END TYPE
CONTAINS
SUBROUTINE init(this, i)
CLASS(mytype), INTENT(OUT) :: this
INTEGER, INTENT(IN) :: i
write(*,*) this%x
IF(i > 0) THEN
this%x = 1
ELSE
this%x = 2
END IF
write(*,*) this%x
END SUBROUTINE init
END
PROGRAM test
USE mymod
TYPE(mytype) :: y
CALL y%init(1)
END PROGRAM
use Static Constructors or Structure Constructors (http://www.lahey.com/docs/lfenthelp/NLMOvUsInvConst.htm)
But it appears that this is NOT for general Fortran http://www.lahey.com/docs/lfenthelp/NLMGSWhatIs.htm
So I haven't understood well enough what is most preferred and flexible approach to initialize/construct a derived type in practice, especially when I use nested derived type in development. I hope I can organize this topic with some help.
OK, so I will assume you read well the answers at How to override a structure constructor in fortran and I will answer your problem raised in the comment. There is not enough place in the comment to answer that.
You can also make constructors in Fortran which accept variable number of arguments.
It is even possible with the default structure constructors which every derived type has by default. If you default-initialize a component, it is optional in the constructor. The same holds for allocatable and pointer components.
For type
type t1
integer :: i = 1
integer, pointer :: ip => null()
integer, allocatable :: ap
end type
you can call the default constructor just as
instance = t1()
and it is perfectly legal, i will be 1, ip will point to null and ap will not be allocated.
Or you can call it as
instance = t1(ap=5)
and the ap component will be allocated and set to 5 and the other components will be left default.
You can achieve similar stuff with user defined constructors just by making the arguments optional.
function t1_user(ap, i) result(res)
type(t1) :: res
integer, allocatable :: ap !this argument MUST be passed,
! it does not have to be allocated
integer, optional :: i ! this argument is optional
if (present(i)) then
...
end if
end function
any type-bound procedure can of-course also have optional arguments.
As for the nested types, that is really best done with constructors as functions, no matter if they are default or user defined:
type inner
real :: x, y
end type
type outer
type(inner), allocatable :: in
real :: z
end type
instance1 = outer(inner(1., 2.), 3.)
instance2 = outer(z=4.)

Procedure with assumed-shape dummy argument must have an explicit interface [duplicate]

This question already has an answer here:
Module calling an external procedure with implicit interface
(1 answer)
Closed 5 years ago.
I am completely new to Fortran 90 and I am trying to understand how to pass an array to a function. I looked on the web and I could not find any clear and simple enough example, so I decided to post here.
I would like the function be able to work on an array of any length (the length of the array should not be one of the parameters of the functions).
I tried to write a simple example of a function that returns the sum of the elements of an array:
function mysum(arr)
implicit none
real, dimension(:), intent(in) :: arr
real :: mysum
integer :: i,arrsize
arrsize = size(arr)
mysum=0.0
do i=1,arrsize
mysum=mysum+arr(i)
enddo
end function mysum
program test
implicit none
real, dimension(4) :: a
real :: mysum,a_sum
call random_number(a)
print *,a
a_sum=mysum(a)
print *,a_sum
end program
When I try to compile, I get the following error:
array_test.f90:17.14:
real mysum,a_sum
1
Error: Procedure 'mysum' at (1) with assumed-shape dummy argument 'arr' must have an explicit interface
What is the problem with my program?
Assumed shape dummy arguments (those with (:)) require explicit interface to the procedure to be available at the call site. That means the calling code must know how exactly the subroutine header looks like. See also Module calling an external procedure with implicit interface
That explicit interface can be provided in several ways
1.
preferred - a module procedure
module procedures
implicit none
contains
function mysum(arr)
real, dimension(:), intent(in) :: arr
real :: mysum
integer :: i,arrsize
arrsize = size(arr)
mysum=0.0
do i=1,arrsize
mysum=mysum+arr(i)
enddo
end function mysum
end module
program test
use procedures
implicit none
!no mysum declared here, it comes from the module
...
end program
2.
internal procedure - only for short simple procedures or if the procedure needs access to the host's variables. Because of the access to the host variables it is error-prone.
program test
implicit none
!no a_sum declared here, it is visible below contains
...
contains
function mysum(arr)
!implicit none inherited from the program
real, dimension(:), intent(in) :: arr
real :: mysum
integer :: i,arrsize
arrsize = size(arr)
mysum=0.0
do i=1,arrsize
mysum=mysum+arr(i)
enddo
end function mysum
end program
3.
interface block - not recommended at all, you should have some particular reason to use it
function mysum(arr)
! removed to save space
end function mysum
program test
implicit none
interface
function mysum(arr)
real, dimension(:), intent(in) :: arr
real :: mysum
end function
end interface
!no mysum declared there
!it is declared in the interface block
...
end program