\subsection{User-defined distributions file}
\label{userdefined}

It is possible to add distributions to the program. These new distributions are defined and found in a user-defined distribution file. The program takes the filename of the file as a command line parameter. It's possible to use a unique distribution file in every model, or to use only one user-defined distribution file. The file must be a Fortran 90 source file named `user\_dist.f90'. It must contain a valid Fortran module named `user\_dist'. A user-defined distribution consists of two parts. The first one is an introductory line at the beginning of the file and the second part are the Fortran subroutines and functions in the file. One file can hold multiple user-defined distributions. The user-defined distribution file is compiled with the rest of the Fortran modules.

When the user wants to add an own distribution, the following steps are needed:
\begin{enumerate}
\item Decide a name for the distribution. The name must begin with `user\_'.
\item Add a definition line in the beginning of user-distribution file.
\item Add a subroutine user\_name\_freq() into the user-distribution module. The parameters depend on the parameters of the distribution.
\item If the distribution could be used as a proposal distribution, add a subroutine user\_name\_gen() into the user-distribution module. 
\end{enumerate}

NOTE: Both user\_name\_gen() and user\_name\_freq() need to be subroutines. They cannot be functions.

The file needs to be in following format:

\begin{verbatim}
Definition lines

  MODULE user_dist
    IMPLICIT NONE
      CONTAINS
      
      Subroutines and functions
      
  END MODULE user_dist
\end{verbatim}

\subsubsection{Definition lines}

The program reads the definition lines at the beginning of the user-distribution file and creates a distribution objects into its data structures. The program assumes that the subroutines are present and in the same format as the definitions.

NOTE: The definitions need to be at the start of the file. No empty lines, comments, or any other lines are allowed before them.

Since the module is compiled, the definitions need to start with Fortran comment mark `!'. Should you want to add Fortran comments to the beginning of the module, add an empty line after the last definition and begin the comment from the next line after the empty line.

\textbf{The definition line has the following syntax:}
\begin{verbatim}
! name param_count types gen_present
\end{verbatim}

Where 
\begin{itemize}
\item name is the name of the distribution
\item `param\_count' is the number of distribution's parameters
\item `types' contain as many types as param\_count suggests
\item each type is either INTEGER or REAL
\item gen\_present is .TRUE. if there is a subroutine that generates proposals from the distribution, .FALSE. otherwise.
\end{itemize}

NOTE: `param\_count' is the number of the distribution's parameters, not the number of the subroutine's parameters.

The name of the distribution needs to start with `user\_'. For example a valid name would be `user\_gamma'. This function could then be used in the model and proposal distribution file with the name `user\_gamma'.

The parameters count is the amount of the parameters of the distribution. For example for the Normal distribution the count would be two, for the Poisson distribution it would be one. Note that the program assumes that a generation subroutine has one more parameter than the `param\_count' and that the frequency function has two more parameters. These extra parameters are the point for which the frequency is calculated and the return value parameter.

`types' is a list of parameter types. Should the parameter count be two for the distribution, you need to define the types of both.

The last field `gen\_present' tells if distribution has a generation function defined in the file. The generation function is required for generating proposals from the distribution. It is optional (the distribution can be used for variables that are not updated) but the frequency function is always required.

\textbf{An example:} 
\begin{verbatim}
! user_points 1 INTEGER .FALSE.
\end{verbatim}

This distribution could be used with the name `user\_points' in the input files. It has only one parameter which is an integer type. It does not have a generation function, so it can not be used as a proposal distribution. It could be used in the model file in this manner:

\textbf{An example:}
\begin{verbatim}
    INTEGER alpha ...
    INTEGER beta ~ user_points(alpha)
\end{verbatim}

NOTE: The return value isn't defined. It's up to the user to use correct distributions for integer and real variables.

\subsubsection{Subroutines}

The parameters of user\_name\_freq and user\_name\_gen subroutines depend on the parameters of the distribution: the subroutine implementing the frequency function has two additional parameters (the point on which the frequency is calculated and the result) and the subroutine generating the proposals has one additional parameter (the array which to generate proposals to).

Should a distribution be defined as `! user\_normal 2 REAL REAL .TRUE.' in the beginning of the file, the frequency and generation functions need to be in following format:

\begin{verbatim}
SUBROUTINE user_normal_freq(param1, param2, point, result)
! param1 and param2 are real type
  ...
END SUBROUTINE user_normal_freq

SUBROUTINE user_normal_gen(param1, param2, result)
! param1 and param2 are real type
  ...
END SUBROUTINE user_normal_gen
\end{verbatim}

NOTE: The generation subroutine is assumed to generate an array full of proposals.

NOTE: All user-defined subroutines and functions that user REAL variables must define them as REAL (KIND=SELECTED\_REAL\_KIND(8,0)) for compliance with NAG.

NOTE: It is possible to program the subroutines to use existing NAG subroutines.

NOTE: You can add other functions and subroutines to the file and use them in the required subroutines.

\textbf{An example:}
\begin{verbatim}
! user_gamma 2 REAL REAL .TRUE.

MODULE user_dist
  IMPLICIT NONE

  CONTAINS

  SUBROUTINE user_gamma_freq(alpha, lambda, point, freq)
  
    ...
    
  END SUBROUTINE user_gamma_freq
  
  
  SUBROUTINE user_gamma_gen(param1, param2, buffer)
  
    ...
    
  END SUBROUTINE user_gamma_gen
  
END MODULE user_dist
\end{verbatim}
