@c automatically generated by `make_texi.pl'

@c -------------------------------------
@c top.dh
@c

@node TOP
@top   UNU.RAN -- Universal Non-Uniform RANdom number generators

@menu
* Intro:: Introduction
* Examples:: Examples
* StringAPI:: String Interface
* Distribution_objects:: Handling distribution objects
* Methods:: Methods for generating non-uniform random variates
* URNG:: Using uniform random number generators
* Stddist:: UNU.RAN Library of standard distributions
* Error_Debug:: Error handling and Debugging
* Testing:: Testing
* Misc:: Miscelleanous
* RVG:: A Short Introduction to Random Variate Generation
* Glossary:: Glossary
* Bibliography:: Bibliography
* FIndex:: Function Index
@end menu


@ifinfo
@noindent
This is the online-documentation of UNU.RAN.@*
Version: @value{VERSION}@*
Date: @value{UPDATED}
@end ifinfo


UNU.RAN (Universal Non-Uniform RAndom Number generator) is
a collection of algorithms for generating non-uniform
pseudorandom variates as a library of C functions
designed and implemented by the ARVAG (Automatic Random VAriate
Generation) project group in Vienna, and
released under the GNU Public License (GPL).
It is especially designed for such situations where

@itemize @minus
@item a non-standard distribution or a truncated distribution is
needed.

@item experiments with different types of distributions are made.

@item random variates for variance reduction techniques are used.

@item fast generators of predictable quality are necessary.

@end itemize

Of course it is also well suited for standard distributions.
However due to its more sophisticated programming interface it
might not be as easy to use if you only look for a generator for
the standard normal distribution. (Although UNU.RAN provides
generators that are superior in many aspects to those found in
quite a number of other libraries.)



UNU.RAN implements several methods for generating random numbers.
The choice depends primary on the information about the
distribution can be provided and -- if the user is familar with
the different methods -- on the preferences of the user.

The design goals of UNU.RAN are to provide @emph{reliable},
@emph{portable} and @emph{robust} (as far as this is possible)
functions with a consisent and easy to use interface. It is
suitable for all situation where experiments with different
distributions including non-standard distributions.
For example it is no problem to replace the normal distribution
by an empirical distribution in a model.

Since originally designed as a library for so called black-box or
universal algorithms its interface is different from other
libraries. (Nevertheless it also contains special generators for
standard distributions.) It does not provide subroutines for
random variate generation for particular distributions. Instead
it uses an object-oriented interface. Distributions and
generators are treated as independent objects. This approach
allows one not only to have different methods for generating
non-uniform random variates. It is also possible to choose the
method which is optimal for a given situation (e.g. speed, quality
of random numbers, using for variance reduction techniques,
etc.). It also allows to sample from non-standard distribution or
even from distributions that arise in a model and can only be
computed in a complicated subroutine.

Sampling from a particular distribution requires the following steps:

@enumerate
@item
Create a distribution object.
(Objects for standard distributions are available in the library)

@item
Choose a method.

@item
Initialize the generator, i.e., create the generator object.
If the choosen method is not suitable for the given distribution
(or if the distribution object contains too little information
about the distribution) the initialization routine fails and
produces an error message. Thus the generator object does
(probably) not produce false results (random variates of a
different distribution).

@item
Use this generator object to sample from the distribution.

@end enumerate

There are four types of objects that can be manipulated
independently:

@itemize @bullet

@item
@strong{Distribution objects:}
hold all information about the random variates that should be
generated. The following types of distributions are available:

@itemize @minus
@item
Continuous and Discrete distributions
@item
Empirical distributions
@item
Multivariate distributions
@end itemize

Of course a library of standard distributions is included
(and these can be further modified to get, e.g., truncated
distributions). Moreover the library provides subroutines to
build almost arbitrary distributions.

@item
@strong{Generator objects:}
hold the generators for the given distributions. It is possible
to build independent generator objects for the same distribution
object which might use the same or different methods for
generation. (If the choosen method is not suitable for the given
method, a @code{NULL} pointer is returned in the initialization step).

@item
@strong{Parameter objects:}
Each transformation method requires several parameters to adjust
the generator to a given distribution. The parameter object holds
all this information. When created it contains all necessary
default settings. It is only used to create a generator object
and destroyed immediately. Altough there is no need to change
these parameters or even know about their existence for ``usual
distributions'', they allow a fine tuning of the generator to
work with distributions with some awkward properties. The library
provides all necessary functions to change these default
parameters.

@item
@strong{Uniform Random Number Generators:}
All generator objects need one (or more) streams of uniform
random numbers that are transformed into random variates of the
given distribution. These are given as pointers to appropriate
functions or structures (objects). Two generator objects may have
their own uniform random number generators or share a common
one. Any functions that produce uniform (pseudo-) random numbers
can be used. We suggest Otmar Lendl's PRNG library.

@end itemize



@c
@c end of top.dh
@c -------------------------------------
@c -------------------------------------
@c intro.dh
@c

@node Intro
@chapter   Introduction

@menu
* UsageDoc:: Usage of this document
* Installation:: Installation
* UsageLib:: Using the library
* Concepts:: Concepts of UNU.RAN
* Contact:: Contact the authors
@end menu


@c
@c end of intro.dh
@c -------------------------------------
@c -------------------------------------
@c intro.dh
@c

@node UsageDoc
@section   Usage of this document


We designed this document in a way such that one can
use UNU.RAN with reading as little as necessary.
Read @ref{Installation} for the instructions to
install the library.
@ref{Concepts,,Concepts of UNU.RAN},
discribes the basics of UNU.RAN.
It also has a short guideline for choosing an appropriate method.
In @ref{Examples} examples are given that can be copied and modified.
They also can be found in the directory @file{examples} in the
source tree.

Further information are given in consecutive chapters.
@ref{Distribution_objects,,Handling distribution objects},
describes how to create and manipulate distribution objects.
@ref{Stddist,,standard distributions},
describes predefined distribution objects that are ready to use.
@ref{Methods} describes the various methods in detail.
For each of possible distribution classes
(continuous, discrete, empirical, multivariate)
there exists a short overview section that can be used to choose an
appropriate method followed by sections that describe each of the
particular methods in detail.
These are merely for users with some knowledge about
the methods who want to change method-specific parameters and can
be ignored by others.

Abbreviations and explanation of some basic terms can be found in
@ref{Glossary}.


@c
@c end of intro.dh
@c -------------------------------------
@c -------------------------------------
@c installation.dh
@c

@node Installation
@section   Installation


UNU.RAN was developed on an Intel architecture under Linux with
the GNU C compiler but should compile and run on any computing
environment. It requires an ANSI compliant C compiler.

Below find the installation instructions for unices.


@subsubheading Uniform random number generator

UNU.RAN can be used with any uniform random number generator but (at the
moment) some features work best with Pierre L'Ecuyer's RngStreams library
(see @url{http://statmath.wu.ac.at/software/RngStreams/} for a
description and downloading.
For details on using uniform random number in UNU.RAN
see @ref{URNG,,Using uniform random number generators}.

Install the required libraries first.


@subsubheading UNU.RAN

@enumerate

@item First unzip and untar the package and change to the directory:

@example
tar zxvf unuran-@value{VERSION}.tar.gz
cd unuran-@value{VERSION}
@end example

@item Optional: Edit the file @file{src/unuran_config.h}

@item Run a configuration script:

@example
sh ./configure --prefix=<prefix>
@end example

@noindent
where @code{<prefix>} is the root of the installation tree.
When omitted @file{/usr/local} is used.

Use @code{./configure --help} to get a list of other options.
In particular the following flags are important:

@itemize @bullet
@item
Enable support for some external sources of uniform random
number generators
(@pxref{URNG,,Using uniform random number generators}):

@table @code
@item --with-urng-rngstream
URNG: use Pierre L'Ecuyer's RNGSTREAM library
[default=@code{no}]

@item --with-urng-prng
URNG: use Otmar Lendl's PRNG library
[default=@code{no}]

@item --with-urng-gsl
URNG: use random number generators from GNU Scientific Library
[default=@code{no}]

@item --with-urng-default
URNG: global default URNG (builtin|rngstream)
[default=@code{builtin}]
@end table

We strongly recommend to use RngStreams library:

@example
sh ./configure --with-urng-rngstream --with-urng-default=rngstream
@end example

@emph{Important:} You must install the respective libraries
@file{RngStreams}, @file{PRNG} and @file{GSL} before
@code{./configure} is executed.

@item
Also make a shared library:

@table @code
@item --enable-shared
build shared libraries  [default=@code{no}]
@end table

@item
The library provides the function @code{unur_gen_info} for
information about generator objects. This is intented for
using in interactive computing environments.
This feature can be enabled / disabled by means of the
configure flag

@table @code
@item --enable-info
INFO: provide function with information about
generator objects [default=@code{yes}]
@end table

@item
Enable support for deprecated UNU.RAN routines if you have
some problems with older application after upgrading the
library:

@table @code
@item --enable-deprecated
enable support for deprecated UNU.RAN routines
[default=@code{no}]
@end table

@item
Enable debugging tools:

@table @code
@item --enable-check-struct
Debug: check validity of pointers to structures
[default=@code{no}]

@item --enable-logging
Debug: print informations about generator into logfile
[default=no]
@end table
@end itemize


@item Compile and install the libray:

@example
make
make install
@end example

@noindent
Obviously @code{$(prefix)/include} and @code{$(prefix)/lib}
must be in the search path of your compiler. You can use environment
variables to add these directories to the search path. If you
are using the bash type (or add to your profile):

@example
export LIBRARY_PATH="<prefix>/lib"
export C_INCLURE_PATH="<prefix>/include"
@end example

@noindent
If you want to make a shared library, then making such
a library can be enabled using

@example
sh ./configure --enable-shared
@end example

@noindent
If you want to link against the shared library make sure that
it can be found when executing the binary that links to the
library. If it is not installed in the usual path, then the
easiest way is to set the @code{LD_LIBRARY_PATH} environment
variable. See any operating system documentation about shared
libraries for more information, such as the ld(1) and
ld.so(8) manual pages.

@item Documentation in various formats (PDF, HTML, info, plain
text) can be found in directory @file{doc}.

@item You can run some tests by

@example
make check
@end example

@noindent
However, some of these tests requires the usage of the PRNG or
RngStreams library and are only executed if these are installed
enabled by the corresponding configure flag.

An extended set of tests is run by

@example
make fullcheck
@end example

@noindent
However some of these might fail occasionally due to
roundoff errors or the mysteries of floating point arithmetic,
since we have used some extreme settings to test the library.

@end enumerate


@subsubheading Upgrading

@itemize @minus
@item @emph{Important:}

UNU.RAN now relies on some aspects of IEEE
754 compliant floating point arithmetic. In particular,
@code{1./0.} and @code{0./0.} must result in @code{infinity}
and @code{NaN} (not a number), respectively, and must not
cause a floating point exception.
For allmost all modern compting architecture this is implemented
in hardware. For others there should be a special compiler flag
to get this feature (e.g., @code{-MIEEE} on DEC alpha or
@code{-mp} for the Intel C complier).

@item Upgrading UNU.RAN from version 0.9.x or earlier:

With UNU.RAN version 1.0.x some of the macro definitions in
file @file{src/unuran_config.h} are moved into file
@file{config.h} and are set/controlled by the
@code{./configure} script.

Writting logging information into the logfile must now be
enabled when running the configure script:

@example
sh ./configure --enable-logging
@end example

@item Upgrading UNU.RAN from version 0.7.x or earlier:

With UNU.RAN version 0.8.0 the interface for changing
underlying distributions and running a reinitialization
routine has been simplified. The old routines can be compiled
into the library using the following configure flag:

@example
sh ./configure --enable-deprecated
@end example

@noindent
Notice: Using these deprecated routines is not supported any
more and this strong discouraged.

Wrapper functions for external sources of uniform random
numbers are now enabled by configure flags and not by macros
defined in file @file{src/unuran_config.h}.

The file @file{src/unuran_config.h} is not installed any
more. It is now only included when the library is compiled.
It should be removed from the global include path of the
compiler.

@end itemize



@c
@c end of installation.dh
@c -------------------------------------
@c -------------------------------------
@c intro.dh
@c

@node UsageLib
@section   Using the library



@subsubheading ANSI C Compliance

The library is written in ANSI C and is intended to conform to the
ANSI C standard.  It should be portable to any system with a
working ANSI C compiler.

The library does not rely on any non-ANSI extensions in the
interface it exports to the user.  Programs you write using UNU.RAN
can be ANSI compliant.  Extensions which can be used in a way
compatible with pure ANSI C are supported, however, via conditional
compilation.	 This allows the library to take advantage of compiler
extensions on those platforms which support them.

To avoid namespace conflicts all exported function names and
variables have the prefix @code{unur_}, while exported macros have
the prefix @code{UNUR_}.


@subsubheading Compiling and Linking

If you want to use the library you must include the UNU.RAN header
file

@example
#include <unuran.h>
@end example

@noindent
If you also need the test routines then also add

@example
#include <unuran_tests.h>
@end example

@noindent
If wrapper functions for external sources of uniform random number
generators are used, the corresponding header files must also be
included, e.g.,

@example
#include <unuran_urng_rngstream.h>
@end example

@noindent
If these header files are not installed on the standard search path
of your compiler you will also need to provide its location to the
preprocessor as a command line flag.	 The default location of the
@file{unuran.h} is @file{/usr/local/include}.  A typical compilation
command for a source file @file{app.c} with the GNU C compiler
@code{gcc} is,

@example
gcc -I/usr/local/include -c app.c
@end example

@noindent
This results in an object file @file{app.o}.	 The default include
path for @code{gcc} searches @file{/usr/local/include}
automatically so the @code{-I} option can be omitted when UNU.RAN is
installed in its default location.

The library is installed as a single file, @file{libunuran.a}.  A
shared version of the library is also installed on systems that
support shared libraries.  The default location of these files is
@file{/usr/local/lib}.  To link against the library you need to
specify the main library.  The following example shows how to link
an application with the library (and the the RNGSTREAMS library if you
decide to use this source of uniform pseudo-random numbers),

@example
gcc app.o -lunuran -lrngstreams -lm
@end example


@subsubheading Shared Libraries

To run a program linked with the shared version of the library it
may be necessary to define the shell variable
@code{LD_LIBRARY_PATH} to include the directory where the library
is installed.  For example,

@example
LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
@end example

@noindent
To compile a statically linked version of the program instead, use the
@code{-static} flag in @code{gcc},

@example
gcc -static app.o -lunuran -lrngstreams -lm
@end example


@subsubheading Compatibility with C++

The library header files automatically define functions to have
@code{extern "C"} linkage when included in C++ programs.




@c
@c end of intro.dh
@c -------------------------------------
@c -------------------------------------
@c intro.dh
@c

@node Concepts
@section   Concepts of UNU.RAN


UNU.RAN is a C library for generating non-uniformly distributed
random variates. Its emphasis is on the generation of non-standard
distribution and on streams of random variates of special purposes.
It is designed to provide a consistent tool to
sample from distributions with various properties.
Since there is no universal method that fits for all situations,
various methods for sampling are implemented.

UNU.RAN solves this complex task by means of an object oriented
programming interface. Three basic objects are used:

@itemize @bullet
@item distribution object @code{UNUR_DISTR}@*
Hold all information about the random variates that should be
generated.

@item generator object @code{UNUR_GEN}@*
Hold the generators for the given distributions.
Two generator objects are completely independent of each other.
They may share a common uniform random number generator or have
their owns.

@item parameter object @code{UNUR_PAR}@*
Hold all information for creating a generator object. It is
necessary due to various parameters and switches for each of
these generation methods.

Notice that the parameter objects only hold pointers to arrays
but do not have their own copy of such an array.
Especially, if a dynamically allocated array is used
it @emph{must not} be freed until the generator object has
been created!

@end itemize

The idea behind these structures is that creatin distributions,
choosing a generation method and draing samples are orthogonal
(ie. independent) functions of the library.
The parameter object is only introduced due to the necessity to
deal with various parameters and switches for
each of these generation methods which are required to adjust the
algorithms to unusual distributions with extreme properties but
have default values that are suitable for most applications.
These parameters and the data for distributions are set by various
functions.

Once a generator object has been created sampling (from the
univariate continuous distribution) can be done by
the following command:

@example
double x = unur_sample_cont(generator);
@end example

@noindent
Analogous commands exist for discrete and multivariate
distributions.
For detailed examples that can be copied and modified
see @ref{Examples}.


@subheading Distribution objects

All information about a distribution are stored in objects
(structures) of type @code{UNUR_DISTR}.
UNU.RAN has five different types of distribution objects:

@table @code
@item cont
Continuous univariate distributions.
@item cvec
Continuous multivariate distributions.
@item discr
Discrete univariate distributions.
@item cemp
Continuous empirical univariate distribution, ie. given by a sample.
@item cvemp
Continuous empirical multivariate distribution, ie. given by a sample.
@item matr
Matrix distributions.

@end table

@noindent
Distribution objects can be
created from scratch by the following call

@example
distr = unur_distr_<type>_new();
@end example

@noindent
where @code{<type>} is one of the five possible types from the
above table.
Notice that these commands only create an @emph{empty} object which
still must be filled by means of calls for each type of
distribution object
(@pxref{Distribution_objects,,Handling distribution objects}).
The naming scheme of these functions is designed to indicate the
corresponding type of the distribution object and the task to be
performed. It is demonstated on the following example.

@example
unur_distr_cont_set_pdf(distr, mypdf);
@end example

@noindent
This command stores a PDF named @code{mypdf} in the distribution
object @code{distr} which must have the type @code{cont}.

Of course UNU.RAN provides an easier way to use standard distributions.
Instead of using @command{unur_distr_<type>_new} calls and fuctions
@command{unur_distr_<type>_set_<@dots{}>} for setting data,
objects for standard distribution can be created by a single call.
Eg. to get an object for the normal distribution with mean 2 and
standard deviation 5 use

@example
double parameter[2] = @{2.0 ,5.0@};
UNUR_DISTR *distr = unur_distr_normal(parameter, 2);
@end example

@noindent
For a list of standard distributions
see @ref{Stddist,,Standard distributions}.


@subheading Generation methods

The information that a distribution object must contain depends
heavily on the chosen generation method choosen.

Brackets indicate optional information while a tilde indicates
that only an approximation must be provided.
See @ref{Glossary}, for unfamiliar terms.

@include methods_cont.texi

@include methods_cemp.texi

@include methods_cvec.texi

@include methods_cvemp.texi

@include methods_discr.texi

@include methods_matr.texi

@include methods_mcmc.texi

Because of tremendous variety of possible problems, UNU.RAN provides many
methods. All information for creating a generator object has to be
collected in a parameter object first.
For example, if the task is to sample from a continuous distribution
the method AROU might be a good choice. Then the call

@example
UNUR_PAR *par = unur_arou_new(distribution);
@end example

@noindent
creates an parameter object @code{par} with a pointer to the
distribution object and default values for all necessary parameters
for method AROU.
Other methods can be used by replacing @code{arou} with the name
of the desired methods (in lower case letters):

@example
UNUR_PAR *par = unur_<method>_new(distribution);
@end example

@noindent
This sets the default values for all necessary parameters for the
chosen method. These are suitable for almost all
applications. Nevertheless, it is possible to control the behavior
of the method using corresponding @command{set} calls for each method.
This might be necessary to adjust the algorithm for an unusual
distribution with extreme properties, or just for fine tuning the
perforence of the algorithm.
The following example demonstrates how to change the maximum
number of iterations for method NINV to the value 50:

@example
unur_ninv_set_max_iteration(par, 50);
@end example

@noindent
All available methods are described in details in
@ref{Methods}.


@subheading Creating a generator object

Now it is possible to create a generator object:

@example
UNUR_GEN *generator = unur_init(par);
if (generator == @code{NULL}) exit(EXIT_FAILURE);
@end example

@noindent
@strong{Important:} You must always check whether
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
has
been executed successfully. Otherwise the @code{NULL} pointer is returned
which causes a segmentation fault when used for sampling.

@noindent
@strong{Important:}
The call of
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
@strong{destroys} the parameter object!@*
Moreover, it is recommended to call
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
immediately after
the parameter object @code{par} has created and modified.

An existing generator object is a rather static construct.
Nevertheless, some of the parameters can still be modified by
@command{chg} calls, e.g.

@example
unur_ninv_chg_max_iteration(gen, 30);
@end example

@noindent
Notice that it is important @emph{when} parameters are
changed because different functions must be used:

The function name includes the term @command{set} and the first
argument must be of type @code{UNUR_PAR} when the parameters are
changed @emph{before} the generator object is created.

The function name includes the term @command{chg} and the first
argument must be of type @code{UNUR_GEN} when the parameters are
changed for an @emph{existing} generator object.

For details see @ref{Methods}.


@subheading Sampling

You can now use your generator object in any place of your program
to sample from your distribution. You only have to take care about
the type of variates it computes: @code{double}, @code{int} or a
vector (array of @code{double}s).
Notice that at this point it does not matter whether you are
sampling from a gamma distribution, a truncated normal distribution
or even an empirical distribution.


@subheading Reinitializing

It is possible for a generator object to change the parameters and
the domain of the underlying distribution. This must be done by
extracting this object by means of a
@ifhtml
@ref{funct:unur_get_distr,@command{unur_get_distr}}
@end ifhtml
@ifnothtml
@command{unur_get_distr}
@end ifnothtml
call and
changing the distribution using the correspondig set calls,
see @ref{Distribution_objects,,Handling distribution objects}.
The generator object @strong{must} then be reinitialized by means
of the
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
call.

@emph{Important}: Currently not all methods allow reinitialization,
see the description of the particular method (keyword @i{Reinit}).


@subheading Destroy

When you do not need your generator object any more, you should
destroy it:

@example
unur_free(generator);
@end example


@subheading Uniform random numbers

Each generator object can have its own uniform random number
generator or share one with others.
When created a parameter object the pointer for the uniform random
number generator is set to the default generator. However, it can be
changed at any time to any other generator:

@example
unur_set_urng(par, urng);
@end example

@noindent
or

@example
unur_chg_urng(generator, urng);
@end example

@noindent
respectively.
See @ref{URNG,,Using uniform random number generators},
for details.



@c
@c end of intro.dh
@c -------------------------------------
@c -------------------------------------
@c intro.dh
@c

@node Contact
@section   Contact the authors


If you have any problems with UNU.RAN, suggestions how to improve
the library, or find a bug, please contact us via email
@email{unuran@@statmath.wu.ac.at}.

For news please visit out homepage at
@uref{http://statmath.wu.ac.at/unuran/}.



@c
@c end of intro.dh
@c -------------------------------------
@c -------------------------------------
@c examples.dh
@c

@node Examples
@chapter   Examples

@menu
* Example_0:: As short as possible
* Example_0_str:: As short as possible (String API)
* Example_1:: Select a method
* Example_1_str:: Select a method (String API)
* Example_2:: Arbitrary distributions
* Example_2_str:: Arbitrary distributions (String API)
* Example_3:: Change parameters of the method
* Example_3_str:: Change parameters of the method (String API)
* Example_4:: Change uniform random generator
* Example_reinit:: Change parameters of underlying distribution
* Example_anti:: Sample pairs of antithetic random variates
* Example_anti_str:: Sample pairs of antithetic random variates (String API)
* Example_More:: More examples
@end menu



The examples in this chapter should compile cleanly and can be
found in the directory @file{examples} of the source tree of
UNU.RAN. Assuming that UNU.RAN as well as the PRNG libraries
have been installed properly (@pxref{Installation}) each
of these can be compiled (using the GCC in this example) with

@example
gcc -Wall -O2 -o example example.c -lunuran -lprng -lm
@end example

@noindent
@emph{Remark:} @code{-lprng} must be omitted when the PRNG library
is not installed. Then however some of the examples might not work.

The library uses three objects:
@code{UNUR_DISTR}, @code{UNUR_PAR} and @code{UNUR_GEN}.
It is not important to understand the details of these objects but
it is important not to changed the order of their creation.
The distribution object can be destroyed @emph{after} the generator
object has been made. (The parameter object is freed automatically
by the
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
call.) It is also important to check the result
of the
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
call. If it has failed the @code{NULL} pointer is
returned and causes a segmentation fault when used for sampling.

We give all examples with the UNU.RAN standard API and the more
convenient string API.



@c
@c end of examples.dh
@c -------------------------------------
@c -------------------------------------
@c examples.dh
@c

@page
@node Example_0
@section   As short as possible



Select a distribution and let UNU.RAN do all necessary steps.

@smallexample
@include ref_example0.texi
@end smallexample



@c
@c end of examples.dh
@c -------------------------------------
@c -------------------------------------
@c examples.dh
@c

@page
@node Example_0_str
@section   As short as possible (String API)



Select a distribution and let UNU.RAN do all necessary steps.

@smallexample
@include ref_example0_str.texi
@end smallexample



@c
@c end of examples.dh
@c -------------------------------------
@c -------------------------------------
@c examples.dh
@c

@page
@node Example_1
@section   Select a method



Select method AROU and use it with default parameters.

@smallexample
@include ref_example1.texi
@end smallexample



@c
@c end of examples.dh
@c -------------------------------------
@c -------------------------------------
@c examples.dh
@c

@page
@node Example_1_str
@section   Select a method (String API)



Select method AROU and use it with default parameters.

@smallexample
@include ref_example1_str.texi
@end smallexample



@c
@c end of examples.dh
@c -------------------------------------
@c -------------------------------------
@c examples.dh
@c

@page
@node Example_2
@section   Arbitrary distributions



If you want to sample from a non-standard distribution,
UNU.RAN might be exactly what you need.
Depending on the information is available, a method
must be choosen for sampling,
see @ref{Concepts} for an overview and
@ref{Methods} for details.

@smallexample
@include ref_example2.texi
@end smallexample



@c
@c end of examples.dh
@c -------------------------------------
@c -------------------------------------
@c examples.dh
@c

@page
@node Example_2_str
@section   Arbitrary distributions (String API)



If you want to sample from a non-standard distribution,
UNU.RAN might be exactly what you need.
Depending on the information is available, a method
must be choosen for sampling,
see @ref{Concepts} for an overview and
@ref{Methods} for details.

@smallexample
@include ref_example2_str.texi
@end smallexample



@c
@c end of examples.dh
@c -------------------------------------
@c -------------------------------------
@c examples.dh
@c

@page
@node Example_3
@section   Change parameters of the method



Each method for generating random numbers allows several
parameters to be modified. If you do not want to use default values,
it is possible to change them.
The following example illustrates how to change parameters.
For details see @ref{Methods}.

@smallexample
@include ref_example3.texi
@end smallexample



@c
@c end of examples.dh
@c -------------------------------------
@c -------------------------------------
@c examples.dh
@c

@page
@node Example_3_str
@section   Change parameters of the method (String API)



Each method for generating random numbers allows several
parameters to be modified. If you do not want to use default values,
it is possible to change them.
The following example illustrates how to change parameters.
For details see @ref{Methods}.

@smallexample
@include ref_example3_str.texi
@end smallexample



@c
@c end of examples.dh
@c -------------------------------------
@c -------------------------------------
@c examples.dh
@c

@page
@node Example_4
@section   Change uniform random generator



All generator object use the same default uniform random number
generator by default. This can be changed to any generator of your
choice such that each generator object has its own random number
generator or can share it with some other objects.
It is also possible to change the default generator at any time.
See @ref{URNG,,Using uniform random number generators},
for details.

The following example shows how the uniform random number generator
can be set or changed for a generator object. It requires the
RNGSTREAMS library to be installed and used. Otherwise the example must be
modified accordingly.

@smallexample
@include ref_example_rngstreams.texi
@end smallexample



@c
@c end of examples.dh
@c -------------------------------------
@c -------------------------------------
@c examples.dh
@c

@page
@node Example_reinit
@section   Change parameters of underlying distribution



One a generator object has been created it allows to draw samples from
the distribution with the given parameters.
However, some methods allow to change the parameters of the underlying
distribution and reinitialize the generator object again.
Thus when the parameters of the distribution vary for each draw we
save overhead for destroying the old object and creating a new one.

The following example shows how the parameters of a GIG distribution
can be changed when method CSTD is used.

@smallexample
@include ref_example_reinit.texi
@end smallexample



@c
@c end of examples.dh
@c -------------------------------------
@c -------------------------------------
@c examples.dh
@c

@page
@node Example_anti
@section   Sample pairs of antithetic random variates


Using Method TDR it is easy to sample pairs of antithetic random variates.

@smallexample
@include ref_example_anti.texi
@end smallexample



@c
@c end of examples.dh
@c -------------------------------------
@c -------------------------------------
@c examples.dh
@c

@page
@node Example_anti_str
@section   Sample pairs of antithetic random variates (String API)


Using Method TDR it is easy to sample pairs of antithetic random variates.

@smallexample
@include ref_example_anti_str.texi
@end smallexample



@c
@c end of examples.dh
@c -------------------------------------
@c -------------------------------------
@c examples.dh
@c

@page
@node Example_More
@section   More examples



@xref{Methods_for_CONT,,Methods for continuous univariate distributions}.

@xref{Methods_for_CEMP,,Methods for continuous empirical univariate distributions}.

@xref{Methods_for_CVEMP,,Methods for continuous empirical multivariate distributions}.

@xref{Methods_for_DISCR,,Methods for discrete univariate distributions}.



@c
@c end of examples.dh
@c -------------------------------------
@c -------------------------------------
@c parser.h
@c

@node StringAPI
@chapter   String Interface

@menu
* StringSyntax:: Syntax of String Interface
* StringDistr:: Distribution String
* StringFunct:: Function String
* StringMethod:: Method String
* StringURNG:: Uniform RNG String
@end menu



The string interface (string API) provided by the
@ifhtml
@ref{funct:unur_str2gen,@command{unur_str2gen}}
@end ifhtml
@ifnothtml
@command{unur_str2gen}
@end ifnothtml
call is the easiest way to use UNU.RAN. This
function takes a character string as its argument. The string is
parsed and the information obtained is used to create a generator
object. It returns @code{NULL} if this fails, either due to a syntax
error, or due to invalid data. In both cases @code{unur_error} is
set to the corresponding error codes
(@pxref{Error_reporting,,Error reporting}).
Additionally there exists the call
@ifhtml
@ref{funct:unur_str2distr,@command{unur_str2distr}}
@end ifhtml
@ifnothtml
@command{unur_str2distr}
@end ifnothtml
that only
produces a distribution object.

Notice that the string interface does not implement all features of
the UNU.RAN library. For trickier tasks it might be necessary to use
the UNU.RAN calls.

In @ref{Examples}, all examples are given using both the
UNU.RAN standard API and this convenient string API.
The corresponding programm codes are equivalent.


@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_str2gen,unur_str2gen}
@item @ref{funct:unur_str2distr,unur_str2distr}
@item @ref{funct:unur_makegen_ssu,unur_makegen_ssu}
@item @ref{funct:unur_makegen_dsu,unur_makegen_dsu}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_str2gen}
@deftypefn Function {UNUR_GEN*} unur_str2gen (const @var{char* string})
Get a generator object for the distribution, method and uniform
random number generator as described in the given @var{string}.
See @ref{StringSyntax,,Syntax of String Interface}, for details.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_str2gen}
@deftypefn {} {UNUR_GEN*} unur_str2gen (const @var{char* string})
Get a generator object for the distribution, method and uniform
random number generator as described in the given @var{string}.
See @ref{StringSyntax,,Syntax of String Interface}, for details.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_str2distr}
@deftypefn Function {UNUR_DISTR*} unur_str2distr (const @var{char* string})
Get a distribution object for the distribution described in
@var{string}.
See @ref{StringSyntax,,Syntax of String Interface},
and @ref{StringDistr,,Distribution String},
for details. However, only the block for the distribution object is
allowed.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_str2distr}
@deftypefn {} {UNUR_DISTR*} unur_str2distr (const @var{char* string})
Get a distribution object for the distribution described in
@var{string}.
See @ref{StringSyntax,,Syntax of String Interface},
and @ref{StringDistr,,Distribution String},
for details. However, only the block for the distribution object is
allowed.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_makegen_ssu}
@anchor{funct:unur_makegen_dsu}
@deftypefn Function {UNUR_GEN*} unur_makegen_ssu (const @var{char* distrstr}, const @var{char* methodstr}, UNUR_URNG* @var{urng})
@deftypefnx Function {UNUR_GEN*} unur_makegen_dsu (const @var{UNUR_DISTR* distribution}, const @var{char* methodstr}, UNUR_URNG* @var{urng})
Make a generator object for the distribution, method and uniform
random number generator. The distribution can be given either as
string @var{distrstr} or as a distribution object @var{distr}.
The method must be given as a string @var{methodstr}.
For the syntax of these strings see
@ref{StringSyntax,,Syntax of String Interface}.
However, the @code{method} keyword is optional for these calls
and can be omitted. If @var{methodstr} is the empty (blank) string
or @code{NULL} method AUTO is used.
The uniform random number generator is optional. If
@var{urng} is @code{NULL} then the default uniform random number generator
is used.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_makegen_ssu}
@anchor{funct:unur_makegen_dsu}
@deftypefn {} {UNUR_GEN*} unur_makegen_ssu (const @var{char* distrstr}, const @var{char* methodstr}, UNUR_URNG* @var{urng})
@deftypefnx {} {UNUR_GEN*} unur_makegen_dsu (const @var{UNUR_DISTR* distribution}, const @var{char* methodstr}, UNUR_URNG* @var{urng})
Make a generator object for the distribution, method and uniform
random number generator. The distribution can be given either as
string @var{distrstr} or as a distribution object @var{distr}.
The method must be given as a string @var{methodstr}.
For the syntax of these strings see
@ref{StringSyntax,,Syntax of String Interface}.
However, the @code{method} keyword is optional for these calls
and can be omitted. If @var{methodstr} is the empty (blank) string
or @code{NULL} method AUTO is used.
The uniform random number generator is optional. If
@var{urng} is @code{NULL} then the default uniform random number generator
is used.
@end deftypefn
@end ifnotinfo




@c
@c end of parser.h
@c -------------------------------------
@c -------------------------------------
@c parser.h
@c

@node StringSyntax
@section   Syntax of String Interface



The given string holds information about the requested distribution
and (optional) about the sampling method and the uniform random
number generator invoked. The interpretation of the string is not
case-sensitive, all white spaces are ignored.

The string consists of up to three blocks, separated by ampersands
@code{&}.

Each block consists of @code{<key>=<value>} pairs, separated by
semicolons @code{;}.

The first key in each block is used to indicate each block.
We have three different blocks with the following (first) keys:
@table @code
@item distr
definition of the distribution
(@pxref{StringDistr,,Distribution String}).

@item method
description of the transformation method
(@pxref{StringMethod,,Method String}).

@item urng
uniform random number generation
(@pxref{StringURNG,,Uniform RNG String}).
@end table

The @code{distr} block must be the very first block and is
obligatory. All the other blocks are optional and can be arranged
in arbitrary order.

For details see the following description of each block.

In the following example

@example
distr = normal(3.,0.75); domain = (0,inf) & method = tdr; c = 0
@end example

@noindent
we have a distribution block for the truncated normal distribution
with mean 3 and standard deviation 0.75 on domain (0,infinity);
and block for choosing method TDR with parameter c set to 0.

The @code{<key>=<value>} pairs that follow the first (initial) pair
in each block are used to set parameters.
The name of the parameter is given by the @code{<key>} string. It is
deduced from the UNU.RAN set calls by taking the part after
@code{@dots{}_set_}.
The @code{<value>} string holds the parameters to be
set, separated by commata @code{,}.
There are three types of parameters:
@table @emph
@item string @code{"@dots{}"} or @code{'@dots{}'}
i.e. any sequence of characters enclosed by double quotes
@code{"@dots{}"} or single quotes @code{'@dots{}'}
(there is no distinction between double quotes @code{"} and
single quotes @code{'}).
@item list @code{(@dots{},@dots{})}
i.e. list of @emph{numbers}, separated by commata @code{,},
enclosed in parenthesis @code{(...)}.
@item number
a sequence of characters that is not enclosed by double quotes
@code{"@dots{}"}, single quotes @code{'@dots{}'},
or parenthesis @code{(...)}.
It is interpreted as float or integer depending on the type of
the corresponding parameter.
@end table
The @code{<value>} string (including the character @code{=}) can be
omitted when no argument is required.

At the moment not all @command{set} calls are supported.
The syntax for the @code{<value>} can be directly derived from the
corresponding @command{set} calls. To simplify the syntax additional
shortcuts are possible. The following table lists the parameters for
the @code{set} calls that are supported by the string interface; the
entry in parenthesis gives the type of the argument as
@code{<value>} string:

@table @code
@item int  @i{(number)}:
The @i{number} is interpreted as an integer.
@code{true} and @code{on} are transformed to @code{1},
@code{false} and @code{off} are transformed to @code{0}.
A missing argument is interpreted as @code{1}.

@item int, int  @i{(number, number} @r{or} @i{list)}:
The two numbers or the first two entries in the list are
interpreted as a integers.
@code{inf} and @code{-inf} are transformed to @code{INT_MAX} and
@code{INT_MIN} respectively, i.e. the largest and smallest
integers that can be represented by the computer.

@item unsigned @i{(number)}:
The @i{number} is interpreted as an unsigned hexadecimal
integer.

@item double  @i{(number)}:
The number is interpreted as a floating point number.
@code{inf} is transformed to @code{UNUR_INFINITY}.

@item double, double  @i{(number, number} @r{or} @i{list)}:
The two numbers or the first two entries in the list are
interpreted as a floating point numbers.
@code{inf} is transformed to @code{UNUR_INFINITY}. However using
@code{inf} in the list might not work for all versions of C. Then it
is recommended to use two single numbers instead of a list.

@item int, double*  @i{([number,] list} @r{or} @i{number)}:
@itemize @minus
@item
The list is interpreted as a double array.
The (first) number as its length.
If it is less than the actual size of the array only the
first entries of the array are used.
@item
If only the list is given (i.e., if the first number is omitted),
the first number is set to the actual size of the array.
@item
If only the number is given (i.e., if the list is omitted), the @code{NULL}
pointer is used instead an array as argument.
@end itemize

@item double*, int  @i{(list [,number])}:
The list is interpreted as a double array.
The (second) number as its length.
If the length is omitted, it is replaced by the actual size of the
array. (Only in the @code{distribution} block!)

@item char*  @i{(string)}:
The character string is passed as is to the corresponding set
call.

@end table

Notice that missing entries in a list of numbers are interpreted as
@code{0}. E.g, a the list @code{(1,,3)} is read as @code{(1,0,3)}, the
list @code{(1,2,)} as @code{(1,2,0)}.

The the list of @code{key} strings in
@ref{KeysDistr,,Keys for Distribution String}, and
@ref{KeysMethod,,Keys for Method String}, for further details.



@c
@c end of parser.h
@c -------------------------------------
@c -------------------------------------
@c parser.h
@c

@page
@node StringDistr
@section   Distribution String

@menu
* KeysDistr:: Keys for Distribution String
@end menu



The @code{distr} block must be the very first block and is
obligatory. For that reason the keyword @code{distr} is optional and
can be omitted (together with the @code{=} character).
Moreover it is ignored while parsing the string. However, to
avoid some possible confusion it has to start with the
letter @code{d} (if it is given at all).

The value of the @code{distr} key is used to get the distribution
object, either via a @command{unur_distr_<value>} call for a standard
distribution via a @command{unur_distr_<value>_new} call to get an
object of a generic distribution.
However not all generic distributions are supported yet.

The parameters for the standard distribution are given
as a list. There must not be any character (other than white space)
between the name of the standard distribution and the opening
parenthesis @code{(} of this list. E.g., to get a beta distribution,
use

@example
distr = beta(2,4)
@end example

To get an object for a discrete distribution with probability
vector (0.5,0.2,0.3), use

@example
distr = discr; pv = (0.5,0.2,0.3)
@end example

It is also possible to set a PDF, PMF, or CDF using a string.
E.g., to create a continuous distribution with PDF proportional to
@code{exp(-sqrt(2+(x-1)^2) + (x-1))} and domain (0,inf) use

@example
distr = cont; pdf = "exp(-sqrt(2+(x-1)^2) + (x-1))"
@end example

@noindent
Notice: If this string is used in an
@ifhtml
@ref{funct:unur_str2distr,@command{unur_str2distr}}
@end ifhtml
@ifnothtml
@command{unur_str2distr}
@end ifnothtml
or
@ifhtml
@ref{funct:unur_str2gen,@command{unur_str2gen}}
@end ifhtml
@ifnothtml
@command{unur_str2gen}
@end ifnothtml
call the double quotes @code{"} must be protected by
@code{\"}. Alternatively, single quotes may be used instead

@example
distr = cont; pdf = 'exp(-sqrt(2+(x-1)^2) + (x-1))'
@end example

For the details of function strings see
@ref{StringFunct,,Function String}.



@c
@c end of parser.h
@c -------------------------------------
@c -------------------------------------
@c stringparser_doc.dh
@c

@node KeysDistr
@subsection   Keys for Distribution String



List of standard distributions @pxref{Stddist,,Standard distributions}

@itemize @minus
@item @code{[distr =] beta(@dots{})} @ @ @ @  @result{} @pxref{beta}
@item @code{[distr =] binomial(@dots{})} @ @ @ @  @result{} @pxref{binomial}
@item @code{[distr =] cauchy(@dots{})} @ @ @ @  @result{} @pxref{cauchy}
@item @code{[distr =] chi(@dots{})} @ @ @ @  @result{} @pxref{chi}
@item @code{[distr =] chisquare(@dots{})} @ @ @ @  @result{} @pxref{chisquare}
@item @code{[distr =] exponential(@dots{})} @ @ @ @  @result{} @pxref{exponential}
@item @code{[distr =] extremeI(@dots{})} @ @ @ @  @result{} @pxref{extremeI}
@item @code{[distr =] extremeII(@dots{})} @ @ @ @  @result{} @pxref{extremeII}
@item @code{[distr =] F(@dots{})} @ @ @ @  @result{} @pxref{F}
@item @code{[distr =] gamma(@dots{})} @ @ @ @  @result{} @pxref{gamma}
@item @code{[distr =] geometric(@dots{})} @ @ @ @  @result{} @pxref{geometric}
@item @code{[distr =] gig(@dots{})} @ @ @ @  @result{} @pxref{gig}
@item @code{[distr =] gig2(@dots{})} @ @ @ @  @result{} @pxref{gig2}
@item @code{[distr =] hyperbolic(@dots{})} @ @ @ @  @result{} @pxref{hyperbolic}
@item @code{[distr =] hypergeometric(@dots{})} @ @ @ @  @result{} @pxref{hypergeometric}
@item @code{[distr =] ig(@dots{})} @ @ @ @  @result{} @pxref{ig}
@item @code{[distr =] laplace(@dots{})} @ @ @ @  @result{} @pxref{laplace}
@item @code{[distr =] logarithmic(@dots{})} @ @ @ @  @result{} @pxref{logarithmic}
@item @code{[distr =] logistic(@dots{})} @ @ @ @  @result{} @pxref{logistic}
@item @code{[distr =] lognormal(@dots{})} @ @ @ @  @result{} @pxref{lognormal}
@item @code{[distr =] lomax(@dots{})} @ @ @ @  @result{} @pxref{lomax}
@item @code{[distr =] negativebinomial(@dots{})} @ @ @ @  @result{} @pxref{negativebinomial}
@item @code{[distr =] normal(@dots{})} @ @ @ @  @result{} @pxref{normal}
@item @code{[distr =] pareto(@dots{})} @ @ @ @  @result{} @pxref{pareto}
@item @code{[distr =] poisson(@dots{})} @ @ @ @  @result{} @pxref{poisson}
@item @code{[distr =] powerexponential(@dots{})} @ @ @ @  @result{} @pxref{powerexponential}
@item @code{[distr =] rayleigh(@dots{})} @ @ @ @  @result{} @pxref{rayleigh}
@item @code{[distr =] slash(@dots{})} @ @ @ @  @result{} @pxref{slash}
@item @code{[distr =] student(@dots{})} @ @ @ @  @result{} @pxref{student}
@item @code{[distr =] triangular(@dots{})} @ @ @ @  @result{} @pxref{triangular}
@item @code{[distr =] uniform(@dots{})} @ @ @ @  @result{} @pxref{uniform}
@item @code{[distr =] weibull(@dots{})} @ @ @ @  @result{} @pxref{weibull}
@end itemize

List of generic distributions @pxref{Distribution_objects,,Handling Distribution Objects}

@itemize @minus
@item @code{[distr =] cemp} @ @ @ @  @result{} @pxref{CEMP}
@item @code{[distr =] cont} @ @ @ @  @result{} @pxref{CONT}
@item @code{[distr =] discr} @ @ @ @  @result{} @pxref{DISCR}
@end itemize

@emph{Notice}:
Order statistics for continuous distributions (@pxref{CORDER}) are
supported by using the key @code{orderstatistics} for distributions
of type @code{CONT}.

List of keys that are available via the String API.
For description see the corresponding UNU.RAN set calls.

@itemize @bullet
@item All distribution types
@table @code
@item name = "@i{<string>}"
@result{} @pxref{funct:unur_distr_set_name,,@command{unur_distr_set_name}}
@end table

@item @code{cemp} @ @i{(Distribution Type)}@ @ @ @ (@pxref{CEMP})
@table @code
@item data = (@i{<list>}) [, @i{<int>}]
@result{} @pxref{funct:unur_distr_cemp_set_data,,@command{unur_distr_cemp_set_data}}
@item hist_bins = (@i{<list>}) [, @i{<int>}]
@result{} @pxref{funct:unur_distr_cemp_set_hist_bins,,@command{unur_distr_cemp_set_hist_bins}}
@item hist_domain = @i{<double>}, @i{<double>} | (@i{<list>})
@result{} @pxref{funct:unur_distr_cemp_set_hist_domain,,@command{unur_distr_cemp_set_hist_domain}}
@item hist_prob = (@i{<list>}) [, @i{<int>}]
@result{} @pxref{funct:unur_distr_cemp_set_hist_prob,,@command{unur_distr_cemp_set_hist_prob}}
@end table

@item @code{cont} @ @i{(Distribution Type)}@ @ @ @ (@pxref{CONT})
@table @code
@item cdf = "@i{<string>}"
@result{} @pxref{funct:unur_distr_cont_set_cdfstr,,@command{unur_distr_cont_set_cdfstr}}
@item center = @i{<double>}
@result{} @pxref{funct:unur_distr_cont_set_center,,@command{unur_distr_cont_set_center}}
@item domain = @i{<double>}, @i{<double>} | (@i{<list>})
@result{} @pxref{funct:unur_distr_cont_set_domain,,@command{unur_distr_cont_set_domain}}
@item hr = "@i{<string>}"
@result{} @pxref{funct:unur_distr_cont_set_hrstr,,@command{unur_distr_cont_set_hrstr}}
@item logcdf = "@i{<string>}"
@result{} @pxref{funct:unur_distr_cont_set_logcdfstr,,@command{unur_distr_cont_set_logcdfstr}}
@item logpdf = "@i{<string>}"
@result{} @pxref{funct:unur_distr_cont_set_logpdfstr,,@command{unur_distr_cont_set_logpdfstr}}
@item mode = @i{<double>}
@result{} @pxref{funct:unur_distr_cont_set_mode,,@command{unur_distr_cont_set_mode}}
@item pdf = "@i{<string>}"
@result{} @pxref{funct:unur_distr_cont_set_pdfstr,,@command{unur_distr_cont_set_pdfstr}}
@item pdfarea = @i{<double>}
@result{} @pxref{funct:unur_distr_cont_set_pdfarea,,@command{unur_distr_cont_set_pdfarea}}
@item pdfparams = (@i{<list>}) [, @i{<int>}]
@result{} @pxref{funct:unur_distr_cont_set_pdfparams,,@command{unur_distr_cont_set_pdfparams}}
@item orderstatistics = @i{<int>}, @i{<int>} | (@i{<list>})
Make order statistics for given distribution. The first parameter
gives the sample size, the second parameter its rank.
(see @pxref{funct:unur_distr_corder_new,,@command{unur_distr_corder_new}})
@end table

@item @code{discr} @ @i{(Distribution Type)}@ @ @ @ (@pxref{DISCR})
@table @code
@item cdf = "@i{<string>}"
@result{} @pxref{funct:unur_distr_discr_set_cdfstr,,@command{unur_distr_discr_set_cdfstr}}
@item domain = @i{<int>}, @i{<int>} | (@i{<list>})
@result{} @pxref{funct:unur_distr_discr_set_domain,,@command{unur_distr_discr_set_domain}}
@item mode [= @i{<int>}]
@result{} @pxref{funct:unur_distr_discr_set_mode,,@command{unur_distr_discr_set_mode}}
@item pmf = "@i{<string>}"
@result{} @pxref{funct:unur_distr_discr_set_pmfstr,,@command{unur_distr_discr_set_pmfstr}}
@item pmfparams = (@i{<list>}) [, @i{<int>}]
@result{} @pxref{funct:unur_distr_discr_set_pmfparams,,@command{unur_distr_discr_set_pmfparams}}
@item pmfsum = @i{<double>}
@result{} @pxref{funct:unur_distr_discr_set_pmfsum,,@command{unur_distr_discr_set_pmfsum}}
@item pv = (@i{<list>}) [, @i{<int>}]
@result{} @pxref{funct:unur_distr_discr_set_pv,,@command{unur_distr_discr_set_pv}}
@end table

@end itemize




@c
@c end of stringparser_doc.dh
@c -------------------------------------
@c -------------------------------------
@c functparser_doc.dh
@c

@page
@node StringFunct
@section   Function String



In unuran it is also possible to define functions (e.g. CDF or PDF) as
strings. As you can see in Example 2 (@ref{Example_2_str}) it is very
easy to define the PDF of a distribution object by means of a string.
The possibilities using this string interface are more restricted than
using a pointer to a routine coded in C (@ref{Example_2}).
But the differences in evaluation time is small.
When a distribution object is defined using this string interface then
of course the same conditions on the given density or CDF must be
satisfied for a chosen method as for the standard API.
This string interface can be used for both within the UNU.RAN string
API using the
@ifhtml
@ref{funct:unur_str2gen,@command{unur_str2gen}}
@end ifhtml
@ifnothtml
@command{unur_str2gen}
@end ifnothtml
call, and for calls that define the
density or CDF for a particular distribution object as done with
(e.g.) the call
@ifhtml
@ref{funct:unur_distr_cont_set_pdfstr,@command{unur_distr_cont_set_pdfstr}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_pdfstr}.
@end ifnothtml
Here is an example for the latter case:

@example
unur_distr_cont_set_pdfstr(distr,"1-x*x");
@end example


@subheading Syntax

The syntax for the function string is case insensitive, white spaces
are ingnored. The expressions are similar to most programming languages
and mathematical programs (see also the examples below). It is especially
influenced by C. The usual preceedence rules are used (from highest
to lowest preceedence: functions, power, multiplication,
addition, relation operators). Use parentheses in case of doubt or
when these preceedences should be changed.

Relation operators can be used as indicator functions, i.e. the term
@code{(x>1)} is evaluted as @code{1} if this relation is satisfied,
and as @code{0} otherwise.

The first unknown symbol (letter or word) is interpreted as the
variable of the function. It is recommended to use @code{x}.
Only one variable can be used.

@noindent
@emph{Important}: The symbol @code{e} is used twice, for Euler's
constant (= 2.7182@dots{}) and as exponent.
The multiplication operator @code{*} must not be omitted, i.e.
@code{2 x} is interpreted as the string @code{2x} (which will result
in a syntax error).


@subheading List of symbols

@cartouche
@noindent
@b{Numbers}

@noindent
Numbers are composed using digits and, optionally, a sign,
a decimal point, and an exponent indicated by @code{e}.

@multitable {xxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
@item Symbol        @tab Explanation              @tab Examples
@item @code{0@dots{}9} @tab @i{digits}            @tab @code{2343}
@item @code{.}      @tab @i{decimal point}        @tab @code{165.567}
@item @code{-}      @tab @i{negative sign}        @tab @code{-465.223}
@item @code{e}      @tab @i{exponet}              @tab @code{13.2e-4} (=0.00132)
@end multitable
@end cartouche

@cartouche
@noindent
@b{Constants}

@multitable {xxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
@item @code{pi}     @tab @i{pi = 3.1415@dots{}}   @tab @code{3*pi+2}
@item @code{e}      @tab @i{Euler's constant}     @tab @code{3*e+2} (= 10.15@dots{};
do not cofuse with @code{3e2} = 300)
@item @code{inf}    @tab @i{infinity}             @tab (used for domains)
@end multitable
@end cartouche

@cartouche
@noindent
@b{Special symbols}

@multitable {xxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
@item @code{(}      @tab @i{opening parenthesis}  @tab @code{2*(3+x)}
@item @code{)}      @tab @i{closing parenthesis}  @tab @code{2*(3+x)}
@item @code{,}      @tab @i{(argument) list separator} @tab @code{mod(13,2)}
@end multitable
@end cartouche

@cartouche
@noindent
@b{Relation operators (Indicator functions)}

@multitable {xxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
@item @code{<}      @tab @i{less than}            @tab @code{(x<1)}
@item @code{=}      @tab @i{equal}                @tab @code{(2=x)}
@item @code{==}     @tab @i{same as} @code{=}     @tab @code{(x==3)}
@item @code{>}      @tab @i{greater than}         @tab @code{(x>0)}
@item @code{<=}     @tab @i{less than or equal}   @tab @code{(x<=1)}
@item @code{!=}     @tab @i{not equal}            @tab @code{(x!0)}
@item @code{<>}     @tab @i{same as} @code{!=}    @tab @code{(x<>pi)}
@item @code{>=}     @tab @i{greater or equal}     @tab @code{(x>=1)}
@end multitable
@end cartouche

@cartouche
@noindent
@b{Arithmetic operators}

@multitable {xxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
@item @code{+}      @tab @i{addition}             @tab @code{2+x}
@item @code{-}      @tab @i{subtraction}          @tab @code{2-x}
@item @code{*}      @tab @i{multiplication}       @tab @code{2*x}
@item @code{/}      @tab @i{division}             @tab @code{x/2}
@item @code{^}      @tab @i{power}                @tab @code{x^2}
@end multitable
@end cartouche

@cartouche
@noindent
@b{Functions}

@multitable {xxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
@item @code{mod}    @tab @code{mod(m,n)} @i{remainder of devision m over n} @tab mod(x,2)
@item @code{exp}    @tab @i{exponential function
(same as @code{e^x})}    @tab @code{exp(-x^2)} (same as @code{e^(-x^2)})
@item @code{log}    @tab @i{natural logarithm}    @tab @code{log(x)}
@item @code{sin}    @tab @i{sine}                 @tab @code{sin(x)}
@item @code{cos}    @tab @i{cosine}               @tab @code{cos(x)}
@item @code{tan}    @tab @i{tangent}              @tab @code{tan(x)}
@item @code{sec}    @tab @i{secant}               @tab @code{sec(x*2)}
@item @code{sqrt}   @tab @i{square root}          @tab @code{sqrt(2*x)}
@item @code{abs}    @tab @i{absolute value}       @tab @code{abs(x)}
@item @code{sgn}    @tab @i{sign function}        @tab @code{sign(x)*3}
@end multitable
@end cartouche

@cartouche
@noindent
@b{Variable}

@multitable {xxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
@item @code{x}      @tab @i{variable}             @tab @code{3*x^2}
@end multitable
@end cartouche


@subheading Examples

@example
1.231+7.9876*x-1.234e-3*x^2+3.335e-5*x^3
sin(2*pi*x)+x^2
exp(-((x-3)/2.1)^2)
@end example

@noindent
It is also possible to define functions using different terms
on separate domains. However, instead of constructs using
@code{if @dots{} then @dots{} else @dots{}}
indicator functions are available.

@noindent
For example to define the density of triangular distribution
with domain (-1,1) and mode 0 use

@example
(x>-1)*(x<0)*(1+x) + (x>=0)*(x<1)*(1-x)
@end example



@c
@c end of functparser_doc.dh
@c -------------------------------------
@c -------------------------------------
@c parser.h
@c

@page
@node StringMethod
@section   Method String

@menu
* KeysMethod:: Keys for Method String
@end menu



The key @code{method} is obligatory, it must be the first key and its
value is the name of a method suitable for the choosen standard
distribution. E.g., if method AROU is chosen, use

@example
method = arou
@end example

Of course the all following keys dependend on the method choosen at
first. All corresponding @command{set} calls of UNU.RAN are available
and the key is the string after the @command{unur_<methodname>_set_}
part of the command. E.g., UNU.RAN provides the command
@command{unur_arou_set_max_sqhratio} to set a parameter of method AROU.
To call this function via the string-interface, the
key @code{max_sqhratio} can be used:

@example
max_sqhratio = 0.9
@end example

@noindent
Additionally the keyword @code{debug} can be used to set debugging
flags (see @ref{Debug,,Debugging}, for details).

If this block is omitted, a suitable default method is used. Notice
however that the default method may change in future versions of
UNU.RAN.



@c
@c end of parser.h
@c -------------------------------------
@c -------------------------------------
@c stringparser_doc.dh
@c

@node KeysMethod
@subsection   Keys for Method String



List of methods and keys that are available via the String API.
For description see the corresponding UNU.RAN set calls.

@itemize @bullet
@item @code{method = arou} @ @ @ @  @result{} @command{unur_arou_new}
(@pxref{AROU})
@table @code
@item cpoints = @i{<int>} [, (@i{<list>})] | (@i{<list>})
@result{} @pxref{funct:unur_arou_set_cpoints,,@command{unur_arou_set_cpoints}}
@item darsfactor = @i{<double>}
@result{} @pxref{funct:unur_arou_set_darsfactor,,@command{unur_arou_set_darsfactor}}
@item guidefactor = @i{<double>}
@result{} @pxref{funct:unur_arou_set_guidefactor,,@command{unur_arou_set_guidefactor}}
@item max_segments [= @i{<int>}]
@result{} @pxref{funct:unur_arou_set_max_segments,,@command{unur_arou_set_max_segments}}
@item max_sqhratio = @i{<double>}
@result{} @pxref{funct:unur_arou_set_max_sqhratio,,@command{unur_arou_set_max_sqhratio}}
@item pedantic [= @i{<int>}]
@result{} @pxref{funct:unur_arou_set_pedantic,,@command{unur_arou_set_pedantic}}
@item usecenter [= @i{<int>}]
@result{} @pxref{funct:unur_arou_set_usecenter,,@command{unur_arou_set_usecenter}}
@item usedars [= @i{<int>}]
@result{} @pxref{funct:unur_arou_set_usedars,,@command{unur_arou_set_usedars}}
@item verify [= @i{<int>}]
@result{} @pxref{funct:unur_arou_set_verify,,@command{unur_arou_set_verify}}
@end table

@item @code{method = ars} @ @ @ @  @result{} @command{unur_ars_new}
(@pxref{ARS})
@table @code
@item cpoints = @i{<int>} [, (@i{<list>})] | (@i{<list>})
@result{} @pxref{funct:unur_ars_set_cpoints,,@command{unur_ars_set_cpoints}}
@item max_intervals [= @i{<int>}]
@result{} @pxref{funct:unur_ars_set_max_intervals,,@command{unur_ars_set_max_intervals}}
@item max_iter [= @i{<int>}]
@result{} @pxref{funct:unur_ars_set_max_iter,,@command{unur_ars_set_max_iter}}
@item pedantic [= @i{<int>}]
@result{} @pxref{funct:unur_ars_set_pedantic,,@command{unur_ars_set_pedantic}}
@item reinit_ncpoints [= @i{<int>}]
@result{} @pxref{funct:unur_ars_set_reinit_ncpoints,,@command{unur_ars_set_reinit_ncpoints}}
@item reinit_percentiles = @i{<int>} [, (@i{<list>})] | (@i{<list>})
@result{} @pxref{funct:unur_ars_set_reinit_percentiles,,@command{unur_ars_set_reinit_percentiles}}
@item verify [= @i{<int>}]
@result{} @pxref{funct:unur_ars_set_verify,,@command{unur_ars_set_verify}}
@end table

@item @code{method = auto} @ @ @ @  @result{} @command{unur_auto_new}
(@pxref{AUTO})
@table @code
@item logss [= @i{<int>}]
@result{} @pxref{funct:unur_auto_set_logss,,@command{unur_auto_set_logss}}
@end table

@item @code{method = cstd} @ @ @ @  @result{} @command{unur_cstd_new}
(@pxref{CSTD})
@table @code
@item variant = @i{<unsigned>}
@result{} @pxref{funct:unur_cstd_set_variant,,@command{unur_cstd_set_variant}}
@end table

@item @code{method = dari} @ @ @ @  @result{} @command{unur_dari_new}
(@pxref{DARI})
@table @code
@item cpfactor = @i{<double>}
@result{} @pxref{funct:unur_dari_set_cpfactor,,@command{unur_dari_set_cpfactor}}
@item squeeze [= @i{<int>}]
@result{} @pxref{funct:unur_dari_set_squeeze,,@command{unur_dari_set_squeeze}}
@item tablesize [= @i{<int>}]
@result{} @pxref{funct:unur_dari_set_tablesize,,@command{unur_dari_set_tablesize}}
@item verify [= @i{<int>}]
@result{} @pxref{funct:unur_dari_set_verify,,@command{unur_dari_set_verify}}
@end table

@item @code{method = dau} @ @ @ @  @result{} @command{unur_dau_new}
(@pxref{DAU})
@table @code
@item urnfactor = @i{<double>}
@result{} @pxref{funct:unur_dau_set_urnfactor,,@command{unur_dau_set_urnfactor}}
@end table

@item @code{method = dgt} @ @ @ @  @result{} @command{unur_dgt_new}
(@pxref{DGT})
@table @code
@item guidefactor = @i{<double>}
@result{} @pxref{funct:unur_dgt_set_guidefactor,,@command{unur_dgt_set_guidefactor}}
@item variant = @i{<unsigned>}
@result{} @pxref{funct:unur_dgt_set_variant,,@command{unur_dgt_set_variant}}
@end table

@item @code{method = dsrou} @ @ @ @  @result{} @command{unur_dsrou_new}
(@pxref{DSROU})
@table @code
@item cdfatmode = @i{<double>}
@result{} @pxref{funct:unur_dsrou_set_cdfatmode,,@command{unur_dsrou_set_cdfatmode}}
@item verify [= @i{<int>}]
@result{} @pxref{funct:unur_dsrou_set_verify,,@command{unur_dsrou_set_verify}}
@end table

@item @code{method = dstd} @ @ @ @  @result{} @command{unur_dstd_new}
(@pxref{DSTD})
@table @code
@item variant = @i{<unsigned>}
@result{} @pxref{funct:unur_dstd_set_variant,,@command{unur_dstd_set_variant}}
@end table

@item @code{method = empk} @ @ @ @  @result{} @command{unur_empk_new}
(@pxref{EMPK})
@table @code
@item beta = @i{<double>}
@result{} @pxref{funct:unur_empk_set_beta,,@command{unur_empk_set_beta}}
@item kernel = @i{<unsigned>}
@result{} @pxref{funct:unur_empk_set_kernel,,@command{unur_empk_set_kernel}}
@item positive [= @i{<int>}]
@result{} @pxref{funct:unur_empk_set_positive,,@command{unur_empk_set_positive}}
@item smoothing = @i{<double>}
@result{} @pxref{funct:unur_empk_set_smoothing,,@command{unur_empk_set_smoothing}}
@item varcor [= @i{<int>}]
@result{} @pxref{funct:unur_empk_set_varcor,,@command{unur_empk_set_varcor}}
@end table

@item @code{method = gibbs} @ @ @ @  @result{} @command{unur_gibbs_new}
(@pxref{GIBBS})
@table @code
@item burnin [= @i{<int>}]
@result{} @pxref{funct:unur_gibbs_set_burnin,,@command{unur_gibbs_set_burnin}}
@item c = @i{<double>}
@result{} @pxref{funct:unur_gibbs_set_c,,@command{unur_gibbs_set_c}}
@item thinning [= @i{<int>}]
@result{} @pxref{funct:unur_gibbs_set_thinning,,@command{unur_gibbs_set_thinning}}
@item variant_coordinate
@result{} @pxref{funct:unur_gibbs_set_variant_coordinate,,@command{unur_gibbs_set_variant_coordinate}}
@item variant_random_direction
@result{} @pxref{funct:unur_gibbs_set_variant_random_direction,,@command{unur_gibbs_set_variant_random_direction}}
@end table

@item @code{method = hinv} @ @ @ @  @result{} @command{unur_hinv_new}
(@pxref{HINV})
@table @code
@item boundary = @i{<double>}, @i{<double>} | (@i{<list>})
@result{} @pxref{funct:unur_hinv_set_boundary,,@command{unur_hinv_set_boundary}}
@item cpoints = (@i{<list>}), @i{<int>}
@result{} @pxref{funct:unur_hinv_set_cpoints,,@command{unur_hinv_set_cpoints}}
@item guidefactor = @i{<double>}
@result{} @pxref{funct:unur_hinv_set_guidefactor,,@command{unur_hinv_set_guidefactor}}
@item max_intervals [= @i{<int>}]
@result{} @pxref{funct:unur_hinv_set_max_intervals,,@command{unur_hinv_set_max_intervals}}
@item order [= @i{<int>}]
@result{} @pxref{funct:unur_hinv_set_order,,@command{unur_hinv_set_order}}
@item u_resolution = @i{<double>}
@result{} @pxref{funct:unur_hinv_set_u_resolution,,@command{unur_hinv_set_u_resolution}}
@end table

@item @code{method = hitro} @ @ @ @  @result{} @command{unur_hitro_new}
(@pxref{HITRO})
@table @code
@item adaptive_multiplier = @i{<double>}
@result{} @pxref{funct:unur_hitro_set_adaptive_multiplier,,@command{unur_hitro_set_adaptive_multiplier}}
@item burnin [= @i{<int>}]
@result{} @pxref{funct:unur_hitro_set_burnin,,@command{unur_hitro_set_burnin}}
@item r = @i{<double>}
@result{} @pxref{funct:unur_hitro_set_r,,@command{unur_hitro_set_r}}
@item thinning [= @i{<int>}]
@result{} @pxref{funct:unur_hitro_set_thinning,,@command{unur_hitro_set_thinning}}
@item use_adaptiveline [= @i{<int>}]
@result{} @pxref{funct:unur_hitro_set_use_adaptiveline,,@command{unur_hitro_set_use_adaptiveline}}
@item use_adaptiverectangle [= @i{<int>}]
@result{} @pxref{funct:unur_hitro_set_use_adaptiverectangle,,@command{unur_hitro_set_use_adaptiverectangle}}
@item use_boundingrectangle [= @i{<int>}]
@result{} @pxref{funct:unur_hitro_set_use_boundingrectangle,,@command{unur_hitro_set_use_boundingrectangle}}
@item v = @i{<double>}
@result{} @pxref{funct:unur_hitro_set_v,,@command{unur_hitro_set_v}}
@item variant_coordinate
@result{} @pxref{funct:unur_hitro_set_variant_coordinate,,@command{unur_hitro_set_variant_coordinate}}
@item variant_random_direction
@result{} @pxref{funct:unur_hitro_set_variant_random_direction,,@command{unur_hitro_set_variant_random_direction}}
@end table

@item @code{method = hrb} @ @ @ @  @result{} @command{unur_hrb_new}
(@pxref{HRB})
@table @code
@item upperbound = @i{<double>}
@result{} @pxref{funct:unur_hrb_set_upperbound,,@command{unur_hrb_set_upperbound}}
@item verify [= @i{<int>}]
@result{} @pxref{funct:unur_hrb_set_verify,,@command{unur_hrb_set_verify}}
@end table

@item @code{method = hrd} @ @ @ @  @result{} @command{unur_hrd_new}
(@pxref{HRD})
@table @code
@item verify [= @i{<int>}]
@result{} @pxref{funct:unur_hrd_set_verify,,@command{unur_hrd_set_verify}}
@end table

@item @code{method = hri} @ @ @ @  @result{} @command{unur_hri_new}
(@pxref{HRI})
@table @code
@item p0 = @i{<double>}
@result{} @pxref{funct:unur_hri_set_p0,,@command{unur_hri_set_p0}}
@item verify [= @i{<int>}]
@result{} @pxref{funct:unur_hri_set_verify,,@command{unur_hri_set_verify}}
@end table

@item @code{method = itdr} @ @ @ @  @result{} @command{unur_itdr_new}
(@pxref{ITDR})
@table @code
@item cp = @i{<double>}
@result{} @pxref{funct:unur_itdr_set_cp,,@command{unur_itdr_set_cp}}
@item ct = @i{<double>}
@result{} @pxref{funct:unur_itdr_set_ct,,@command{unur_itdr_set_ct}}
@item verify [= @i{<int>}]
@result{} @pxref{funct:unur_itdr_set_verify,,@command{unur_itdr_set_verify}}
@item xi = @i{<double>}
@result{} @pxref{funct:unur_itdr_set_xi,,@command{unur_itdr_set_xi}}
@end table

@item @code{method = mvtdr} @ @ @ @  @result{} @command{unur_mvtdr_new}
(@pxref{MVTDR})
@table @code
@item boundsplitting = @i{<double>}
@result{} @pxref{funct:unur_mvtdr_set_boundsplitting,,@command{unur_mvtdr_set_boundsplitting}}
@item maxcones [= @i{<int>}]
@result{} @pxref{funct:unur_mvtdr_set_maxcones,,@command{unur_mvtdr_set_maxcones}}
@item stepsmin [= @i{<int>}]
@result{} @pxref{funct:unur_mvtdr_set_stepsmin,,@command{unur_mvtdr_set_stepsmin}}
@item verify [= @i{<int>}]
@result{} @pxref{funct:unur_mvtdr_set_verify,,@command{unur_mvtdr_set_verify}}
@end table

@item @code{method = ninv} @ @ @ @  @result{} @command{unur_ninv_new}
(@pxref{NINV})
@table @code
@item max_iter [= @i{<int>}]
@result{} @pxref{funct:unur_ninv_set_max_iter,,@command{unur_ninv_set_max_iter}}
@item start = @i{<double>}, @i{<double>} | (@i{<list>})
@result{} @pxref{funct:unur_ninv_set_start,,@command{unur_ninv_set_start}}
@item table [= @i{<int>}]
@result{} @pxref{funct:unur_ninv_set_table,,@command{unur_ninv_set_table}}
@item u_resolution = @i{<double>}
@result{} @pxref{funct:unur_ninv_set_u_resolution,,@command{unur_ninv_set_u_resolution}}
@item usebisect
@result{} @pxref{funct:unur_ninv_set_usebisect,,@command{unur_ninv_set_usebisect}}
@item usenewton
@result{} @pxref{funct:unur_ninv_set_usenewton,,@command{unur_ninv_set_usenewton}}
@item useregula
@result{} @pxref{funct:unur_ninv_set_useregula,,@command{unur_ninv_set_useregula}}
@item x_resolution = @i{<double>}
@result{} @pxref{funct:unur_ninv_set_x_resolution,,@command{unur_ninv_set_x_resolution}}
@end table

@item @code{method = nrou} @ @ @ @  @result{} @command{unur_nrou_new}
(@pxref{NROU})
@table @code
@item center = @i{<double>}
@result{} @pxref{funct:unur_nrou_set_center,,@command{unur_nrou_set_center}}
@item r = @i{<double>}
@result{} @pxref{funct:unur_nrou_set_r,,@command{unur_nrou_set_r}}
@item u = @i{<double>}, @i{<double>} | (@i{<list>})
@result{} @pxref{funct:unur_nrou_set_u,,@command{unur_nrou_set_u}}
@item v = @i{<double>}
@result{} @pxref{funct:unur_nrou_set_v,,@command{unur_nrou_set_v}}
@item verify [= @i{<int>}]
@result{} @pxref{funct:unur_nrou_set_verify,,@command{unur_nrou_set_verify}}
@end table

@item @code{method = pinv} @ @ @ @  @result{} @command{unur_pinv_new}
(@pxref{PINV})
@table @code
@item boundary = @i{<double>}, @i{<double>} | (@i{<list>})
@result{} @pxref{funct:unur_pinv_set_boundary,,@command{unur_pinv_set_boundary}}
@item extra_testpoints [= @i{<int>}]
@result{} @pxref{funct:unur_pinv_set_extra_testpoints,,@command{unur_pinv_set_extra_testpoints}}
@item keepcdf [= @i{<int>}]
@result{} @pxref{funct:unur_pinv_set_keepcdf,,@command{unur_pinv_set_keepcdf}}
@item max_intervals [= @i{<int>}]
@result{} @pxref{funct:unur_pinv_set_max_intervals,,@command{unur_pinv_set_max_intervals}}
@item order [= @i{<int>}]
@result{} @pxref{funct:unur_pinv_set_order,,@command{unur_pinv_set_order}}
@item searchboundary = @i{<int>}, @i{<int>} | (@i{<list>})
@result{} @pxref{funct:unur_pinv_set_searchboundary,,@command{unur_pinv_set_searchboundary}}
@item smoothness [= @i{<int>}]
@result{} @pxref{funct:unur_pinv_set_smoothness,,@command{unur_pinv_set_smoothness}}
@item u_resolution = @i{<double>}
@result{} @pxref{funct:unur_pinv_set_u_resolution,,@command{unur_pinv_set_u_resolution}}
@item use_upoints [= @i{<int>}]
@result{} @pxref{funct:unur_pinv_set_use_upoints,,@command{unur_pinv_set_use_upoints}}
@item usecdf
@result{} @pxref{funct:unur_pinv_set_usecdf,,@command{unur_pinv_set_usecdf}}
@item usepdf
@result{} @pxref{funct:unur_pinv_set_usepdf,,@command{unur_pinv_set_usepdf}}
@end table

@item @code{method = srou} @ @ @ @  @result{} @command{unur_srou_new}
(@pxref{SROU})
@table @code
@item cdfatmode = @i{<double>}
@result{} @pxref{funct:unur_srou_set_cdfatmode,,@command{unur_srou_set_cdfatmode}}
@item pdfatmode = @i{<double>}
@result{} @pxref{funct:unur_srou_set_pdfatmode,,@command{unur_srou_set_pdfatmode}}
@item r = @i{<double>}
@result{} @pxref{funct:unur_srou_set_r,,@command{unur_srou_set_r}}
@item usemirror [= @i{<int>}]
@result{} @pxref{funct:unur_srou_set_usemirror,,@command{unur_srou_set_usemirror}}
@item usesqueeze [= @i{<int>}]
@result{} @pxref{funct:unur_srou_set_usesqueeze,,@command{unur_srou_set_usesqueeze}}
@item verify [= @i{<int>}]
@result{} @pxref{funct:unur_srou_set_verify,,@command{unur_srou_set_verify}}
@end table

@item @code{method = ssr} @ @ @ @  @result{} @command{unur_ssr_new}
(@pxref{SSR})
@table @code
@item cdfatmode = @i{<double>}
@result{} @pxref{funct:unur_ssr_set_cdfatmode,,@command{unur_ssr_set_cdfatmode}}
@item pdfatmode = @i{<double>}
@result{} @pxref{funct:unur_ssr_set_pdfatmode,,@command{unur_ssr_set_pdfatmode}}
@item usesqueeze [= @i{<int>}]
@result{} @pxref{funct:unur_ssr_set_usesqueeze,,@command{unur_ssr_set_usesqueeze}}
@item verify [= @i{<int>}]
@result{} @pxref{funct:unur_ssr_set_verify,,@command{unur_ssr_set_verify}}
@end table

@item @code{method = tabl} @ @ @ @  @result{} @command{unur_tabl_new}
(@pxref{TABL})
@table @code
@item areafraction = @i{<double>}
@result{} @pxref{funct:unur_tabl_set_areafraction,,@command{unur_tabl_set_areafraction}}
@item boundary = @i{<double>}, @i{<double>} | (@i{<list>})
@result{} @pxref{funct:unur_tabl_set_boundary,,@command{unur_tabl_set_boundary}}
@item cpoints = @i{<int>} [, (@i{<list>})] | (@i{<list>})
@result{} @pxref{funct:unur_tabl_set_cpoints,,@command{unur_tabl_set_cpoints}}
@item darsfactor = @i{<double>}
@result{} @pxref{funct:unur_tabl_set_darsfactor,,@command{unur_tabl_set_darsfactor}}
@item guidefactor = @i{<double>}
@result{} @pxref{funct:unur_tabl_set_guidefactor,,@command{unur_tabl_set_guidefactor}}
@item max_intervals [= @i{<int>}]
@result{} @pxref{funct:unur_tabl_set_max_intervals,,@command{unur_tabl_set_max_intervals}}
@item max_sqhratio = @i{<double>}
@result{} @pxref{funct:unur_tabl_set_max_sqhratio,,@command{unur_tabl_set_max_sqhratio}}
@item nstp [= @i{<int>}]
@result{} @pxref{funct:unur_tabl_set_nstp,,@command{unur_tabl_set_nstp}}
@item pedantic [= @i{<int>}]
@result{} @pxref{funct:unur_tabl_set_pedantic,,@command{unur_tabl_set_pedantic}}
@item slopes = (@i{<list>}), @i{<int>}
@result{} @pxref{funct:unur_tabl_set_slopes,,@command{unur_tabl_set_slopes}}
@item usedars [= @i{<int>}]
@result{} @pxref{funct:unur_tabl_set_usedars,,@command{unur_tabl_set_usedars}}
@item useear [= @i{<int>}]
@result{} @pxref{funct:unur_tabl_set_useear,,@command{unur_tabl_set_useear}}
@item variant_ia [= @i{<int>}]
@result{} @pxref{funct:unur_tabl_set_variant_ia,,@command{unur_tabl_set_variant_ia}}
@item variant_splitmode = @i{<unsigned>}
@result{} @pxref{funct:unur_tabl_set_variant_splitmode,,@command{unur_tabl_set_variant_splitmode}}
@item verify [= @i{<int>}]
@result{} @pxref{funct:unur_tabl_set_verify,,@command{unur_tabl_set_verify}}
@end table

@item @code{method = tdr} @ @ @ @  @result{} @command{unur_tdr_new}
(@pxref{TDR})
@table @code
@item c = @i{<double>}
@result{} @pxref{funct:unur_tdr_set_c,,@command{unur_tdr_set_c}}
@item cpoints = @i{<int>} [, (@i{<list>})] | (@i{<list>})
@result{} @pxref{funct:unur_tdr_set_cpoints,,@command{unur_tdr_set_cpoints}}
@item darsfactor = @i{<double>}
@result{} @pxref{funct:unur_tdr_set_darsfactor,,@command{unur_tdr_set_darsfactor}}
@item guidefactor = @i{<double>}
@result{} @pxref{funct:unur_tdr_set_guidefactor,,@command{unur_tdr_set_guidefactor}}
@item max_intervals [= @i{<int>}]
@result{} @pxref{funct:unur_tdr_set_max_intervals,,@command{unur_tdr_set_max_intervals}}
@item max_sqhratio = @i{<double>}
@result{} @pxref{funct:unur_tdr_set_max_sqhratio,,@command{unur_tdr_set_max_sqhratio}}
@item pedantic [= @i{<int>}]
@result{} @pxref{funct:unur_tdr_set_pedantic,,@command{unur_tdr_set_pedantic}}
@item reinit_ncpoints [= @i{<int>}]
@result{} @pxref{funct:unur_tdr_set_reinit_ncpoints,,@command{unur_tdr_set_reinit_ncpoints}}
@item reinit_percentiles = @i{<int>} [, (@i{<list>})] | (@i{<list>})
@result{} @pxref{funct:unur_tdr_set_reinit_percentiles,,@command{unur_tdr_set_reinit_percentiles}}
@item usecenter [= @i{<int>}]
@result{} @pxref{funct:unur_tdr_set_usecenter,,@command{unur_tdr_set_usecenter}}
@item usedars [= @i{<int>}]
@result{} @pxref{funct:unur_tdr_set_usedars,,@command{unur_tdr_set_usedars}}
@item usemode [= @i{<int>}]
@result{} @pxref{funct:unur_tdr_set_usemode,,@command{unur_tdr_set_usemode}}
@item variant_gw
@result{} @pxref{funct:unur_tdr_set_variant_gw,,@command{unur_tdr_set_variant_gw}}
@item variant_ia
@result{} @pxref{funct:unur_tdr_set_variant_ia,,@command{unur_tdr_set_variant_ia}}
@item variant_ps
@result{} @pxref{funct:unur_tdr_set_variant_ps,,@command{unur_tdr_set_variant_ps}}
@item verify [= @i{<int>}]
@result{} @pxref{funct:unur_tdr_set_verify,,@command{unur_tdr_set_verify}}
@end table

@item @code{method = utdr} @ @ @ @  @result{} @command{unur_utdr_new}
(@pxref{UTDR})
@table @code
@item cpfactor = @i{<double>}
@result{} @pxref{funct:unur_utdr_set_cpfactor,,@command{unur_utdr_set_cpfactor}}
@item deltafactor = @i{<double>}
@result{} @pxref{funct:unur_utdr_set_deltafactor,,@command{unur_utdr_set_deltafactor}}
@item pdfatmode = @i{<double>}
@result{} @pxref{funct:unur_utdr_set_pdfatmode,,@command{unur_utdr_set_pdfatmode}}
@item verify [= @i{<int>}]
@result{} @pxref{funct:unur_utdr_set_verify,,@command{unur_utdr_set_verify}}
@end table

@item @code{method = vempk} @ @ @ @  @result{} @command{unur_vempk_new}
(@pxref{VEMPK})
@table @code
@item smoothing = @i{<double>}
@result{} @pxref{funct:unur_vempk_set_smoothing,,@command{unur_vempk_set_smoothing}}
@item varcor [= @i{<int>}]
@result{} @pxref{funct:unur_vempk_set_varcor,,@command{unur_vempk_set_varcor}}
@end table

@item @code{method = vnrou} @ @ @ @  @result{} @command{unur_vnrou_new}
(@pxref{VNROU})
@table @code
@item r = @i{<double>}
@result{} @pxref{funct:unur_vnrou_set_r,,@command{unur_vnrou_set_r}}
@item v = @i{<double>}
@result{} @pxref{funct:unur_vnrou_set_v,,@command{unur_vnrou_set_v}}
@item verify [= @i{<int>}]
@result{} @pxref{funct:unur_vnrou_set_verify,,@command{unur_vnrou_set_verify}}
@end table

@end itemize




@c
@c end of stringparser_doc.dh
@c -------------------------------------
@c -------------------------------------
@c parser.h
@c

@page
@node StringURNG
@section   Uniform RNG String



The value of the @code{urng} key is passed to the PRNG interface (see
@ifinfo
@xref{Top,,Overview,prng,PRNG Manual}.
@end ifinfo
@ifnotinfo
@uref{http://statmath.wu.ac.at/prng/manual/,PRNG manual}
@end ifnotinfo
for details).
However it only works when using the PRNG library is enabled,
see @ref{Installation} for details. There are no other keys.

IMPORTANT: UNU.RAN creates a new uniform random number generator for
the generator object. The pointer to this uniform generator
has to be read and saved via a
@ifhtml
@ref{funct:unur_get_urng,@command{unur_get_urng}}
@end ifhtml
@ifnothtml
@command{unur_get_urng}
@end ifnothtml
call in order to
clear the memory @emph{before} the UNU.RAN generator object is
destroyed.

If this block is omitted the UNU.RAN default generator is used
(which @emph{must not} be destroyed).



@c
@c end of parser.h
@c -------------------------------------
@c -------------------------------------
@c distr.h
@c

@page
@node Distribution_objects
@chapter   Handling distribution objects

@menu
* AllDistr:: Functions for all kinds of distribution objects
* CONT:: Continuous univariate distributions
* CORDER:: Continuous univariate order statistics
* CEMP:: Continuous empirical univariate distributions
* CVEC:: Continuous multivariate distributions
* CONDI:: Continuous univariate full conditional distribution
* CVEMP:: Continuous empirical multivariate distributions
* MATR:: MATRix distributions
* DISCR:: Discrete univariate distributions
@end menu


Objects of type @code{UNUR_DISTR} are used for handling
distributions. All data about a distribution are stored in this
object. UNU.RAN provides functions that return instances of such
objects for standard distributions
(@pxref{Stddist,,Standard distributions}).
It is then possible to change these distribution objects by
various set calls. Moreover, it is possible to build a
distribution object entirely from scratch. For this purpose
there exists @command{unur_distr_<type>_new} calls that
return an empty object of this type for each object type
(eg. univariate contiuous) which can be filled with the
appropriate set calls.

UNU.RAN distinguishes between several types of distributions,
each of which has its own sets of possible parameters (for
details see the corresponding sections):
@itemize @minus
@item continuous univariate distributions
@item continuous univariate order statistics
@item continuous empirical univariate distributions
@item continuous multivariate distributions
@item continuous empirical multivariate distributions
@item matrix distributions
@item discrete univariate distributions
@end itemize

Notice that there are essential data about a distribution,
eg. the PDF, a list of (shape, scale, location) parameters for
the distribution, and the domain of (the possibly truncated)
distribution. And there exist parameters that are/can be
derived from these, eg. the mode of the distribution or the area
below the given PDF (which need not be normalized for many
methods). UNU.RAN keeps track of parameters which are
known. Thus if one of the essential parameters is changed all
derived parameters are marked as unknown and must be set again
if these are required for the chosen generation method.
Additionally to set calls there are calls for updating derived
parameters for objects provided by the UNU.RAN library of standard
distributions (one for each parameter to avoid computational
overhead since not all parameters are required for all generator
methods).

All parameters of distribution objects can be read by
corresponding get calls.

Every generator object has its own copy of a distribution object
which is accessible by a
@ifhtml
@ref{funct:unur_get_distr,@command{unur_get_distr}}
@end ifhtml
@ifnothtml
@command{unur_get_distr}
@end ifnothtml
call. Thus the
parameter for this distribution can be read. However,
@strong{never} extract the distribution object out of a
generator object and run one of the set calls on it to modify
the distribution.  (How should the poor generator object know
what has happend?) Instead there exist calls for each of the
generator methods that change particular parameters of the
internal copy of the distribution object.


@subsubheading How To Use


UNU.RAN collects all data required for a particular generation
method in a @emph{distribution object}. There are two ways to
get an instance of a distributions object:
@enumerate
@item
Build a distribtion from scratch, by means of
the corresponding @command{unur_distr_<type>_new} call,
where @command{<type>} is the type of the distribution as
listed in the below subsections.

@item
Use the corresponding @command{unur_distr_<name>_new} call
to get prebuild distribution from the UNU.RAN library of standard
distributions.
Here @command{<name>} is the name of the
standard distribution in @ref{Stddist,,Standard distributions}.
@end enumerate

In either cases the corresponding
@command{unur_distr_<type>_set_<param>} calls to set the
necessary parameters @command{<param>} (case 1), or
change the values of the standard distribution in case 2 (if
this makes sense for you). In the latter case @command{<type>}
is the type to which the standard distribution belongs to.
These @command{set} calls return @code{UNUR_SUCCESS} when the
correspondig parameter has been set successfully. Otherwise an
error code is returned.

The parameters of a distribution are divided into
@emph{essential} and @emph{derived} parameters.

Notice, that there are some restrictions in setting parameters
to avoid possible confusions.
Changing essential parameters marks derived parameters as
@code{unknown}. Some of the parameters cannot be changed any
more when already set; some parameters block each others.
In such a case a new instance of a distribution object has to be
build.

Additionally @command{unur_distr_<type>_upd_<param>} calls can
be used for updating derived parameters for objects provided by
the UNU.RAN library of standard distributions.

All parameters of a distribution object get be read by means of
@command{unur_distr_<type>_get_<param>} calls.

Every distribution object be identified by its @code{name} which
is a string of arbitrary characters provided by the user. For
standard distribution it is automatically set to
@command{<name>} in the corresponding @command{new} call. It can
be changed to any other string.





@c
@c end of distr.h
@c -------------------------------------
@c -------------------------------------
@c distr.h
@c

@page
@node AllDistr
@section   Functions for all kinds of distribution objects


The calls in this section can be applied to all distribution
objects.

@itemize @minus
@item Destroy @command{free} an instance of a generator object.

@item Ask for the @command{type} of a generator object.

@item Ask for the @command{dimension} of a generator object.

@item Deal with the @command{name} (identifier string) of a generator object.
@end itemize


@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_distr_free,unur_distr_free}
@item @ref{funct:unur_distr_set_name,unur_distr_set_name}
@item @ref{funct:unur_distr_get_name,unur_distr_get_name}
@item @ref{funct:unur_distr_get_dim,unur_distr_get_dim}
@item @ref{funct:unur_distr_get_type,unur_distr_get_type}
@item @ref{funct:unur_distr_is_cont,unur_distr_is_cont}
@item @ref{funct:unur_distr_is_cvec,unur_distr_is_cvec}
@item @ref{funct:unur_distr_is_cemp,unur_distr_is_cemp}
@item @ref{funct:unur_distr_is_cvemp,unur_distr_is_cvemp}
@item @ref{funct:unur_distr_is_discr,unur_distr_is_discr}
@item @ref{funct:unur_distr_is_matr,unur_distr_is_matr}
@item @ref{funct:unur_distr_set_extobj,unur_distr_set_extobj}
@item @ref{funct:unur_distr_get_extobj,unur_distr_get_extobj}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_distr_free}
@deftypefn Function {void} unur_distr_free (UNUR_DISTR* @var{distribution})
Destroy the @var{distribution} object.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_free}
@deftypefn {} {void} unur_distr_free (UNUR_DISTR* @var{distribution})
Destroy the @var{distribution} object.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_set_name}
@anchor{funct:unur_distr_get_name}
@deftypefn Function {int} unur_distr_set_name (UNUR_DISTR* @var{distribution}, const @var{char* name})
@deftypefnx Function {const char*} unur_distr_get_name (const @var{UNUR_DISTR* distribution})
Set and get @var{name} of @var{distribution}. The @var{name} can be
an arbitrary character string. It can be used to identify generator
objects for the user. It is used by UNU.RAN when printing
information of the distribution object into a log files.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_set_name}
@anchor{funct:unur_distr_get_name}
@deftypefn {} {int} unur_distr_set_name (UNUR_DISTR* @var{distribution}, const @var{char* name})
@deftypefnx {} {const char*} unur_distr_get_name (const @var{UNUR_DISTR* distribution})
Set and get @var{name} of @var{distribution}. The @var{name} can be
an arbitrary character string. It can be used to identify generator
objects for the user. It is used by UNU.RAN when printing
information of the distribution object into a log files.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_get_dim}
@deftypefn Function {int} unur_distr_get_dim (const @var{UNUR_DISTR* distribution})
Get number of components of a random vector (its dimension) the
@var{distribution}.

For univariate distributions it returns dimension @code{1}.

For matrix distributions it returns the number of components
(i.e., number of rows times number of columns).
When the respective numbers of rows and columns are needed use
@ifhtml
@ref{funct:unur_distr_matr_get_dim,@command{unur_distr_matr_get_dim}}
@end ifhtml
@ifnothtml
@command{unur_distr_matr_get_dim}
@end ifnothtml
instead.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_get_dim}
@deftypefn {} {int} unur_distr_get_dim (const @var{UNUR_DISTR* distribution})
Get number of components of a random vector (its dimension) the
@var{distribution}.

For univariate distributions it returns dimension @code{1}.

For matrix distributions it returns the number of components
(i.e., number of rows times number of columns).
When the respective numbers of rows and columns are needed use
@ifhtml
@ref{funct:unur_distr_matr_get_dim,@command{unur_distr_matr_get_dim}}
@end ifhtml
@ifnothtml
@command{unur_distr_matr_get_dim}
@end ifnothtml
instead.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_get_type}
@deftypefn Function {unsigned int} unur_distr_get_type (const @var{UNUR_DISTR* distribution})
Get type of @var{distribution}.
Possible types are
@table @code
@item UNUR_DISTR_CONT
univariate continuous distribution
@item UNUR_DISTR_CEMP
empirical continuous univariate distribution (i.e. a sample)
@item UNUR_DISTR_CVEC
continuous mulitvariate distribution
@item UNUR_DISTR_CVEMP
empirical continuous multivariate distribution (i.e. a vector sample)
@item UNUR_DISTR_DISCR
discrete univariate distribution
@item UNUR_DISTR_MATR
matrix distribution
@end table

Alternatively the @command{unur_distr_is_<TYPE>}
calls can be used.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_get_type}
@deftypefn {} {unsigned int} unur_distr_get_type (const @var{UNUR_DISTR* distribution})
Get type of @var{distribution}.
Possible types are
@table @code
@item UNUR_DISTR_CONT
univariate continuous distribution
@item UNUR_DISTR_CEMP
empirical continuous univariate distribution (i.e. a sample)
@item UNUR_DISTR_CVEC
continuous mulitvariate distribution
@item UNUR_DISTR_CVEMP
empirical continuous multivariate distribution (i.e. a vector sample)
@item UNUR_DISTR_DISCR
discrete univariate distribution
@item UNUR_DISTR_MATR
matrix distribution
@end table

Alternatively the @command{unur_distr_is_<TYPE>}
calls can be used.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_is_cont}
@deftypefn Function {int} unur_distr_is_cont (const @var{UNUR_DISTR* distribution})
@code{TRUE} if @var{distribution} is a continuous univariate distribution.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_is_cont}
@deftypefn {} {int} unur_distr_is_cont (const @var{UNUR_DISTR* distribution})
@code{TRUE} if @var{distribution} is a continuous univariate distribution.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_is_cvec}
@deftypefn Function {int} unur_distr_is_cvec (const @var{UNUR_DISTR* distribution})
@code{TRUE} if @var{distribution} is a continuous multivariate distribution.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_is_cvec}
@deftypefn {} {int} unur_distr_is_cvec (const @var{UNUR_DISTR* distribution})
@code{TRUE} if @var{distribution} is a continuous multivariate distribution.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_is_cemp}
@deftypefn Function {int} unur_distr_is_cemp (const @var{UNUR_DISTR* distribution})
@code{TRUE} if @var{distribution} is an empirical continuous univariate distribution,
i.e. a sample.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_is_cemp}
@deftypefn {} {int} unur_distr_is_cemp (const @var{UNUR_DISTR* distribution})
@code{TRUE} if @var{distribution} is an empirical continuous univariate distribution,
i.e. a sample.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_is_cvemp}
@deftypefn Function {int} unur_distr_is_cvemp (const @var{UNUR_DISTR* distribution})
@code{TRUE} if @var{distribution} is an empirical continuous multivariate
distribution.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_is_cvemp}
@deftypefn {} {int} unur_distr_is_cvemp (const @var{UNUR_DISTR* distribution})
@code{TRUE} if @var{distribution} is an empirical continuous multivariate
distribution.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_is_discr}
@deftypefn Function {int} unur_distr_is_discr (const @var{UNUR_DISTR* distribution})
@code{TRUE} if @var{distribution} is a discrete univariate distribution.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_is_discr}
@deftypefn {} {int} unur_distr_is_discr (const @var{UNUR_DISTR* distribution})
@code{TRUE} if @var{distribution} is a discrete univariate distribution.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_is_matr}
@deftypefn Function {int} unur_distr_is_matr (const @var{UNUR_DISTR* distribution})
@code{TRUE} if @var{distribution} is a matrix distribution.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_is_matr}
@deftypefn {} {int} unur_distr_is_matr (const @var{UNUR_DISTR* distribution})
@code{TRUE} if @var{distribution} is a matrix distribution.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_set_extobj}
@deftypefn Function {int} unur_distr_set_extobj (UNUR_DISTR* @var{distribution}, const @var{void* extobj})
Store a pointer to an external object. This might be usefull if
the PDF, PMF, CDF or other functions used to implement a particular
distribution a parameter set that cannot be stored as doubles
(e.g. pointers to some structure that holds information of the distribution).

@strong{Important:}
When UNU.RAN copies this distribution object into the generator object,
then the address @var{extobj} that this pointer contains is simply copied.
Thus the generator holds an address of a non-private object!
Once the generator object has been created any change in the external
object might effect the generator object.

@strong{Warning:}
External objects must be used with care. Once the generator object has been
created or the distribution object has been copied you @emph{must not}
destroy this external object.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_set_extobj}
@deftypefn {} {int} unur_distr_set_extobj (UNUR_DISTR* @var{distribution}, const @var{void* extobj})
Store a pointer to an external object. This might be usefull if
the PDF, PMF, CDF or other functions used to implement a particular
distribution a parameter set that cannot be stored as doubles
(e.g. pointers to some structure that holds information of the distribution).

@strong{Important:}
When UNU.RAN copies this distribution object into the generator object,
then the address @var{extobj} that this pointer contains is simply copied.
Thus the generator holds an address of a non-private object!
Once the generator object has been created any change in the external
object might effect the generator object.

@strong{Warning:}
External objects must be used with care. Once the generator object has been
created or the distribution object has been copied you @emph{must not}
destroy this external object.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_get_extobj}
@deftypefn Function {const void*} unur_distr_get_extobj (const @var{UNUR_DISTR* distribution})
Get the pointer to the external object.

@emph{Important:}
Changing this object must be done with with extreme care.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_get_extobj}
@deftypefn {} {const void*} unur_distr_get_extobj (const @var{UNUR_DISTR* distribution})
Get the pointer to the external object.

@emph{Important:}
Changing this object must be done with with extreme care.
@end deftypefn
@end ifnotinfo




@c
@c end of distr.h
@c -------------------------------------
@c -------------------------------------
@c cont.h
@c

@page
@node CONT
@section   Continuous univariate distributions


The calls in this section can be applied to continuous
univariate distributions.

@itemize @minus
@item Create a @command{new} instance of a continuous univariate
distribution.

@item Handle and evaluate
distribution function (CDF, @command{cdf}),
probability density function (PDF, @command{pdf}) and the
derivative of the density function (@command{dpdf}).
The following is important:
@itemize .
@item @command{pdf} need not be normalized, i.e.,
any integrable nonnegative function can be used.
@item @command{dpdf} must the derivate of the function provided
as @command{pdf}.
@item @command{cdf} must be a distribution function, i.e. it
must be monotonically increasing with range [0,1].
@item If @command{cdf} and @command{pdf} are used together for a
pariticular generation method, then @command{pdf} must be the
derivate of the @command{cdf}, i.e., it must be normalized.
@end itemize

@item Handle and evaluate
the logarithm of the probability density function (logPDF,
@command{logpdf}) and the derivative of the logarithm of the
density function (@command{dlogpdf}).

Some methods use the logarithm of the density if available.

@item Set (and change) parameters (@command{pdfparams}) and the
area below the graph (@command{pdfarea}) of the given density.

@item Set the @command{mode} (or pole) of the distribution.

@item Set the @command{center} of the distribution.
It is used by some generation methods to adjust the parameters
of the generation algorithms to gain better performance. It can
be seens as the location of the ``central part'' of the
distribution.

@item Some generation methods require the hazard rate
(@command{hr}) of the distribution instead of its @command{pdf}.

@item Alternatively, @command{cdf}, @command{pdf}, @command{dpdf},
and @command{hr} can be provided as @command{str}ings instead of
function pointers.

@item Set the @command{domain} of the distribution.  Notice that
the library also can handle truncated distributions, i.e.,
distributions that are derived from (standard) distributions by
simply restricting its domain to a subset. However, there is a
subtle difference between changing the domain of a distribution
object by a
@ifhtml
@ref{funct:unur_distr_cont_set_domain,@command{unur_distr_cont_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_domain}
@end ifnothtml
call and changing the
(truncated) domain for an existing generator object. The domain
of the distribution object is used to create the generator
object with hats, squeezes, tables, etc.  Whereas truncating the
domain of an existing generator object need not necessarily
require a recomputation of these data.  Thus by a
@command{unur_<method>_chg_truncated} call (if available) the
sampling region is restricted to the subset of the domain of the
given distribution object. However, generation methods that
require a recreation of the generator object when the domain is
changed have a @command{unur_<method>_chg_domain} call instead.
For these calls there are of course no restrictions on the given
domain (i.e., it is possible to increase the domain of the
distribution) (@pxref{Methods}, for details).

@end itemize


@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_distr_cont_new,unur_distr_cont_new}
@item @ref{funct:unur_distr_cont_set_pdf,unur_distr_cont_set_pdf}
@item @ref{funct:unur_distr_cont_set_dpdf,unur_distr_cont_set_dpdf}
@item @ref{funct:unur_distr_cont_set_cdf,unur_distr_cont_set_cdf}
@item @ref{funct:unur_distr_cont_set_invcdf,unur_distr_cont_set_invcdf}
@item @ref{funct:unur_distr_cont_get_pdf,unur_distr_cont_get_pdf}
@item @ref{funct:unur_distr_cont_get_dpdf,unur_distr_cont_get_dpdf}
@item @ref{funct:unur_distr_cont_get_cdf,unur_distr_cont_get_cdf}
@item @ref{funct:unur_distr_cont_get_invcdf,unur_distr_cont_get_invcdf}
@item @ref{funct:unur_distr_cont_eval_pdf,unur_distr_cont_eval_pdf}
@item @ref{funct:unur_distr_cont_eval_dpdf,unur_distr_cont_eval_dpdf}
@item @ref{funct:unur_distr_cont_eval_cdf,unur_distr_cont_eval_cdf}
@item @ref{funct:unur_distr_cont_eval_invcdf,unur_distr_cont_eval_invcdf}
@item @ref{funct:unur_distr_cont_set_logpdf,unur_distr_cont_set_logpdf}
@item @ref{funct:unur_distr_cont_set_dlogpdf,unur_distr_cont_set_dlogpdf}
@item @ref{funct:unur_distr_cont_set_logcdf,unur_distr_cont_set_logcdf}
@item @ref{funct:unur_distr_cont_get_logpdf,unur_distr_cont_get_logpdf}
@item @ref{funct:unur_distr_cont_get_dlogpdf,unur_distr_cont_get_dlogpdf}
@item @ref{funct:unur_distr_cont_get_logcdf,unur_distr_cont_get_logcdf}
@item @ref{funct:unur_distr_cont_eval_logpdf,unur_distr_cont_eval_logpdf}
@item @ref{funct:unur_distr_cont_eval_dlogpdf,unur_distr_cont_eval_dlogpdf}
@item @ref{funct:unur_distr_cont_eval_logcdf,unur_distr_cont_eval_logcdf}
@item @ref{funct:unur_distr_cont_set_pdfstr,unur_distr_cont_set_pdfstr}
@item @ref{funct:unur_distr_cont_set_cdfstr,unur_distr_cont_set_cdfstr}
@item @ref{funct:unur_distr_cont_get_pdfstr,unur_distr_cont_get_pdfstr}
@item @ref{funct:unur_distr_cont_get_dpdfstr,unur_distr_cont_get_dpdfstr}
@item @ref{funct:unur_distr_cont_get_cdfstr,unur_distr_cont_get_cdfstr}
@item @ref{funct:unur_distr_cont_set_pdfparams,unur_distr_cont_set_pdfparams}
@item @ref{funct:unur_distr_cont_get_pdfparams,unur_distr_cont_get_pdfparams}
@item @ref{funct:unur_distr_cont_set_pdfparams_vec,unur_distr_cont_set_pdfparams_vec}
@item @ref{funct:unur_distr_cont_get_pdfparams_vec,unur_distr_cont_get_pdfparams_vec}
@item @ref{funct:unur_distr_cont_set_logpdfstr,unur_distr_cont_set_logpdfstr}
@item @ref{funct:unur_distr_cont_get_logpdfstr,unur_distr_cont_get_logpdfstr}
@item @ref{funct:unur_distr_cont_get_dlogpdfstr,unur_distr_cont_get_dlogpdfstr}
@item @ref{funct:unur_distr_cont_set_logcdfstr,unur_distr_cont_set_logcdfstr}
@item @ref{funct:unur_distr_cont_get_logcdfstr,unur_distr_cont_get_logcdfstr}
@item @ref{funct:unur_distr_cont_set_domain,unur_distr_cont_set_domain}
@item @ref{funct:unur_distr_cont_get_domain,unur_distr_cont_get_domain}
@item @ref{funct:unur_distr_cont_get_truncated,unur_distr_cont_get_truncated}
@item @ref{funct:unur_distr_cont_set_hr,unur_distr_cont_set_hr}
@item @ref{funct:unur_distr_cont_get_hr,unur_distr_cont_get_hr}
@item @ref{funct:unur_distr_cont_eval_hr,unur_distr_cont_eval_hr}
@item @ref{funct:unur_distr_cont_set_hrstr,unur_distr_cont_set_hrstr}
@item @ref{funct:unur_distr_cont_get_hrstr,unur_distr_cont_get_hrstr}
@item @ref{funct:unur_distr_cont_set_mode,unur_distr_cont_set_mode}
@item @ref{funct:unur_distr_cont_upd_mode,unur_distr_cont_upd_mode}
@item @ref{funct:unur_distr_cont_get_mode,unur_distr_cont_get_mode}
@item @ref{funct:unur_distr_cont_set_center,unur_distr_cont_set_center}
@item @ref{funct:unur_distr_cont_get_center,unur_distr_cont_get_center}
@item @ref{funct:unur_distr_cont_set_pdfarea,unur_distr_cont_set_pdfarea}
@item @ref{funct:unur_distr_cont_upd_pdfarea,unur_distr_cont_upd_pdfarea}
@item @ref{funct:unur_distr_cont_get_pdfarea,unur_distr_cont_get_pdfarea}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_distr_cont_new}
@deftypefn Function {UNUR_DISTR*} unur_distr_cont_new (void)
Create a new (empty) object for univariate continuous distribution.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_new}
@deftypefn {} {UNUR_DISTR*} unur_distr_cont_new (void)
Create a new (empty) object for univariate continuous distribution.
@end deftypefn
@end ifnotinfo

@subsubheading Essential parameters

@ifinfo
@anchor{funct:unur_distr_cont_set_pdf}
@anchor{funct:unur_distr_cont_set_dpdf}
@anchor{funct:unur_distr_cont_set_cdf}
@anchor{funct:unur_distr_cont_set_invcdf}
@deftypefn Function {int} unur_distr_cont_set_pdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_CONT* @var{pdf})
@deftypefnx Function {int} unur_distr_cont_set_dpdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_CONT* @var{dpdf})
@deftypefnx Function {int} unur_distr_cont_set_cdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_CONT* @var{cdf})
@deftypefnx Function {int} unur_distr_cont_set_invcdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_CONT* @var{invcdf})
Set respective pointer to the probability density function (PDF),
the derivative of the probability density function (dPDF), the
cumulative distribution function (CDF), and the inverse CDF of the
@var{distribution}.
Each of these function pointers must be of type
@code{double funct(double x, const UNUR_DISTR *distr)}.

Due to the fact that some of the methods do not require a
normalized PDF the following is important:

@itemize @minus
@item
The given CDF must be the cumulative distribution function of
the (non-truncated) distribution. If a distribution from the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions})
is truncated, there is no need to change the CDF.

@item
If both the CDF and the PDF are used (for a method or for order
statistics), the PDF must be the derivative of the CDF.
If a truncated distribution for one of the standard distributions
from the UNU.RAN library of standard distributions is used,
there is no need to change the PDF.

@item
If the area below the PDF is required for a given distribution
it must be given by the
@ifhtml
@ref{funct:unur_distr_cont_set_pdfarea,@command{unur_distr_cont_set_pdfarea}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_pdfarea}
@end ifnothtml
call.
For a truncated distribution this must be of course the integral of
the PDF in the given truncated domain.
For distributions from the UNU.RAN library of standard
distributions this is done automatically by the
@ifhtml
@ref{funct:unur_distr_cont_upd_pdfarea,@command{unur_distr_cont_upd_pdfarea}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_pdfarea}
@end ifnothtml
call.

@end itemize

It is important to note that all these functions must return a
result for all values of @var{x}. Eg., if the domain of a given
PDF is the interval [-1,1], then the given function must return
@code{0.0} for all points outside this interval.
In case of an overflow the PDF should return
@code{UNUR_INFINITY}.

It is not possible to change such a function. Once the PDF or
CDF is set it cannot be overwritten. This also holds when the
logPDF is given or when the PDF
is given by the
@ifhtml
@ref{funct:unur_distr_cont_set_pdfstr,@command{unur_distr_cont_set_pdfstr}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_pdfstr}
@end ifnothtml
or
@ifhtml
@ref{funct:unur_distr_cont_set_logpdfstr,@command{unur_distr_cont_set_logpdfstr}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_logpdfstr}
@end ifnothtml
call.
A new distribution object has to be used instead.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_set_pdf}
@anchor{funct:unur_distr_cont_set_dpdf}
@anchor{funct:unur_distr_cont_set_cdf}
@anchor{funct:unur_distr_cont_set_invcdf}
@deftypefn {} {int} unur_distr_cont_set_pdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_CONT* @var{pdf})
@deftypefnx {} {int} unur_distr_cont_set_dpdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_CONT* @var{dpdf})
@deftypefnx {} {int} unur_distr_cont_set_cdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_CONT* @var{cdf})
@deftypefnx {} {int} unur_distr_cont_set_invcdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_CONT* @var{invcdf})
Set respective pointer to the probability density function (PDF),
the derivative of the probability density function (dPDF), the
cumulative distribution function (CDF), and the inverse CDF of the
@var{distribution}.
Each of these function pointers must be of type
@code{double funct(double x, const UNUR_DISTR *distr)}.

Due to the fact that some of the methods do not require a
normalized PDF the following is important:

@itemize @minus
@item
The given CDF must be the cumulative distribution function of
the (non-truncated) distribution. If a distribution from the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions})
is truncated, there is no need to change the CDF.

@item
If both the CDF and the PDF are used (for a method or for order
statistics), the PDF must be the derivative of the CDF.
If a truncated distribution for one of the standard distributions
from the UNU.RAN library of standard distributions is used,
there is no need to change the PDF.

@item
If the area below the PDF is required for a given distribution
it must be given by the
@ifhtml
@ref{funct:unur_distr_cont_set_pdfarea,@command{unur_distr_cont_set_pdfarea}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_pdfarea}
@end ifnothtml
call.
For a truncated distribution this must be of course the integral of
the PDF in the given truncated domain.
For distributions from the UNU.RAN library of standard
distributions this is done automatically by the
@ifhtml
@ref{funct:unur_distr_cont_upd_pdfarea,@command{unur_distr_cont_upd_pdfarea}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_pdfarea}
@end ifnothtml
call.

@end itemize

It is important to note that all these functions must return a
result for all values of @var{x}. Eg., if the domain of a given
PDF is the interval [-1,1], then the given function must return
@code{0.0} for all points outside this interval.
In case of an overflow the PDF should return
@code{UNUR_INFINITY}.

It is not possible to change such a function. Once the PDF or
CDF is set it cannot be overwritten. This also holds when the
logPDF is given or when the PDF
is given by the
@ifhtml
@ref{funct:unur_distr_cont_set_pdfstr,@command{unur_distr_cont_set_pdfstr}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_pdfstr}
@end ifnothtml
or
@ifhtml
@ref{funct:unur_distr_cont_set_logpdfstr,@command{unur_distr_cont_set_logpdfstr}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_logpdfstr}
@end ifnothtml
call.
A new distribution object has to be used instead.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_get_pdf}
@anchor{funct:unur_distr_cont_get_dpdf}
@anchor{funct:unur_distr_cont_get_cdf}
@anchor{funct:unur_distr_cont_get_invcdf}
@deftypefn Function {UNUR_FUNCT_CONT*} unur_distr_cont_get_pdf (const @var{UNUR_DISTR* distribution})
@deftypefnx Function {UNUR_FUNCT_CONT*} unur_distr_cont_get_dpdf (const @var{UNUR_DISTR* distribution})
@deftypefnx Function {UNUR_FUNCT_CONT*} unur_distr_cont_get_cdf (const @var{UNUR_DISTR* distribution})
@deftypefnx Function {UNUR_FUNCT_CONT*} unur_distr_cont_get_invcdf (const @var{UNUR_DISTR* distribution})
Get the respective pointer to the PDF, the derivative of the
PDF, the CDF, and the inverse CDF of the @var{distribution}. The
pointer is of type @code{double funct(double x, const UNUR_DISTR *distr)}.
If the corresponding function is not available for the distribution,
the @code{NULL} pointer is returned.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_get_pdf}
@anchor{funct:unur_distr_cont_get_dpdf}
@anchor{funct:unur_distr_cont_get_cdf}
@anchor{funct:unur_distr_cont_get_invcdf}
@deftypefn {} {UNUR_FUNCT_CONT*} unur_distr_cont_get_pdf (const @var{UNUR_DISTR* distribution})
@deftypefnx {} {UNUR_FUNCT_CONT*} unur_distr_cont_get_dpdf (const @var{UNUR_DISTR* distribution})
@deftypefnx {} {UNUR_FUNCT_CONT*} unur_distr_cont_get_cdf (const @var{UNUR_DISTR* distribution})
@deftypefnx {} {UNUR_FUNCT_CONT*} unur_distr_cont_get_invcdf (const @var{UNUR_DISTR* distribution})
Get the respective pointer to the PDF, the derivative of the
PDF, the CDF, and the inverse CDF of the @var{distribution}. The
pointer is of type @code{double funct(double x, const UNUR_DISTR *distr)}.
If the corresponding function is not available for the distribution,
the @code{NULL} pointer is returned.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_eval_pdf}
@anchor{funct:unur_distr_cont_eval_dpdf}
@anchor{funct:unur_distr_cont_eval_cdf}
@anchor{funct:unur_distr_cont_eval_invcdf}
@deftypefn Function {double} unur_distr_cont_eval_pdf (double @var{x}, const @var{UNUR_DISTR* distribution})
@deftypefnx Function {double} unur_distr_cont_eval_dpdf (double @var{x}, const @var{UNUR_DISTR* distribution})
@deftypefnx Function {double} unur_distr_cont_eval_cdf (double @var{x}, const @var{UNUR_DISTR* distribution})
@deftypefnx Function {double} unur_distr_cont_eval_invcdf (double @var{u}, const @var{UNUR_DISTR* distribution})
Evaluate the PDF, derivative of the PDF, the CDF, and the inverse
CDF at @var{x} and @var{u},respectively.
Notice that @var{distribution} must not be the @code{NULL} pointer.
If the corresponding function is not available for the distribution,
@code{UNUR_INFINITY} is returned and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_DATA}.

@emph{IMPORTANT:}
In the case of a truncated standard distribution these calls always
return the respective values of the @emph{untruncated} distribution!
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_eval_pdf}
@anchor{funct:unur_distr_cont_eval_dpdf}
@anchor{funct:unur_distr_cont_eval_cdf}
@anchor{funct:unur_distr_cont_eval_invcdf}
@deftypefn {} {double} unur_distr_cont_eval_pdf (double @var{x}, const @var{UNUR_DISTR* distribution})
@deftypefnx {} {double} unur_distr_cont_eval_dpdf (double @var{x}, const @var{UNUR_DISTR* distribution})
@deftypefnx {} {double} unur_distr_cont_eval_cdf (double @var{x}, const @var{UNUR_DISTR* distribution})
@deftypefnx {} {double} unur_distr_cont_eval_invcdf (double @var{u}, const @var{UNUR_DISTR* distribution})
Evaluate the PDF, derivative of the PDF, the CDF, and the inverse
CDF at @var{x} and @var{u},respectively.
Notice that @var{distribution} must not be the @code{NULL} pointer.
If the corresponding function is not available for the distribution,
@code{UNUR_INFINITY} is returned and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_DATA}.

@emph{IMPORTANT:}
In the case of a truncated standard distribution these calls always
return the respective values of the @emph{untruncated} distribution!
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_set_logpdf}
@anchor{funct:unur_distr_cont_set_dlogpdf}
@anchor{funct:unur_distr_cont_set_logcdf}
@anchor{funct:unur_distr_cont_get_logpdf}
@anchor{funct:unur_distr_cont_get_dlogpdf}
@anchor{funct:unur_distr_cont_get_logcdf}
@anchor{funct:unur_distr_cont_eval_logpdf}
@anchor{funct:unur_distr_cont_eval_dlogpdf}
@anchor{funct:unur_distr_cont_eval_logcdf}
@deftypefn Function {int} unur_distr_cont_set_logpdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_CONT* @var{logpdf})
@deftypefnx Function {int} unur_distr_cont_set_dlogpdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_CONT* @var{dlogpdf})
@deftypefnx Function {int} unur_distr_cont_set_logcdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_CONT* @var{logcdf})
@deftypefnx Function {UNUR_FUNCT_CONT*} unur_distr_cont_get_logpdf (const @var{UNUR_DISTR* distribution})
@deftypefnx Function {UNUR_FUNCT_CONT*} unur_distr_cont_get_dlogpdf (const @var{UNUR_DISTR* distribution})
@deftypefnx Function {UNUR_FUNCT_CONT*} unur_distr_cont_get_logcdf (const @var{UNUR_DISTR* distribution})
@deftypefnx Function {double} unur_distr_cont_eval_logpdf (double @var{x}, const @var{UNUR_DISTR* distribution})
@deftypefnx Function {double} unur_distr_cont_eval_dlogpdf (double @var{x}, const @var{UNUR_DISTR* distribution})
@deftypefnx Function {double} unur_distr_cont_eval_logcdf (double @var{x}, const @var{UNUR_DISTR* distribution})
Analogous calls for the logarithm of the density distribution functions.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_set_logpdf}
@anchor{funct:unur_distr_cont_set_dlogpdf}
@anchor{funct:unur_distr_cont_set_logcdf}
@anchor{funct:unur_distr_cont_get_logpdf}
@anchor{funct:unur_distr_cont_get_dlogpdf}
@anchor{funct:unur_distr_cont_get_logcdf}
@anchor{funct:unur_distr_cont_eval_logpdf}
@anchor{funct:unur_distr_cont_eval_dlogpdf}
@anchor{funct:unur_distr_cont_eval_logcdf}
@deftypefn {} {int} unur_distr_cont_set_logpdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_CONT* @var{logpdf})
@deftypefnx {} {int} unur_distr_cont_set_dlogpdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_CONT* @var{dlogpdf})
@deftypefnx {} {int} unur_distr_cont_set_logcdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_CONT* @var{logcdf})
@deftypefnx {} {UNUR_FUNCT_CONT*} unur_distr_cont_get_logpdf (const @var{UNUR_DISTR* distribution})
@deftypefnx {} {UNUR_FUNCT_CONT*} unur_distr_cont_get_dlogpdf (const @var{UNUR_DISTR* distribution})
@deftypefnx {} {UNUR_FUNCT_CONT*} unur_distr_cont_get_logcdf (const @var{UNUR_DISTR* distribution})
@deftypefnx {} {double} unur_distr_cont_eval_logpdf (double @var{x}, const @var{UNUR_DISTR* distribution})
@deftypefnx {} {double} unur_distr_cont_eval_dlogpdf (double @var{x}, const @var{UNUR_DISTR* distribution})
@deftypefnx {} {double} unur_distr_cont_eval_logcdf (double @var{x}, const @var{UNUR_DISTR* distribution})
Analogous calls for the logarithm of the density distribution functions.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_set_pdfstr}
@deftypefn Function {int} unur_distr_cont_set_pdfstr (UNUR_DISTR* @var{distribution}, const @var{char* pdfstr})
This function provides an alternative way to set a PDF and its
derivative of the @var{distribution}.
@var{pdfstr} is a character string that contains the formula
for the PDF, see @ref{StringFunct,,Function String}, for details.
The derivative of the given PDF is computed automatically.
See also the remarks for the
@ifhtml
@ref{funct:unur_distr_cont_set_pdf,@command{unur_distr_cont_set_pdf}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_pdf}
@end ifnothtml
call.

It is not possible to call this funtion twice or to call this
function after a
@ifhtml
@ref{funct:unur_distr_cont_set_pdf,@command{unur_distr_cont_set_pdf}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_pdf}
@end ifnothtml
call.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_set_pdfstr}
@deftypefn {} {int} unur_distr_cont_set_pdfstr (UNUR_DISTR* @var{distribution}, const @var{char* pdfstr})
This function provides an alternative way to set a PDF and its
derivative of the @var{distribution}.
@var{pdfstr} is a character string that contains the formula
for the PDF, see @ref{StringFunct,,Function String}, for details.
The derivative of the given PDF is computed automatically.
See also the remarks for the
@ifhtml
@ref{funct:unur_distr_cont_set_pdf,@command{unur_distr_cont_set_pdf}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_pdf}
@end ifnothtml
call.

It is not possible to call this funtion twice or to call this
function after a
@ifhtml
@ref{funct:unur_distr_cont_set_pdf,@command{unur_distr_cont_set_pdf}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_pdf}
@end ifnothtml
call.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_set_cdfstr}
@deftypefn Function {int} unur_distr_cont_set_cdfstr (UNUR_DISTR* @var{distribution}, const @var{char* cdfstr})
This function provides an alternative way to set a CDF; analogously
to the
@ifhtml
@ref{funct:unur_distr_cont_set_pdfstr,@command{unur_distr_cont_set_pdfstr}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_pdfstr}
@end ifnothtml
call.
The PDF and its derivative of the given CDF are computed automatically.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_set_cdfstr}
@deftypefn {} {int} unur_distr_cont_set_cdfstr (UNUR_DISTR* @var{distribution}, const @var{char* cdfstr})
This function provides an alternative way to set a CDF; analogously
to the
@ifhtml
@ref{funct:unur_distr_cont_set_pdfstr,@command{unur_distr_cont_set_pdfstr}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_pdfstr}
@end ifnothtml
call.
The PDF and its derivative of the given CDF are computed automatically.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_get_pdfstr}
@anchor{funct:unur_distr_cont_get_dpdfstr}
@anchor{funct:unur_distr_cont_get_cdfstr}
@deftypefn Function {char*} unur_distr_cont_get_pdfstr (const @var{UNUR_DISTR* distribution})
@deftypefnx Function {char*} unur_distr_cont_get_dpdfstr (const @var{UNUR_DISTR* distribution})
@deftypefnx Function {char*} unur_distr_cont_get_cdfstr (const @var{UNUR_DISTR* distribution})
Get pointer to respective string for PDF, derivate of PDF, and CDF
of @var{distribution} that is given as string (instead of a
function pointer).
This call allocates memory to produce this string. It should be
freed when it is not used any more.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_get_pdfstr}
@anchor{funct:unur_distr_cont_get_dpdfstr}
@anchor{funct:unur_distr_cont_get_cdfstr}
@deftypefn {} {char*} unur_distr_cont_get_pdfstr (const @var{UNUR_DISTR* distribution})
@deftypefnx {} {char*} unur_distr_cont_get_dpdfstr (const @var{UNUR_DISTR* distribution})
@deftypefnx {} {char*} unur_distr_cont_get_cdfstr (const @var{UNUR_DISTR* distribution})
Get pointer to respective string for PDF, derivate of PDF, and CDF
of @var{distribution} that is given as string (instead of a
function pointer).
This call allocates memory to produce this string. It should be
freed when it is not used any more.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_set_pdfparams}
@deftypefn Function {int} unur_distr_cont_set_pdfparams (UNUR_DISTR* @var{distribution}, const @var{double* params}, int @var{n_params})
Sets array of parameters for @var{distribution}. There is an upper limit
for the number of parameters @code{n_params}. It is given by the
macro @code{UNUR_DISTR_MAXPARAMS} in @file{unuran_config.h}. (It is set to
5 by default but can be changed to any appropriate nonnegative number.)
If @var{n_params} is negative or exceeds this limit no parameters
are copied into the distribution object and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_NPARAMS}.

For standard distributions from the UNU.RAN library the parameters
are checked. Moreover, the domain is updated automatically unless it
has been changed before by a
@ifhtml
@ref{funct:unur_distr_cont_set_domain,@command{unur_distr_cont_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_domain}
@end ifnothtml
call.
If the given parameters are invalid for the standard distribution,
then no parameters are set and an error code is returned.
Notice, that the given parameter list for such a distribution is
handled in the same way as in the corresponding @command{new}
calls, i.e. optional parameters for the PDF that are not present in
the given list are (re-)set to their default values.

@strong{Important:} If the parameters of a distribution from the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions})
are changed, then neither its mode nor the normalization
constant are updated. Please use the respective calls
@ifhtml
@ref{funct:unur_distr_cont_upd_mode,@command{unur_distr_cont_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_mode}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_distr_cont_upd_pdfarea,@command{unur_distr_cont_upd_pdfarea}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_pdfarea}.
@end ifnothtml
Moreover, if the domain has been changed by a
@ifhtml
@ref{funct:unur_distr_cont_set_domain,@command{unur_distr_cont_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_domain}
@end ifnothtml
it is not automatically updated, either.
Updating the normalization constant is in particular very important,
when the CDF of the distribution is used.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_set_pdfparams}
@deftypefn {} {int} unur_distr_cont_set_pdfparams (UNUR_DISTR* @var{distribution}, const @var{double* params}, int @var{n_params})
Sets array of parameters for @var{distribution}. There is an upper limit
for the number of parameters @code{n_params}. It is given by the
macro @code{UNUR_DISTR_MAXPARAMS} in @file{unuran_config.h}. (It is set to
5 by default but can be changed to any appropriate nonnegative number.)
If @var{n_params} is negative or exceeds this limit no parameters
are copied into the distribution object and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_NPARAMS}.

For standard distributions from the UNU.RAN library the parameters
are checked. Moreover, the domain is updated automatically unless it
has been changed before by a
@ifhtml
@ref{funct:unur_distr_cont_set_domain,@command{unur_distr_cont_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_domain}
@end ifnothtml
call.
If the given parameters are invalid for the standard distribution,
then no parameters are set and an error code is returned.
Notice, that the given parameter list for such a distribution is
handled in the same way as in the corresponding @command{new}
calls, i.e. optional parameters for the PDF that are not present in
the given list are (re-)set to their default values.

@strong{Important:} If the parameters of a distribution from the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions})
are changed, then neither its mode nor the normalization
constant are updated. Please use the respective calls
@ifhtml
@ref{funct:unur_distr_cont_upd_mode,@command{unur_distr_cont_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_mode}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_distr_cont_upd_pdfarea,@command{unur_distr_cont_upd_pdfarea}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_pdfarea}.
@end ifnothtml
Moreover, if the domain has been changed by a
@ifhtml
@ref{funct:unur_distr_cont_set_domain,@command{unur_distr_cont_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_domain}
@end ifnothtml
it is not automatically updated, either.
Updating the normalization constant is in particular very important,
when the CDF of the distribution is used.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_get_pdfparams}
@deftypefn Function {int} unur_distr_cont_get_pdfparams (const @var{UNUR_DISTR* distribution}, const @var{double** params})
Get number of parameters of the PDF and set pointer @var{params} to
array of parameters. If no parameters are stored in the object, an
error code is returned and @code{params} is set to @code{NULL}.

@emph{Important:} Do @strong{not} change the entries in @var{params}!
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_get_pdfparams}
@deftypefn {} {int} unur_distr_cont_get_pdfparams (const @var{UNUR_DISTR* distribution}, const @var{double** params})
Get number of parameters of the PDF and set pointer @var{params} to
array of parameters. If no parameters are stored in the object, an
error code is returned and @code{params} is set to @code{NULL}.

@emph{Important:} Do @strong{not} change the entries in @var{params}!
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_set_pdfparams_vec}
@deftypefn Function {int} unur_distr_cont_set_pdfparams_vec (UNUR_DISTR* @var{distribution}, int @var{par}, const @var{double* param_vec}, int @var{n_param_vec})
This function provides an interface for additional vector parameters for a
continuous @var{distribution}.

It sets the parameter with number @var{par}.
@var{par} indicates directly which of the parameters is set and
must be a number between @code{0} and @code{UNUR_DISTR_MAXPARAMS}-1
(the upper limit of possible parameters defined in
@file{unuran_config.h}; it is set to 5 but can be changed to any
appropriate nonnegative number.)

The entries of a this parameter are given by the array @var{param_vec}
of size @var{n_param_vec}.

If @var{param_vec} is @code{NULL} then the corresponding entry is cleared.

If an error occurs no parameters are copied into the parameter
object @code{unur_errno} is set to @code{UNUR_ERR_DISTR_DATA}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_set_pdfparams_vec}
@deftypefn {} {int} unur_distr_cont_set_pdfparams_vec (UNUR_DISTR* @var{distribution}, int @var{par}, const @var{double* param_vec}, int @var{n_param_vec})
This function provides an interface for additional vector parameters for a
continuous @var{distribution}.

It sets the parameter with number @var{par}.
@var{par} indicates directly which of the parameters is set and
must be a number between @code{0} and @code{UNUR_DISTR_MAXPARAMS}-1
(the upper limit of possible parameters defined in
@file{unuran_config.h}; it is set to 5 but can be changed to any
appropriate nonnegative number.)

The entries of a this parameter are given by the array @var{param_vec}
of size @var{n_param_vec}.

If @var{param_vec} is @code{NULL} then the corresponding entry is cleared.

If an error occurs no parameters are copied into the parameter
object @code{unur_errno} is set to @code{UNUR_ERR_DISTR_DATA}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_get_pdfparams_vec}
@deftypefn Function {int} unur_distr_cont_get_pdfparams_vec (const @var{UNUR_DISTR* distribution}, int @var{par}, const @var{double** param_vecs})
Get parameter of the PDF with number @var{par}.
The pointer to the parameter array is stored in @var{param_vecs}, its
size is returned by the function.
If the requested parameter is not set, then an error code is returned
and @code{params} is set to @code{NULL}.

@emph{Important:} Do @strong{not} change the entries in @var{param_vecs}!
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_get_pdfparams_vec}
@deftypefn {} {int} unur_distr_cont_get_pdfparams_vec (const @var{UNUR_DISTR* distribution}, int @var{par}, const @var{double** param_vecs})
Get parameter of the PDF with number @var{par}.
The pointer to the parameter array is stored in @var{param_vecs}, its
size is returned by the function.
If the requested parameter is not set, then an error code is returned
and @code{params} is set to @code{NULL}.

@emph{Important:} Do @strong{not} change the entries in @var{param_vecs}!
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_set_logpdfstr}
@anchor{funct:unur_distr_cont_get_logpdfstr}
@anchor{funct:unur_distr_cont_get_dlogpdfstr}
@anchor{funct:unur_distr_cont_set_logcdfstr}
@anchor{funct:unur_distr_cont_get_logcdfstr}
@deftypefn Function {int} unur_distr_cont_set_logpdfstr (UNUR_DISTR* @var{distribution}, const @var{char* logpdfstr})
@deftypefnx Function {char*} unur_distr_cont_get_logpdfstr (const @var{UNUR_DISTR* distribution})
@deftypefnx Function {char*} unur_distr_cont_get_dlogpdfstr (const @var{UNUR_DISTR* distribution})
@deftypefnx Function {int} unur_distr_cont_set_logcdfstr (UNUR_DISTR* @var{distribution}, const @var{char* logcdfstr})
@deftypefnx Function {char*} unur_distr_cont_get_logcdfstr (const @var{UNUR_DISTR* distribution})
Analogous calls for the logarithm of the density and distribution functions.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_set_logpdfstr}
@anchor{funct:unur_distr_cont_get_logpdfstr}
@anchor{funct:unur_distr_cont_get_dlogpdfstr}
@anchor{funct:unur_distr_cont_set_logcdfstr}
@anchor{funct:unur_distr_cont_get_logcdfstr}
@deftypefn {} {int} unur_distr_cont_set_logpdfstr (UNUR_DISTR* @var{distribution}, const @var{char* logpdfstr})
@deftypefnx {} {char*} unur_distr_cont_get_logpdfstr (const @var{UNUR_DISTR* distribution})
@deftypefnx {} {char*} unur_distr_cont_get_dlogpdfstr (const @var{UNUR_DISTR* distribution})
@deftypefnx {} {int} unur_distr_cont_set_logcdfstr (UNUR_DISTR* @var{distribution}, const @var{char* logcdfstr})
@deftypefnx {} {char*} unur_distr_cont_get_logcdfstr (const @var{UNUR_DISTR* distribution})
Analogous calls for the logarithm of the density and distribution functions.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_set_domain}
@deftypefn Function {int} unur_distr_cont_set_domain (UNUR_DISTR* @var{distribution}, double @var{left}, double @var{right})
Set the left and right borders of the domain of the
distribution. This can also be used to truncate an existing
distribution. For setting the boundary to
@math{+/- infinity}
use @code{+/- UNUR_INFINITY}.
If @var{right} is not strictly greater than @var{left} no domain
is set and @code{unur_errno} is set to @code{UNUR_ERR_DISTR_SET}.

@emph{Important:} For some technical reasons it is assumed that the density
is unimodal and thus monotone on either side of the mode! This is used in
the case when the given mode is outside of the original domain. Then the
mode is set to the corresponding boundary of the new domain.
If this result is not the desired it must be changed by using a
@ifhtml
@ref{funct:unur_distr_cont_set_mode,@command{unur_distr_cont_set_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_mode}
@end ifnothtml
call (or a
@ifhtml
@ref{funct:unur_distr_cont_upd_mode,@command{unur_distr_cont_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_mode}
@end ifnothtml
call). The same holds for the center of the distribution.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_set_domain}
@deftypefn {} {int} unur_distr_cont_set_domain (UNUR_DISTR* @var{distribution}, double @var{left}, double @var{right})
Set the left and right borders of the domain of the
distribution. This can also be used to truncate an existing
distribution. For setting the boundary to
@iftex
@math{\pm\infty}
@end iftex
@ifhtml
@html
+/- infinity
@end html
@end ifhtml
use @code{+/- UNUR_INFINITY}.
If @var{right} is not strictly greater than @var{left} no domain
is set and @code{unur_errno} is set to @code{UNUR_ERR_DISTR_SET}.

@emph{Important:} For some technical reasons it is assumed that the density
is unimodal and thus monotone on either side of the mode! This is used in
the case when the given mode is outside of the original domain. Then the
mode is set to the corresponding boundary of the new domain.
If this result is not the desired it must be changed by using a
@ifhtml
@ref{funct:unur_distr_cont_set_mode,@command{unur_distr_cont_set_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_mode}
@end ifnothtml
call (or a
@ifhtml
@ref{funct:unur_distr_cont_upd_mode,@command{unur_distr_cont_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_mode}
@end ifnothtml
call). The same holds for the center of the distribution.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_get_domain}
@deftypefn Function {int} unur_distr_cont_get_domain (const @var{UNUR_DISTR* distribution}, double* @var{left}, double* @var{right})
Get the left and right borders of the domain of the
distribution. If the domain is not set @code{+/- UNUR_INFINITY} is
assumed and returned. No error is reported in this case.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_get_domain}
@deftypefn {} {int} unur_distr_cont_get_domain (const @var{UNUR_DISTR* distribution}, double* @var{left}, double* @var{right})
Get the left and right borders of the domain of the
distribution. If the domain is not set @code{+/- UNUR_INFINITY} is
assumed and returned. No error is reported in this case.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_get_truncated}
@deftypefn Function {int} unur_distr_cont_get_truncated (const @var{UNUR_DISTR* distribution}, double* @var{left}, double* @var{right})
Get the left and right borders of the (truncated) domain of the
distribution. For non-truncated distribution this call is
equivalent to the
@ifhtml
@ref{funct:unur_distr_cont_get_domain,@command{unur_distr_cont_get_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_get_domain}
@end ifnothtml
call.

This call is only useful in connection with a
@ifhtml
@ref{funct:unur_get_distr,@command{unur_get_distr}}
@end ifhtml
@ifnothtml
@command{unur_get_distr}
@end ifnothtml
call
to get the boundaries of the sampling region of a generator object.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_get_truncated}
@deftypefn {} {int} unur_distr_cont_get_truncated (const @var{UNUR_DISTR* distribution}, double* @var{left}, double* @var{right})
Get the left and right borders of the (truncated) domain of the
distribution. For non-truncated distribution this call is
equivalent to the
@ifhtml
@ref{funct:unur_distr_cont_get_domain,@command{unur_distr_cont_get_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_get_domain}
@end ifnothtml
call.

This call is only useful in connection with a
@ifhtml
@ref{funct:unur_get_distr,@command{unur_get_distr}}
@end ifhtml
@ifnothtml
@command{unur_get_distr}
@end ifnothtml
call
to get the boundaries of the sampling region of a generator object.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_set_hr}
@deftypefn Function {int} unur_distr_cont_set_hr (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_CONT* @var{hazard})
Set pointer to the hazard rate (HR) of the @var{distribution}.

The @emph{hazard rate} (or failure rate) is a mathematical way of
describing aging. If the lifetime @i{X} is a random variable with
density @i{f(x)} and CDF @i{F(x)} the hazard rate @i{h(x)}
is defined as @i{h(x) = f(x) / (1-F(x))}.
In other words, @i{h(x)} represents the (conditional) rate of
failure of a unit that has survived up to time @i{x} with
probability @i{1-F(x)}.
The key distribution is the exponential distribution as it has
constant hazard rate of value 1. Hazard rates tending to infinity
describe distributions with sub-exponential tails whereas
distributions with hazard rates tending to zero have heavier tails
than the exponential distribution.

It is important to note that all these functions must return a
result for all floats @i{x}. In case of an overflow the PDF should
return @code{UNUR_INFINITY}.

@strong{Important}: Do not simply use @i{f(x) / (1-F(x))}, since
this is numerically very unstable and results in numerical noise
if @i{F(x)} is (very) close to 1. Moreover, if the density @i{f(x)}
is known a generation method that uses the density is more
appropriate.

It is not possible to change such a function. Once the HR is set it
cannot be overwritten. This also holds when the HR is given by the
@ifhtml
@ref{funct:unur_distr_cont_set_hrstr,@command{unur_distr_cont_set_hrstr}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_hrstr}
@end ifnothtml
call. A new distribution object has to
be used instead.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_set_hr}
@deftypefn {} {int} unur_distr_cont_set_hr (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_CONT* @var{hazard})
Set pointer to the hazard rate (HR) of the @var{distribution}.

The @emph{hazard rate} (or failure rate) is a mathematical way of
describing aging. If the lifetime @i{X} is a random variable with
density @i{f(x)} and CDF @i{F(x)} the hazard rate @i{h(x)}
is defined as @i{h(x) = f(x) / (1-F(x))}.
In other words, @i{h(x)} represents the (conditional) rate of
failure of a unit that has survived up to time @i{x} with
probability @i{1-F(x)}.
The key distribution is the exponential distribution as it has
constant hazard rate of value 1. Hazard rates tending to infinity
describe distributions with sub-exponential tails whereas
distributions with hazard rates tending to zero have heavier tails
than the exponential distribution.

It is important to note that all these functions must return a
result for all floats @i{x}. In case of an overflow the PDF should
return @code{UNUR_INFINITY}.

@strong{Important}: Do not simply use @i{f(x) / (1-F(x))}, since
this is numerically very unstable and results in numerical noise
if @i{F(x)} is (very) close to 1. Moreover, if the density @i{f(x)}
is known a generation method that uses the density is more
appropriate.

It is not possible to change such a function. Once the HR is set it
cannot be overwritten. This also holds when the HR is given by the
@ifhtml
@ref{funct:unur_distr_cont_set_hrstr,@command{unur_distr_cont_set_hrstr}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_hrstr}
@end ifnothtml
call. A new distribution object has to
be used instead.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_get_hr}
@deftypefn Function {UNUR_FUNCT_CONT*} unur_distr_cont_get_hr (const @var{UNUR_DISTR* distribution})
Get the pointer to the hazard rate of the @var{distribution}. The
pointer is of type
@code{double funct(double x, const UNUR_DISTR *distr)}.
If the corresponding function is not available for the distribution,
the @code{NULL} pointer is returned.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_get_hr}
@deftypefn {} {UNUR_FUNCT_CONT*} unur_distr_cont_get_hr (const @var{UNUR_DISTR* distribution})
Get the pointer to the hazard rate of the @var{distribution}. The
pointer is of type
@code{double funct(double x, const UNUR_DISTR *distr)}.
If the corresponding function is not available for the distribution,
the @code{NULL} pointer is returned.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_eval_hr}
@deftypefn Function {double} unur_distr_cont_eval_hr (double @var{x}, const @var{UNUR_DISTR* distribution})
Evaluate the hazard rate at @var{x}.
Notice that @var{distribution} must not be the @code{NULL} pointer.
If the corresponding function is not available for the distribution,
@code{UNUR_INFINITY} is returned and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_DATA}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_eval_hr}
@deftypefn {} {double} unur_distr_cont_eval_hr (double @var{x}, const @var{UNUR_DISTR* distribution})
Evaluate the hazard rate at @var{x}.
Notice that @var{distribution} must not be the @code{NULL} pointer.
If the corresponding function is not available for the distribution,
@code{UNUR_INFINITY} is returned and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_DATA}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_set_hrstr}
@deftypefn Function {int} unur_distr_cont_set_hrstr (UNUR_DISTR* @var{distribution}, const @var{char* hrstr})
This function provides an alternative way to set a hazard rate and its
derivative of the @var{distribution}.
@var{hrstr} is a character string that contains the formula
for the HR, see @ref{StringFunct,,Function String}, for details.
See also the remarks for the
@ifhtml
@ref{funct:unur_distr_cont_set_hr,@command{unur_distr_cont_set_hr}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_hr}
@end ifnothtml
call.

It is not possible to call this funtion twice or to call this
function after a
@ifhtml
@ref{funct:unur_distr_cont_set_hr,@command{unur_distr_cont_set_hr}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_hr}
@end ifnothtml
call.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_set_hrstr}
@deftypefn {} {int} unur_distr_cont_set_hrstr (UNUR_DISTR* @var{distribution}, const @var{char* hrstr})
This function provides an alternative way to set a hazard rate and its
derivative of the @var{distribution}.
@var{hrstr} is a character string that contains the formula
for the HR, see @ref{StringFunct,,Function String}, for details.
See also the remarks for the
@ifhtml
@ref{funct:unur_distr_cont_set_hr,@command{unur_distr_cont_set_hr}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_hr}
@end ifnothtml
call.

It is not possible to call this funtion twice or to call this
function after a
@ifhtml
@ref{funct:unur_distr_cont_set_hr,@command{unur_distr_cont_set_hr}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_hr}
@end ifnothtml
call.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_get_hrstr}
@deftypefn Function {char*} unur_distr_cont_get_hrstr (const @var{UNUR_DISTR* distribution})
Get pointer to string for HR of @var{distribution} that is given
via the string interface. This call allocates memory to produce
this string. It should be freed when it is not used any more.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_get_hrstr}
@deftypefn {} {char*} unur_distr_cont_get_hrstr (const @var{UNUR_DISTR* distribution})
Get pointer to string for HR of @var{distribution} that is given
via the string interface. This call allocates memory to produce
this string. It should be freed when it is not used any more.
@end deftypefn
@end ifnotinfo

@subsubheading Derived parameters

The following paramters @strong{must} be set whenever one of the essential
parameters has been set or changed (and the parameter is required
for the chosen method).

@ifinfo
@anchor{funct:unur_distr_cont_set_mode}
@deftypefn Function {int} unur_distr_cont_set_mode (UNUR_DISTR* @var{distribution}, double @var{mode})
Set mode of @var{distribution}. The @var{mode} must be contained in
the domain of @var{distribution}. Otherwise the mode is not set and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_SET}.
For distributions with unbounded density, this call is used to set
the pole of the PDF. Notice that the PDF should then return
@code{UNUR_INFINITY} at the pole.
Notice that the mode is adjusted when the domain is set, see the
remark for the
@ifhtml
@ref{funct:unur_distr_cont_set_domain,@command{unur_distr_cont_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_domain}
@end ifnothtml
call.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_set_mode}
@deftypefn {} {int} unur_distr_cont_set_mode (UNUR_DISTR* @var{distribution}, double @var{mode})
Set mode of @var{distribution}. The @var{mode} must be contained in
the domain of @var{distribution}. Otherwise the mode is not set and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_SET}.
For distributions with unbounded density, this call is used to set
the pole of the PDF. Notice that the PDF should then return
@code{UNUR_INFINITY} at the pole.
Notice that the mode is adjusted when the domain is set, see the
remark for the
@ifhtml
@ref{funct:unur_distr_cont_set_domain,@command{unur_distr_cont_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_domain}
@end ifnothtml
call.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_upd_mode}
@deftypefn Function {int} unur_distr_cont_upd_mode (UNUR_DISTR* @var{distribution})
Recompute the mode of the @var{distribution}. This call works
properly for distribution objects from the UNU.RAN library of
standard distributions when the corresponding function is
available.  Otherwise a (slow) numerical mode finder based on
Brent's algorithm is used. If it failes @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_DATA}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_upd_mode}
@deftypefn {} {int} unur_distr_cont_upd_mode (UNUR_DISTR* @var{distribution})
Recompute the mode of the @var{distribution}. This call works
properly for distribution objects from the UNU.RAN library of
standard distributions when the corresponding function is
available.  Otherwise a (slow) numerical mode finder based on
Brent's algorithm is used. If it failes @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_DATA}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_get_mode}
@deftypefn Function {double} unur_distr_cont_get_mode (UNUR_DISTR* @var{distribution})
Get mode of @var{distribution}. If the mode is not marked as known,
@ifhtml
@ref{funct:unur_distr_cont_upd_mode,@command{unur_distr_cont_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_mode}
@end ifnothtml
is called to compute the mode. If this
is not successful @code{UNUR_INFINITY} is returned and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_GET}.
(There is no difference between the case where no routine for
computing the mode is available and the case where no mode exists
for the distribution at all.)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_get_mode}
@deftypefn {} {double} unur_distr_cont_get_mode (UNUR_DISTR* @var{distribution})
Get mode of @var{distribution}. If the mode is not marked as known,
@ifhtml
@ref{funct:unur_distr_cont_upd_mode,@command{unur_distr_cont_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_mode}
@end ifnothtml
is called to compute the mode. If this
is not successful @code{UNUR_INFINITY} is returned and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_GET}.
(There is no difference between the case where no routine for
computing the mode is available and the case where no mode exists
for the distribution at all.)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_set_center}
@deftypefn Function {int} unur_distr_cont_set_center (UNUR_DISTR* @var{distribution}, double @var{center})
Set center of the @var{distribution}. The center is used by some
methods to shift the distribution in order to decrease numerical
round-off error. If not given explicitly a default is used.

@emph{Important:} This call does not check whether the center is
contained in the given domain.

Default: The mode, if set by a
@ifhtml
@ref{funct:unur_distr_cont_set_mode,@command{unur_distr_cont_set_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_mode}
@end ifnothtml
or
@ifhtml
@ref{funct:unur_distr_cont_upd_mode,@command{unur_distr_cont_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_mode}
@end ifnothtml
call; otherwise @code{0}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_set_center}
@deftypefn {} {int} unur_distr_cont_set_center (UNUR_DISTR* @var{distribution}, double @var{center})
Set center of the @var{distribution}. The center is used by some
methods to shift the distribution in order to decrease numerical
round-off error. If not given explicitly a default is used.

@emph{Important:} This call does not check whether the center is
contained in the given domain.

Default: The mode, if set by a
@ifhtml
@ref{funct:unur_distr_cont_set_mode,@command{unur_distr_cont_set_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_mode}
@end ifnothtml
or
@ifhtml
@ref{funct:unur_distr_cont_upd_mode,@command{unur_distr_cont_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_mode}
@end ifnothtml
call; otherwise @code{0}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_get_center}
@deftypefn Function {double} unur_distr_cont_get_center (const @var{UNUR_DISTR* distribution})
Get center of the @var{distribution}. It always returns some point
as there always exists a default for the center, see
@ifhtml
@ref{funct:unur_distr_cont_set_center,@command{unur_distr_cont_set_center}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_center}.
@end ifnothtml
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_get_center}
@deftypefn {} {double} unur_distr_cont_get_center (const @var{UNUR_DISTR* distribution})
Get center of the @var{distribution}. It always returns some point
as there always exists a default for the center, see
@ifhtml
@ref{funct:unur_distr_cont_set_center,@command{unur_distr_cont_set_center}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_center}.
@end ifnothtml
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_set_pdfarea}
@deftypefn Function {int} unur_distr_cont_set_pdfarea (UNUR_DISTR* @var{distribution}, double @var{area})
Set the area below the PDF. If @code{area} is non-positive, no
area is set and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_SET}.

For a distribution object created by the
UNU.RAN library of standard distributions you always should use
the
@ifhtml
@ref{funct:unur_distr_cont_upd_pdfarea,@command{unur_distr_cont_upd_pdfarea}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_pdfarea}.
@end ifnothtml
Otherwise there might be
ambiguous side-effects.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_set_pdfarea}
@deftypefn {} {int} unur_distr_cont_set_pdfarea (UNUR_DISTR* @var{distribution}, double @var{area})
Set the area below the PDF. If @code{area} is non-positive, no
area is set and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_SET}.

For a distribution object created by the
UNU.RAN library of standard distributions you always should use
the
@ifhtml
@ref{funct:unur_distr_cont_upd_pdfarea,@command{unur_distr_cont_upd_pdfarea}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_pdfarea}.
@end ifnothtml
Otherwise there might be
ambiguous side-effects.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_upd_pdfarea}
@deftypefn Function {int} unur_distr_cont_upd_pdfarea (UNUR_DISTR* @var{distribution})
Recompute the area below the PDF of the distribution.
It only works for distribution objects from the
UNU.RAN library of standard distributions when the
corresponding function is available. Otherwise @code{unur_errno} is
set to @code{UNUR_ERR_DISTR_DATA}.

This call also sets the normalization constant such that the given
PDF is the derivative of a given CDF, i.e. the area is 1.
However, for truncated distributions the area is smaller than 1.

The call does not work for distributions from the
UNU.RAN library of standard distributions with truncated
domain when the CDF is not available.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_upd_pdfarea}
@deftypefn {} {int} unur_distr_cont_upd_pdfarea (UNUR_DISTR* @var{distribution})
Recompute the area below the PDF of the distribution.
It only works for distribution objects from the
UNU.RAN library of standard distributions when the
corresponding function is available. Otherwise @code{unur_errno} is
set to @code{UNUR_ERR_DISTR_DATA}.

This call also sets the normalization constant such that the given
PDF is the derivative of a given CDF, i.e. the area is 1.
However, for truncated distributions the area is smaller than 1.

The call does not work for distributions from the
UNU.RAN library of standard distributions with truncated
domain when the CDF is not available.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cont_get_pdfarea}
@deftypefn Function {double} unur_distr_cont_get_pdfarea (UNUR_DISTR* @var{distribution})
Get the area below the PDF of the distribution. If this area is
not known,@*
@ifhtml
@ref{funct:unur_distr_cont_upd_pdfarea,@command{unur_distr_cont_upd_pdfarea}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_pdfarea}
@end ifnothtml
is called to compute
it. If this is not successful @code{UNUR_INFINITY} is returned and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_GET}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cont_get_pdfarea}
@deftypefn {} {double} unur_distr_cont_get_pdfarea (UNUR_DISTR* @var{distribution})
Get the area below the PDF of the distribution. If this area is
not known,@*
@ifhtml
@ref{funct:unur_distr_cont_upd_pdfarea,@command{unur_distr_cont_upd_pdfarea}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_pdfarea}
@end ifnothtml
is called to compute
it. If this is not successful @code{UNUR_INFINITY} is returned and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_GET}.
@end deftypefn
@end ifnotinfo




@c
@c end of cont.h
@c -------------------------------------
@c -------------------------------------
@c corder.h
@c

@page
@node CORDER
@section   Continuous univariate order statistics


These are special cases of a continuous univariate distributions
and thus they have most of these parameters (with the exception
that functions cannot be changed). Additionally,

@itemize @minus
@item there is a call to extract the underlying distribution,

@item and a call to handle the @command{rank} of the order
statistics.

@end itemize


@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_distr_corder_new,unur_distr_corder_new}
@item @ref{funct:unur_distr_corder_get_distribution,unur_distr_corder_get_distribution}
@item @ref{funct:unur_distr_corder_set_rank,unur_distr_corder_set_rank}
@item @ref{funct:unur_distr_corder_get_rank,unur_distr_corder_get_rank}
@item @ref{funct:unur_distr_corder_get_pdf,unur_distr_corder_get_pdf}
@item @ref{funct:unur_distr_corder_get_dpdf,unur_distr_corder_get_dpdf}
@item @ref{funct:unur_distr_corder_get_cdf,unur_distr_corder_get_cdf}
@item @ref{funct:unur_distr_corder_eval_pdf,unur_distr_corder_eval_pdf}
@item @ref{funct:unur_distr_corder_eval_dpdf,unur_distr_corder_eval_dpdf}
@item @ref{funct:unur_distr_corder_eval_cdf,unur_distr_corder_eval_cdf}
@item @ref{funct:unur_distr_corder_set_pdfparams,unur_distr_corder_set_pdfparams}
@item @ref{funct:unur_distr_corder_get_pdfparams,unur_distr_corder_get_pdfparams}
@item @ref{funct:unur_distr_corder_set_domain,unur_distr_corder_set_domain}
@item @ref{funct:unur_distr_corder_get_domain,unur_distr_corder_get_domain}
@item @ref{funct:unur_distr_corder_get_truncated,unur_distr_corder_get_truncated}
@item @ref{funct:unur_distr_corder_set_mode,unur_distr_corder_set_mode}
@item @ref{funct:unur_distr_corder_upd_mode,unur_distr_corder_upd_mode}
@item @ref{funct:unur_distr_corder_get_mode,unur_distr_corder_get_mode}
@item @ref{funct:unur_distr_corder_set_pdfarea,unur_distr_corder_set_pdfarea}
@item @ref{funct:unur_distr_corder_upd_pdfarea,unur_distr_corder_upd_pdfarea}
@item @ref{funct:unur_distr_corder_get_pdfarea,unur_distr_corder_get_pdfarea}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_distr_corder_new}
@deftypefn Function {UNUR_DISTR*} unur_distr_corder_new (const @var{UNUR_DISTR* distribution}, int @var{n}, int @var{k})
Create an object for order statistics of sample size
@var{n} and rank @var{k}.
@var{distribution} must be a pointer to a univariate continuous
distribution.
The resulting generator object is of the same type as of a
@ifhtml
@ref{funct:unur_distr_cont_new,@command{unur_distr_cont_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_new}
@end ifnothtml
call.
(However, it cannot be used to make an order statistics out of an
order statistics.)

To have a PDF for the order statistics, the given distribution
object must contain a CDF and a PDF. Moreover, it is assumed that
the given PDF is the derivative of the given CDF. Otherwise the
area below the PDF of the order statistics is not computed correctly.

@emph{Important:} There is no warning when the computed area below
the PDF of the order statistics is wrong.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_corder_new}
@deftypefn {} {UNUR_DISTR*} unur_distr_corder_new (const @var{UNUR_DISTR* distribution}, int @var{n}, int @var{k})
Create an object for order statistics of sample size
@var{n} and rank @var{k}.
@var{distribution} must be a pointer to a univariate continuous
distribution.
The resulting generator object is of the same type as of a
@ifhtml
@ref{funct:unur_distr_cont_new,@command{unur_distr_cont_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_new}
@end ifnothtml
call.
(However, it cannot be used to make an order statistics out of an
order statistics.)

To have a PDF for the order statistics, the given distribution
object must contain a CDF and a PDF. Moreover, it is assumed that
the given PDF is the derivative of the given CDF. Otherwise the
area below the PDF of the order statistics is not computed correctly.

@emph{Important:} There is no warning when the computed area below
the PDF of the order statistics is wrong.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_corder_get_distribution}
@deftypefn Function {const UNUR_DISTR*} unur_distr_corder_get_distribution (const @var{UNUR_DISTR* distribution})
Get pointer to distribution object for underlying distribution.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_corder_get_distribution}
@deftypefn {} {const UNUR_DISTR*} unur_distr_corder_get_distribution (const @var{UNUR_DISTR* distribution})
Get pointer to distribution object for underlying distribution.
@end deftypefn
@end ifnotinfo

@subsubheading Essential parameters

@ifinfo
@anchor{funct:unur_distr_corder_set_rank}
@deftypefn Function {int} unur_distr_corder_set_rank (UNUR_DISTR* @var{distribution}, int @var{n}, int @var{k})
Change sample size @var{n} and rank @var{k} of order statistics.
In case of invalid data, no parameters are changed.
The area below the PDF can be set to that of the underlying
distribution by a
@ifhtml
@ref{funct:unur_distr_corder_upd_pdfarea,@command{unur_distr_corder_upd_pdfarea}}
@end ifhtml
@ifnothtml
@command{unur_distr_corder_upd_pdfarea}
@end ifnothtml
call.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_corder_set_rank}
@deftypefn {} {int} unur_distr_corder_set_rank (UNUR_DISTR* @var{distribution}, int @var{n}, int @var{k})
Change sample size @var{n} and rank @var{k} of order statistics.
In case of invalid data, no parameters are changed.
The area below the PDF can be set to that of the underlying
distribution by a
@ifhtml
@ref{funct:unur_distr_corder_upd_pdfarea,@command{unur_distr_corder_upd_pdfarea}}
@end ifhtml
@ifnothtml
@command{unur_distr_corder_upd_pdfarea}
@end ifnothtml
call.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_corder_get_rank}
@deftypefn Function {int} unur_distr_corder_get_rank (const @var{UNUR_DISTR* distribution}, int* @var{n}, int* @var{k})
Get sample size @var{n} and rank @var{k} of order statistics.
In case of error an error code is returned.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_corder_get_rank}
@deftypefn {} {int} unur_distr_corder_get_rank (const @var{UNUR_DISTR* distribution}, int* @var{n}, int* @var{k})
Get sample size @var{n} and rank @var{k} of order statistics.
In case of error an error code is returned.
@end deftypefn
@end ifnotinfo

Additionally most of the set and get calls for continuous
univariate distributions work. The most important exceptions are
that the PDF and CDF cannot be changed and
@ifhtml
@ref{funct:unur_distr_cont_upd_mode,@command{unur_distr_cont_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_mode}
@end ifnothtml
uses in any way a (slow) numerical
method that might fail.

@ifinfo
@anchor{funct:unur_distr_corder_get_pdf}
@anchor{funct:unur_distr_corder_get_dpdf}
@anchor{funct:unur_distr_corder_get_cdf}
@deftypefn Function {UNUR_FUNCT_CONT*} unur_distr_corder_get_pdf (UNUR_DISTR* @var{distribution})
@deftypefnx Function {UNUR_FUNCT_CONT*} unur_distr_corder_get_dpdf (UNUR_DISTR* @var{distribution})
@deftypefnx Function {UNUR_FUNCT_CONT*} unur_distr_corder_get_cdf (UNUR_DISTR* @var{distribution})
Get the respective pointer to the PDF, the derivative of the
PDF and the CDF of the distribution, respectively. The pointer is of type
@code{double funct(double x, UNUR_DISTR *distr)}.
If the corresponding function is not available for the distribution,
the @code{NULL} pointer is returned.
See also
@ifhtml
@ref{funct:unur_distr_cont_get_pdf,@command{unur_distr_cont_get_pdf}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_get_pdf}.
@end ifnothtml
(Macro)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_corder_get_pdf}
@anchor{funct:unur_distr_corder_get_dpdf}
@anchor{funct:unur_distr_corder_get_cdf}
@deftypefn {} {UNUR_FUNCT_CONT*} unur_distr_corder_get_pdf (UNUR_DISTR* @var{distribution})
@deftypefnx {} {UNUR_FUNCT_CONT*} unur_distr_corder_get_dpdf (UNUR_DISTR* @var{distribution})
@deftypefnx {} {UNUR_FUNCT_CONT*} unur_distr_corder_get_cdf (UNUR_DISTR* @var{distribution})
Get the respective pointer to the PDF, the derivative of the
PDF and the CDF of the distribution, respectively. The pointer is of type
@code{double funct(double x, UNUR_DISTR *distr)}.
If the corresponding function is not available for the distribution,
the @code{NULL} pointer is returned.
See also
@ifhtml
@ref{funct:unur_distr_cont_get_pdf,@command{unur_distr_cont_get_pdf}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_get_pdf}.
@end ifnothtml
(Macro)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_corder_eval_pdf}
@anchor{funct:unur_distr_corder_eval_dpdf}
@anchor{funct:unur_distr_corder_eval_cdf}
@deftypefn Function {double} unur_distr_corder_eval_pdf (double @var{x}, UNUR_DISTR* @var{distribution})
@deftypefnx Function {double} unur_distr_corder_eval_dpdf (double @var{x}, UNUR_DISTR* @var{distribution})
@deftypefnx Function {double} unur_distr_corder_eval_cdf (double @var{x}, UNUR_DISTR* @var{distribution})
Evaluate the PDF, derivative of the PDF. and the CDF,
respectively, at @var{x}.
Notice that @var{distribution} must not be the @code{NULL} pointer.
If the corresponding function is not available for the distribution,
@code{UNUR_INFINITY} is returned and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_DATA}.
See also
@ifhtml
@ref{funct:unur_distr_cont_eval_pdf,@command{unur_distr_cont_eval_pdf}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_eval_pdf}.
@end ifnothtml
(Macro)

@emph{IMPORTANT:}
In the case of a truncated standard distribution these calls always
return the respective values of the @emph{untruncated} distribution!
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_corder_eval_pdf}
@anchor{funct:unur_distr_corder_eval_dpdf}
@anchor{funct:unur_distr_corder_eval_cdf}
@deftypefn {} {double} unur_distr_corder_eval_pdf (double @var{x}, UNUR_DISTR* @var{distribution})
@deftypefnx {} {double} unur_distr_corder_eval_dpdf (double @var{x}, UNUR_DISTR* @var{distribution})
@deftypefnx {} {double} unur_distr_corder_eval_cdf (double @var{x}, UNUR_DISTR* @var{distribution})
Evaluate the PDF, derivative of the PDF. and the CDF,
respectively, at @var{x}.
Notice that @var{distribution} must not be the @code{NULL} pointer.
If the corresponding function is not available for the distribution,
@code{UNUR_INFINITY} is returned and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_DATA}.
See also
@ifhtml
@ref{funct:unur_distr_cont_eval_pdf,@command{unur_distr_cont_eval_pdf}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_eval_pdf}.
@end ifnothtml
(Macro)

@emph{IMPORTANT:}
In the case of a truncated standard distribution these calls always
return the respective values of the @emph{untruncated} distribution!
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_corder_set_pdfparams}
@deftypefn Function {int} unur_distr_corder_set_pdfparams (UNUR_DISTR* @var{distribution}, double* @var{params}, int @var{n_params})
Set array of parameters for underlying distribution.
See
@ifhtml
@ref{funct:unur_distr_cont_set_pdfparams,@command{unur_distr_cont_set_pdfparams}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_pdfparams}
@end ifnothtml
for details.
(Macro)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_corder_set_pdfparams}
@deftypefn {} {int} unur_distr_corder_set_pdfparams (UNUR_DISTR* @var{distribution}, double* @var{params}, int @var{n_params})
Set array of parameters for underlying distribution.
See
@ifhtml
@ref{funct:unur_distr_cont_set_pdfparams,@command{unur_distr_cont_set_pdfparams}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_pdfparams}
@end ifnothtml
for details.
(Macro)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_corder_get_pdfparams}
@deftypefn Function {int} unur_distr_corder_get_pdfparams (UNUR_DISTR* @var{distribution}, double** @var{params})
Get number of parameters of the PDF of the underlying distribution
and set pointer @var{params} to array of parameters.
See
@ifhtml
@ref{funct:unur_distr_cont_get_pdfparams,@command{unur_distr_cont_get_pdfparams}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_get_pdfparams}
@end ifnothtml
for details.
(Macro)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_corder_get_pdfparams}
@deftypefn {} {int} unur_distr_corder_get_pdfparams (UNUR_DISTR* @var{distribution}, double** @var{params})
Get number of parameters of the PDF of the underlying distribution
and set pointer @var{params} to array of parameters.
See
@ifhtml
@ref{funct:unur_distr_cont_get_pdfparams,@command{unur_distr_cont_get_pdfparams}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_get_pdfparams}
@end ifnothtml
for details.
(Macro)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_corder_set_domain}
@deftypefn Function {int} unur_distr_corder_set_domain (UNUR_DISTR* @var{distribution}, double @var{left}, double @var{right})
Set the left and right borders of the domain of the
distribution.
See
@ifhtml
@ref{funct:unur_distr_cont_set_domain,@command{unur_distr_cont_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_domain}
@end ifnothtml
for details.
(Macro)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_corder_set_domain}
@deftypefn {} {int} unur_distr_corder_set_domain (UNUR_DISTR* @var{distribution}, double @var{left}, double @var{right})
Set the left and right borders of the domain of the
distribution.
See
@ifhtml
@ref{funct:unur_distr_cont_set_domain,@command{unur_distr_cont_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_domain}
@end ifnothtml
for details.
(Macro)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_corder_get_domain}
@deftypefn Function {int} unur_distr_corder_get_domain (UNUR_DISTR* @var{distribution}, double* @var{left}, double* @var{right})
Get the left and right borders of the domain of the
distribution.
See
@ifhtml
@ref{funct:unur_distr_cont_get_domain,@command{unur_distr_cont_get_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_get_domain}
@end ifnothtml
for details.
(Macro)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_corder_get_domain}
@deftypefn {} {int} unur_distr_corder_get_domain (UNUR_DISTR* @var{distribution}, double* @var{left}, double* @var{right})
Get the left and right borders of the domain of the
distribution.
See
@ifhtml
@ref{funct:unur_distr_cont_get_domain,@command{unur_distr_cont_get_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_get_domain}
@end ifnothtml
for details.
(Macro)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_corder_get_truncated}
@deftypefn Function {int} unur_distr_corder_get_truncated (UNUR_DISTR* @var{distribution}, double* @var{left}, double* @var{right})
Get the left and right borders of the (truncated) domain of the
distribution.
See
@ifhtml
@ref{funct:unur_distr_cont_get_truncated,@command{unur_distr_cont_get_truncated}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_get_truncated}
@end ifnothtml
for details.
(Macro)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_corder_get_truncated}
@deftypefn {} {int} unur_distr_corder_get_truncated (UNUR_DISTR* @var{distribution}, double* @var{left}, double* @var{right})
Get the left and right borders of the (truncated) domain of the
distribution.
See
@ifhtml
@ref{funct:unur_distr_cont_get_truncated,@command{unur_distr_cont_get_truncated}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_get_truncated}
@end ifnothtml
for details.
(Macro)
@end deftypefn
@end ifnotinfo

@subsubheading Derived parameters

The following paramters @strong{must} be set whenever one of the essential
parameters has been set or changed (and the parameter is required
for the chosen method).

@ifinfo
@anchor{funct:unur_distr_corder_set_mode}
@deftypefn Function {int} unur_distr_corder_set_mode (UNUR_DISTR* @var{distribution}, double @var{mode})
Set mode of distribution.
See also
@ifhtml
@ref{funct:unur_distr_corder_set_mode,@command{unur_distr_corder_set_mode}.}
@end ifhtml
@ifnothtml
@command{unur_distr_corder_set_mode}.
@end ifnothtml
(Macro)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_corder_set_mode}
@deftypefn {} {int} unur_distr_corder_set_mode (UNUR_DISTR* @var{distribution}, double @var{mode})
Set mode of distribution.
See also
@ifhtml
@ref{funct:unur_distr_corder_set_mode,@command{unur_distr_corder_set_mode}.}
@end ifhtml
@ifnothtml
@command{unur_distr_corder_set_mode}.
@end ifnothtml
(Macro)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_corder_upd_mode}
@deftypefn Function {double} unur_distr_corder_upd_mode (UNUR_DISTR* @var{distribution})
Recompute the mode of the distribution numerically. Notice that
this routine is slow and might not work properly in every case.
See also
@ifhtml
@ref{funct:unur_distr_cont_upd_mode,@command{unur_distr_cont_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_mode}
@end ifnothtml
for further details.
(Macro)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_corder_upd_mode}
@deftypefn {} {double} unur_distr_corder_upd_mode (UNUR_DISTR* @var{distribution})
Recompute the mode of the distribution numerically. Notice that
this routine is slow and might not work properly in every case.
See also
@ifhtml
@ref{funct:unur_distr_cont_upd_mode,@command{unur_distr_cont_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_mode}
@end ifnothtml
for further details.
(Macro)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_corder_get_mode}
@deftypefn Function {double} unur_distr_corder_get_mode (UNUR_DISTR* @var{distribution})
Get mode of distribution.
See
@ifhtml
@ref{funct:unur_distr_cont_get_mode,@command{unur_distr_cont_get_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_get_mode}
@end ifnothtml
for details.
(Macro)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_corder_get_mode}
@deftypefn {} {double} unur_distr_corder_get_mode (UNUR_DISTR* @var{distribution})
Get mode of distribution.
See
@ifhtml
@ref{funct:unur_distr_cont_get_mode,@command{unur_distr_cont_get_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_get_mode}
@end ifnothtml
for details.
(Macro)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_corder_set_pdfarea}
@deftypefn Function {int} unur_distr_corder_set_pdfarea (UNUR_DISTR* @var{distribution}, double @var{area})
Set the area below the PDF.
See
@ifhtml
@ref{funct:unur_distr_cont_set_pdfarea,@command{unur_distr_cont_set_pdfarea}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_pdfarea}
@end ifnothtml
for details.
(Macro)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_corder_set_pdfarea}
@deftypefn {} {int} unur_distr_corder_set_pdfarea (UNUR_DISTR* @var{distribution}, double @var{area})
Set the area below the PDF.
See
@ifhtml
@ref{funct:unur_distr_cont_set_pdfarea,@command{unur_distr_cont_set_pdfarea}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_pdfarea}
@end ifnothtml
for details.
(Macro)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_corder_upd_pdfarea}
@deftypefn Function {double} unur_distr_corder_upd_pdfarea (UNUR_DISTR* @var{distribution})
Recompute the area below the PDF of the distribution.
It only works for order statistics for distribution objects from
the UNU.RAN library of standard distributions when the
corresponding function is available.
@ifhtml
@ref{funct:unur_distr_cont_upd_pdfarea,@command{unur_distr_cont_upd_pdfarea}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_pdfarea}
@end ifnothtml
assumes that the PDF of the underlying
distribution is normalized, i.e. it is the derivative of its CDF.
Otherwise the computed area is wrong and there is @strong{no} warning
about this failure.
See
@ifhtml
@ref{funct:unur_distr_cont_upd_pdfarea,@command{unur_distr_cont_upd_pdfarea}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_pdfarea}
@end ifnothtml
for further details.
(Macro)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_corder_upd_pdfarea}
@deftypefn {} {double} unur_distr_corder_upd_pdfarea (UNUR_DISTR* @var{distribution})
Recompute the area below the PDF of the distribution.
It only works for order statistics for distribution objects from
the UNU.RAN library of standard distributions when the
corresponding function is available.
@ifhtml
@ref{funct:unur_distr_cont_upd_pdfarea,@command{unur_distr_cont_upd_pdfarea}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_pdfarea}
@end ifnothtml
assumes that the PDF of the underlying
distribution is normalized, i.e. it is the derivative of its CDF.
Otherwise the computed area is wrong and there is @strong{no} warning
about this failure.
See
@ifhtml
@ref{funct:unur_distr_cont_upd_pdfarea,@command{unur_distr_cont_upd_pdfarea}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_pdfarea}
@end ifnothtml
for further details.
(Macro)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_corder_get_pdfarea}
@deftypefn Function {double} unur_distr_corder_get_pdfarea (UNUR_DISTR* @var{distribution})
Get the area below the PDF of the distribution.
See
@ifhtml
@ref{funct:unur_distr_cont_get_pdfarea,@command{unur_distr_cont_get_pdfarea}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_get_pdfarea}
@end ifnothtml
for details.
(Macro)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_corder_get_pdfarea}
@deftypefn {} {double} unur_distr_corder_get_pdfarea (UNUR_DISTR* @var{distribution})
Get the area below the PDF of the distribution.
See
@ifhtml
@ref{funct:unur_distr_cont_get_pdfarea,@command{unur_distr_cont_get_pdfarea}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_get_pdfarea}
@end ifnothtml
for details.
(Macro)
@end deftypefn
@end ifnotinfo




@c
@c end of corder.h
@c -------------------------------------
@c -------------------------------------
@c cemp.h
@c

@page
@node CEMP
@section   Continuous empirical univariate distributions


Empirical univariate distributions are derived from observed data.
There are two ways to create such a generator object:
@enumerate
@item
By a list of @emph{raw data} by means of a
@ifhtml
@ref{funct:unur_distr_cemp_set_data,@command{unur_distr_cemp_set_data}}
@end ifhtml
@ifnothtml
@command{unur_distr_cemp_set_data}
@end ifnothtml
call.
@item
By a @emph{histogram} (i.e. preprocessed data) by means of a
@ifhtml
@ref{funct:unur_distr_cemp_set_hist,@command{unur_distr_cemp_set_hist}}
@end ifhtml
@ifnothtml
@command{unur_distr_cemp_set_hist}
@end ifnothtml
call.
@end enumerate
How these data are used to sample from the empirical distribution
depends from the chosen generation method.


@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_distr_cemp_new,unur_distr_cemp_new}
@item @ref{funct:unur_distr_cemp_set_data,unur_distr_cemp_set_data}
@item @ref{funct:unur_distr_cemp_read_data,unur_distr_cemp_read_data}
@item @ref{funct:unur_distr_cemp_get_data,unur_distr_cemp_get_data}
@item @ref{funct:unur_distr_cemp_set_hist,unur_distr_cemp_set_hist}
@item @ref{funct:unur_distr_cemp_set_hist_prob,unur_distr_cemp_set_hist_prob}
@item @ref{funct:unur_distr_cemp_set_hist_domain,unur_distr_cemp_set_hist_domain}
@item @ref{funct:unur_distr_cemp_set_hist_bins,unur_distr_cemp_set_hist_bins}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_distr_cemp_new}
@deftypefn Function {UNUR_DISTR*} unur_distr_cemp_new (void)
Create a new (empty) object for empirical univariate continuous distribution.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cemp_new}
@deftypefn {} {UNUR_DISTR*} unur_distr_cemp_new (void)
Create a new (empty) object for empirical univariate continuous distribution.
@end deftypefn
@end ifnotinfo

@subsubheading Essential parameters

@ifinfo
@anchor{funct:unur_distr_cemp_set_data}
@deftypefn Function {int} unur_distr_cemp_set_data (UNUR_DISTR* @var{distribution}, const @var{double* sample}, int @var{n_sample})
Set observed sample for empirical distribution.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cemp_set_data}
@deftypefn {} {int} unur_distr_cemp_set_data (UNUR_DISTR* @var{distribution}, const @var{double* sample}, int @var{n_sample})
Set observed sample for empirical distribution.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cemp_read_data}
@deftypefn Function {int} unur_distr_cemp_read_data (UNUR_DISTR* @var{distribution}, const @var{char* filename})
Read data from file @file{filename}.
It reads the first number from each line.
Numbers are parsed by means of the C standard routine @command{strtod}.
Lines that do not start with @code{+}, @code{-}, @code{.}, or a
digit are ignored. (Beware of lines starting with a blank!)

In case of an error (file cannot be opened, invalid string for
double in line) no data are copied into the distribution object
and an error code is returned.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cemp_read_data}
@deftypefn {} {int} unur_distr_cemp_read_data (UNUR_DISTR* @var{distribution}, const @var{char* filename})
Read data from file @file{filename}.
It reads the first number from each line.
Numbers are parsed by means of the C standard routine @command{strtod}.
Lines that do not start with @code{+}, @code{-}, @code{.}, or a
digit are ignored. (Beware of lines starting with a blank!)

In case of an error (file cannot be opened, invalid string for
double in line) no data are copied into the distribution object
and an error code is returned.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cemp_get_data}
@deftypefn Function {int} unur_distr_cemp_get_data (const @var{UNUR_DISTR* distribution}, const @var{double** sample})
Get number of samples and set pointer @var{sample} to array of
observations. If no sample has been given, an error code
is returned and @code{sample} is set to @code{NULL}.

@emph{Important:} Do @strong{not} change the entries in @var{sample}!
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cemp_get_data}
@deftypefn {} {int} unur_distr_cemp_get_data (const @var{UNUR_DISTR* distribution}, const @var{double** sample})
Get number of samples and set pointer @var{sample} to array of
observations. If no sample has been given, an error code
is returned and @code{sample} is set to @code{NULL}.

@emph{Important:} Do @strong{not} change the entries in @var{sample}!
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cemp_set_hist}
@deftypefn Function {int} unur_distr_cemp_set_hist (UNUR_DISTR* @var{distribution}, const @var{double* prob}, int @var{n_prob}, double @var{xmin}, double @var{xmax})
Set a histogram with bins of equal width. @var{prob} is an array
of length @var{n_prob} that contains the probabilities for the bins
(in ascending order). @var{xmin} and @var{xmax} give the lower and
upper bound of the histogram, respectively. The bins are assumed to
have equal width.

@emph{Remark:} This is shortcut for calling
@ifhtml
@ref{funct:unur_distr_cemp_set_hist_prob,@command{unur_distr_cemp_set_hist_prob}}
@end ifhtml
@ifnothtml
@command{unur_distr_cemp_set_hist_prob}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_distr_cemp_set_hist_domain,@command{unur_distr_cemp_set_hist_domain}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cemp_set_hist_domain}.
@end ifnothtml
@emph{Notice:} All sampling methods either use raw data or histogram.
It is possible to set both types of data; however, it is not
checked whether the given histogran corresponds to possibly given
raw data.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cemp_set_hist}
@deftypefn {} {int} unur_distr_cemp_set_hist (UNUR_DISTR* @var{distribution}, const @var{double* prob}, int @var{n_prob}, double @var{xmin}, double @var{xmax})
Set a histogram with bins of equal width. @var{prob} is an array
of length @var{n_prob} that contains the probabilities for the bins
(in ascending order). @var{xmin} and @var{xmax} give the lower and
upper bound of the histogram, respectively. The bins are assumed to
have equal width.

@emph{Remark:} This is shortcut for calling
@ifhtml
@ref{funct:unur_distr_cemp_set_hist_prob,@command{unur_distr_cemp_set_hist_prob}}
@end ifhtml
@ifnothtml
@command{unur_distr_cemp_set_hist_prob}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_distr_cemp_set_hist_domain,@command{unur_distr_cemp_set_hist_domain}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cemp_set_hist_domain}.
@end ifnothtml
@emph{Notice:} All sampling methods either use raw data or histogram.
It is possible to set both types of data; however, it is not
checked whether the given histogran corresponds to possibly given
raw data.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cemp_set_hist_prob}
@deftypefn Function {int} unur_distr_cemp_set_hist_prob (UNUR_DISTR* @var{distribution}, const @var{double* prob}, int @var{n_prob})
Set probabilities of a histogram with @var{n_prob} bins.
Hence @var{prob} must be an array of length @var{n_prob} that
contains the probabilities for the bins in ascending order.
It is important also to set the location of the bins either
with a
@ifhtml
@ref{funct:unur_distr_cemp_set_hist_domain,@command{unur_distr_cemp_set_hist_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cemp_set_hist_domain}
@end ifnothtml
for bins of equal
width or
@ifhtml
@ref{funct:unur_distr_cemp_set_hist_bins,@command{unur_distr_cemp_set_hist_bins}}
@end ifhtml
@ifnothtml
@command{unur_distr_cemp_set_hist_bins}
@end ifnothtml
when the bins have
different width.

@emph{Notice:} All sampling methods either use raw data or histogram.
It is possible to set both types of data; however, it is not
checked whether the given histogram corresponds to possibly given
raw data.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cemp_set_hist_prob}
@deftypefn {} {int} unur_distr_cemp_set_hist_prob (UNUR_DISTR* @var{distribution}, const @var{double* prob}, int @var{n_prob})
Set probabilities of a histogram with @var{n_prob} bins.
Hence @var{prob} must be an array of length @var{n_prob} that
contains the probabilities for the bins in ascending order.
It is important also to set the location of the bins either
with a
@ifhtml
@ref{funct:unur_distr_cemp_set_hist_domain,@command{unur_distr_cemp_set_hist_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cemp_set_hist_domain}
@end ifnothtml
for bins of equal
width or
@ifhtml
@ref{funct:unur_distr_cemp_set_hist_bins,@command{unur_distr_cemp_set_hist_bins}}
@end ifhtml
@ifnothtml
@command{unur_distr_cemp_set_hist_bins}
@end ifnothtml
when the bins have
different width.

@emph{Notice:} All sampling methods either use raw data or histogram.
It is possible to set both types of data; however, it is not
checked whether the given histogram corresponds to possibly given
raw data.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cemp_set_hist_domain}
@deftypefn Function {int} unur_distr_cemp_set_hist_domain (UNUR_DISTR* @var{distribution}, double @var{xmin}, double @var{xmax})
Set a domain of a histogram with bins of equal width.
@var{xmin} and @var{xmax} give the lower and upper bound of the
histogram, respectively.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cemp_set_hist_domain}
@deftypefn {} {int} unur_distr_cemp_set_hist_domain (UNUR_DISTR* @var{distribution}, double @var{xmin}, double @var{xmax})
Set a domain of a histogram with bins of equal width.
@var{xmin} and @var{xmax} give the lower and upper bound of the
histogram, respectively.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cemp_set_hist_bins}
@deftypefn Function {int} unur_distr_cemp_set_hist_bins (UNUR_DISTR* @var{distribution}, const @var{double* bins}, int @var{n_bins})
Set location of bins of a histogram with @var{n_bins} bins.
Hence @var{bins} must be an array of length @var{n_bins}.
The domain of the @var{distribution} is automatically set by
this call and overrides any calls to
@ifhtml
@ref{funct:unur_distr_cemp_set_hist_domain,@command{unur_distr_cemp_set_hist_domain}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cemp_set_hist_domain}.
@end ifnothtml
@emph{Important:}
The probabilities of the bins of the @var{distribution} must be
already be set by a
@ifhtml
@ref{funct:unur_distr_cemp_set_hist_prob,@command{unur_distr_cemp_set_hist_prob}}
@end ifhtml
@ifnothtml
@command{unur_distr_cemp_set_hist_prob}
@end ifnothtml
(or a
@ifhtml
@ref{funct:unur_distr_cemp_set_hist,@command{unur_distr_cemp_set_hist}}
@end ifhtml
@ifnothtml
@command{unur_distr_cemp_set_hist}
@end ifnothtml
call) and the value of
@var{n_bins} must equal @var{n_prob}@code{+1} from the
corresponding value of the respective call.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cemp_set_hist_bins}
@deftypefn {} {int} unur_distr_cemp_set_hist_bins (UNUR_DISTR* @var{distribution}, const @var{double* bins}, int @var{n_bins})
Set location of bins of a histogram with @var{n_bins} bins.
Hence @var{bins} must be an array of length @var{n_bins}.
The domain of the @var{distribution} is automatically set by
this call and overrides any calls to
@ifhtml
@ref{funct:unur_distr_cemp_set_hist_domain,@command{unur_distr_cemp_set_hist_domain}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cemp_set_hist_domain}.
@end ifnothtml
@emph{Important:}
The probabilities of the bins of the @var{distribution} must be
already be set by a
@ifhtml
@ref{funct:unur_distr_cemp_set_hist_prob,@command{unur_distr_cemp_set_hist_prob}}
@end ifhtml
@ifnothtml
@command{unur_distr_cemp_set_hist_prob}
@end ifnothtml
(or a
@ifhtml
@ref{funct:unur_distr_cemp_set_hist,@command{unur_distr_cemp_set_hist}}
@end ifhtml
@ifnothtml
@command{unur_distr_cemp_set_hist}
@end ifnothtml
call) and the value of
@var{n_bins} must equal @var{n_prob}@code{+1} from the
corresponding value of the respective call.
@end deftypefn
@end ifnotinfo




@c
@c end of cemp.h
@c -------------------------------------
@c -------------------------------------
@c cvec.h
@c

@page
@node CVEC
@section   Continuous multivariate distributions


The following calls handle multivariate distributions.
However, the requirements of particular generation methods is not
as unique as for univariate distributions. Moreover, random vector
generation methods are still under development.
The below functions are a first attempt to handle this situation.

Notice that some of the parameters -- when given carelessly -- might
contradict to others. For example: Some methods require the
marginal distribution and some methods need a standardized form of
the marginal distributions, where the actual mean and variance is
stored in the mean vector and the covariance matrix, respectively.

We also have to mention that some methods might abuse some of the
parameters. Please read the discription of the chosen sampling
method carfully.

The following kind of calls exists:

@itemize @minus
@item Create a @command{new} instance of a continuous multivariate
distribution;

@item Handle and evaluate
probability density function (PDF, @command{pdf}) and the
gradient of the density function (@command{dpdf}).
The following is important:
@itemize .
@item @command{pdf} need not be normalized, i.e.,
any integrable nonnegative function can be used.
@item @command{dpdf} must the derivate of the function provided
as @command{pdf}.
@end itemize

@item Handle and evaluate
the logarithm of the probability density function (logPDF,
@command{logpdf}) and the gradient of the logarithm of the
density function (@command{dlogpdf}).

Some methods use the logarithm of the density if available.

@item Set (and change) parameters (@command{pdfparams}) and the
volume below the graph (@command{pdfvol}) of the given density.

@item Set @command{mode} and @command{mean} of the distribution.

@item Set the @command{center} of the distribution.
It is used by some generation methods to adjust the parameters
of the generation algorithms to gain better performance. It can
be seens as the location of the ``central part'' of the
distribution.

@item Handle the @command{covar}iance matrix of the distribution and
its @command{cholesky} and @command{inv}verse matrices.

@item Set the @command{rankcorr}elation matrix of the distribution.

@item Deal with @command{marginal} distributions.

@item Set domain of the distribution.

@end itemize


@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_distr_cvec_new,unur_distr_cvec_new}
@item @ref{funct:unur_distr_cvec_set_pdf,unur_distr_cvec_set_pdf}
@item @ref{funct:unur_distr_cvec_set_dpdf,unur_distr_cvec_set_dpdf}
@item @ref{funct:unur_distr_cvec_set_pdpdf,unur_distr_cvec_set_pdpdf}
@item @ref{funct:unur_distr_cvec_get_pdf,unur_distr_cvec_get_pdf}
@item @ref{funct:unur_distr_cvec_get_dpdf,unur_distr_cvec_get_dpdf}
@item @ref{funct:unur_distr_cvec_eval_pdf,unur_distr_cvec_eval_pdf}
@item @ref{funct:unur_distr_cvec_eval_dpdf,unur_distr_cvec_eval_dpdf}
@item @ref{funct:unur_distr_cvec_eval_pdpdf,unur_distr_cvec_eval_pdpdf}
@item @ref{funct:unur_distr_cvec_set_logpdf,unur_distr_cvec_set_logpdf}
@item @ref{funct:unur_distr_cvec_set_dlogpdf,unur_distr_cvec_set_dlogpdf}
@item @ref{funct:unur_distr_cvec_set_pdlogpdf,unur_distr_cvec_set_pdlogpdf}
@item @ref{funct:unur_distr_cvec_get_logpdf,unur_distr_cvec_get_logpdf}
@item @ref{funct:unur_distr_cvec_get_dlogpdf,unur_distr_cvec_get_dlogpdf}
@item @ref{funct:unur_distr_cvec_eval_logpdf,unur_distr_cvec_eval_logpdf}
@item @ref{funct:unur_distr_cvec_eval_dlogpdf,unur_distr_cvec_eval_dlogpdf}
@item @ref{funct:unur_distr_cvec_eval_pdlogpdf,unur_distr_cvec_eval_pdlogpdf}
@item @ref{funct:unur_distr_cvec_set_mean,unur_distr_cvec_set_mean}
@item @ref{funct:unur_distr_cvec_get_mean,unur_distr_cvec_get_mean}
@item @ref{funct:unur_distr_cvec_set_covar,unur_distr_cvec_set_covar}
@item @ref{funct:unur_distr_cvec_set_covar_inv,unur_distr_cvec_set_covar_inv}
@item @ref{funct:unur_distr_cvec_get_covar,unur_distr_cvec_get_covar}
@item @ref{funct:unur_distr_cvec_get_cholesky,unur_distr_cvec_get_cholesky}
@item @ref{funct:unur_distr_cvec_get_covar_inv,unur_distr_cvec_get_covar_inv}
@item @ref{funct:unur_distr_cvec_set_rankcorr,unur_distr_cvec_set_rankcorr}
@item @ref{funct:unur_distr_cvec_get_rankcorr,unur_distr_cvec_get_rankcorr}
@item @ref{funct:unur_distr_cvec_get_rk_cholesky,unur_distr_cvec_get_rk_cholesky}
@item @ref{funct:unur_distr_cvec_set_marginals,unur_distr_cvec_set_marginals}
@item @ref{funct:unur_distr_cvec_set_marginal_array,unur_distr_cvec_set_marginal_array}
@item @ref{funct:unur_distr_cvec_set_marginal_list,unur_distr_cvec_set_marginal_list}
@item @ref{funct:unur_distr_cvec_get_marginal,unur_distr_cvec_get_marginal}
@item @ref{funct:unur_distr_cvec_set_pdfparams,unur_distr_cvec_set_pdfparams}
@item @ref{funct:unur_distr_cvec_get_pdfparams,unur_distr_cvec_get_pdfparams}
@item @ref{funct:unur_distr_cvec_set_pdfparams_vec,unur_distr_cvec_set_pdfparams_vec}
@item @ref{funct:unur_distr_cvec_get_pdfparams_vec,unur_distr_cvec_get_pdfparams_vec}
@item @ref{funct:unur_distr_cvec_set_domain_rect,unur_distr_cvec_set_domain_rect}
@item @ref{funct:unur_distr_cvec_is_indomain,unur_distr_cvec_is_indomain}
@item @ref{funct:unur_distr_cvec_set_mode,unur_distr_cvec_set_mode}
@item @ref{funct:unur_distr_cvec_upd_mode,unur_distr_cvec_upd_mode}
@item @ref{funct:unur_distr_cvec_get_mode,unur_distr_cvec_get_mode}
@item @ref{funct:unur_distr_cvec_set_center,unur_distr_cvec_set_center}
@item @ref{funct:unur_distr_cvec_get_center,unur_distr_cvec_get_center}
@item @ref{funct:unur_distr_cvec_set_pdfvol,unur_distr_cvec_set_pdfvol}
@item @ref{funct:unur_distr_cvec_upd_pdfvol,unur_distr_cvec_upd_pdfvol}
@item @ref{funct:unur_distr_cvec_get_pdfvol,unur_distr_cvec_get_pdfvol}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_distr_cvec_new}
@deftypefn Function {UNUR_DISTR*} unur_distr_cvec_new (int @var{dim})
Create a new (empty) object for multivariate continuous
distribution. @var{dim} is the number of components of the random
vector (i.e. its dimension). It is also possible to use dimension 1.
Notice, however, that this is treated as a distribution of random
vectors with only one component and not as a distribution of
real numbers. For the latter
@ifhtml
@ref{funct:unur_distr_cont_new,@command{unur_distr_cont_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_new}
@end ifnothtml
should be used
to create an object for a univariate distribution.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_new}
@deftypefn {} {UNUR_DISTR*} unur_distr_cvec_new (int @var{dim})
Create a new (empty) object for multivariate continuous
distribution. @var{dim} is the number of components of the random
vector (i.e. its dimension). It is also possible to use dimension 1.
Notice, however, that this is treated as a distribution of random
vectors with only one component and not as a distribution of
real numbers. For the latter
@ifhtml
@ref{funct:unur_distr_cont_new,@command{unur_distr_cont_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_new}
@end ifnothtml
should be used
to create an object for a univariate distribution.
@end deftypefn
@end ifnotinfo

@subsubheading Essential parameters

@ifinfo
@anchor{funct:unur_distr_cvec_set_pdf}
@deftypefn Function {int} unur_distr_cvec_set_pdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_CVEC* @var{pdf})
Set respective pointer to the PDF of the @var{distribution}.
This function must be of type
@code{double funct(const double *x, UNUR_DISTR *distr)},
where @var{x} must be a pointer to a double array of appropriate
size (i.e. of the same size as given to the
@ifhtml
@ref{funct:unur_distr_cvec_new,@command{unur_distr_cvec_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_new}
@end ifnothtml
call).

It is not necessary that the given PDF is normalized, i.e. the
integral need not be 1.
Nevertheless the volume below the PDF can be provided by a
@ifhtml
@ref{funct:unur_distr_cvec_set_pdfvol,@command{unur_distr_cvec_set_pdfvol}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_pdfvol}
@end ifnothtml
call.

It is not possible to change the PDF. Once the PDF is set it cannot
be overwritten. This also holds when the logPDF is given.
A new distribution object has to be used instead.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_set_pdf}
@deftypefn {} {int} unur_distr_cvec_set_pdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_CVEC* @var{pdf})
Set respective pointer to the PDF of the @var{distribution}.
This function must be of type
@code{double funct(const double *x, UNUR_DISTR *distr)},
where @var{x} must be a pointer to a double array of appropriate
size (i.e. of the same size as given to the
@ifhtml
@ref{funct:unur_distr_cvec_new,@command{unur_distr_cvec_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_new}
@end ifnothtml
call).

It is not necessary that the given PDF is normalized, i.e. the
integral need not be 1.
Nevertheless the volume below the PDF can be provided by a
@ifhtml
@ref{funct:unur_distr_cvec_set_pdfvol,@command{unur_distr_cvec_set_pdfvol}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_pdfvol}
@end ifnothtml
call.

It is not possible to change the PDF. Once the PDF is set it cannot
be overwritten. This also holds when the logPDF is given.
A new distribution object has to be used instead.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_set_dpdf}
@deftypefn Function {int} unur_distr_cvec_set_dpdf (UNUR_DISTR* @var{distribution}, UNUR_VFUNCT_CVEC* @var{dpdf})
Set pointer to the gradient of the PDF. The type of this function must be
@code{int funct(double *result, const double *x, UNUR_DISTR *distr)},
where @var{result} and @var{x} must be pointers to double arrays of
appropriate size (i.e. of the same size as given to the
@ifhtml
@ref{funct:unur_distr_cvec_new,@command{unur_distr_cvec_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_new}
@end ifnothtml
call).
The gradient of the PDF is stored in the array @var{result}.
The function should return an error code in case of an error and must
return @code{UNUR_SUCCESS} otherwise.

The given function must be the gradient of the function
given by a
@ifhtml
@ref{funct:unur_distr_cvec_set_pdf,@command{unur_distr_cvec_set_pdf}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_pdf}
@end ifnothtml
call.

It is not possible to change the gradient of the PDF. Once the dPDF
is set it cannot be overwritten. This also holds when the gradient
of the logPDF is given.
A new distribution object has to be used instead.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_set_dpdf}
@deftypefn {} {int} unur_distr_cvec_set_dpdf (UNUR_DISTR* @var{distribution}, UNUR_VFUNCT_CVEC* @var{dpdf})
Set pointer to the gradient of the PDF. The type of this function must be
@code{int funct(double *result, const double *x, UNUR_DISTR *distr)},
where @var{result} and @var{x} must be pointers to double arrays of
appropriate size (i.e. of the same size as given to the
@ifhtml
@ref{funct:unur_distr_cvec_new,@command{unur_distr_cvec_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_new}
@end ifnothtml
call).
The gradient of the PDF is stored in the array @var{result}.
The function should return an error code in case of an error and must
return @code{UNUR_SUCCESS} otherwise.

The given function must be the gradient of the function
given by a
@ifhtml
@ref{funct:unur_distr_cvec_set_pdf,@command{unur_distr_cvec_set_pdf}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_pdf}
@end ifnothtml
call.

It is not possible to change the gradient of the PDF. Once the dPDF
is set it cannot be overwritten. This also holds when the gradient
of the logPDF is given.
A new distribution object has to be used instead.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_set_pdpdf}
@deftypefn Function {int} unur_distr_cvec_set_pdpdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCTD_CVEC* @var{pdpdf})
Set pointer to partial derivatives of the PDF. The type of this function must be
@code{double funct(const double *x, int coord, UNUR_DISTR *distr)},
where @var{x} must be a pointer to a double array of appropriate
size (i.e. of the same size as given to the
@ifhtml
@ref{funct:unur_distr_cvec_new,@command{unur_distr_cvec_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_new}
@end ifnothtml
call). @var{coord} is the coordinate for which the partial dervative should be
computed.

Notice that @var{coord} must be an integer from @{0,@dots{},dim-1@}.

It is not possible to change the partial derivative of the PDF. Once the pdPDF
is set it cannot be overwritten. This also holds when the partial derivative
of the logPDF is given.
A new distribution object has to be used instead.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_set_pdpdf}
@deftypefn {} {int} unur_distr_cvec_set_pdpdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCTD_CVEC* @var{pdpdf})
Set pointer to partial derivatives of the PDF. The type of this function must be
@code{double funct(const double *x, int coord, UNUR_DISTR *distr)},
where @var{x} must be a pointer to a double array of appropriate
size (i.e. of the same size as given to the
@ifhtml
@ref{funct:unur_distr_cvec_new,@command{unur_distr_cvec_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_new}
@end ifnothtml
call). @var{coord} is the coordinate for which the partial dervative should be
computed.

Notice that @var{coord} must be an integer from @{0,@dots{},dim-1@}.

It is not possible to change the partial derivative of the PDF. Once the pdPDF
is set it cannot be overwritten. This also holds when the partial derivative
of the logPDF is given.
A new distribution object has to be used instead.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_get_pdf}
@deftypefn Function {UNUR_FUNCT_CVEC*} unur_distr_cvec_get_pdf (const @var{UNUR_DISTR* distribution})
Get the pointer to the PDF of the @var{distribution}. The
pointer is of type
@code{double funct(const double *x, UNUR_DISTR *distr)}.
If the corresponding function is not available for the
@var{distribution}, the @code{NULL} pointer is returned.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_get_pdf}
@deftypefn {} {UNUR_FUNCT_CVEC*} unur_distr_cvec_get_pdf (const @var{UNUR_DISTR* distribution})
Get the pointer to the PDF of the @var{distribution}. The
pointer is of type
@code{double funct(const double *x, UNUR_DISTR *distr)}.
If the corresponding function is not available for the
@var{distribution}, the @code{NULL} pointer is returned.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_get_dpdf}
@deftypefn Function {UNUR_VFUNCT_CVEC*} unur_distr_cvec_get_dpdf (const @var{UNUR_DISTR* distribution})
Get the pointer to the gradient of the PDF of the
@var{distribution}. The pointer is of type
@code{int double funct(double *result, const double *x, UNUR_DISTR *distr)}.
If the corresponding function is not available for the
@var{distribution}, the @code{NULL} pointer is returned.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_get_dpdf}
@deftypefn {} {UNUR_VFUNCT_CVEC*} unur_distr_cvec_get_dpdf (const @var{UNUR_DISTR* distribution})
Get the pointer to the gradient of the PDF of the
@var{distribution}. The pointer is of type
@code{int double funct(double *result, const double *x, UNUR_DISTR *distr)}.
If the corresponding function is not available for the
@var{distribution}, the @code{NULL} pointer is returned.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_eval_pdf}
@deftypefn Function {double} unur_distr_cvec_eval_pdf (const @var{double* x}, UNUR_DISTR* @var{distribution})
Evaluate the PDF of the @var{distribution} at @var{x}.
@var{x} must be a pointer to a double array of appropriate size
(i.e. of the same size as given to the
@ifhtml
@ref{funct:unur_distr_cvec_new,@command{unur_distr_cvec_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_new}
@end ifnothtml
call)
that contains the vector for which the function has to be evaluated.

Notice that @var{distribution} must not be the @code{NULL} pointer.
If the corresponding function is not available for the
@var{distribution}, @code{UNUR_INFINITY} is returned and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_DATA}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_eval_pdf}
@deftypefn {} {double} unur_distr_cvec_eval_pdf (const @var{double* x}, UNUR_DISTR* @var{distribution})
Evaluate the PDF of the @var{distribution} at @var{x}.
@var{x} must be a pointer to a double array of appropriate size
(i.e. of the same size as given to the
@ifhtml
@ref{funct:unur_distr_cvec_new,@command{unur_distr_cvec_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_new}
@end ifnothtml
call)
that contains the vector for which the function has to be evaluated.

Notice that @var{distribution} must not be the @code{NULL} pointer.
If the corresponding function is not available for the
@var{distribution}, @code{UNUR_INFINITY} is returned and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_DATA}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_eval_dpdf}
@deftypefn Function {int} unur_distr_cvec_eval_dpdf (double* @var{result}, const @var{double* x}, UNUR_DISTR* @var{distribution})
Evaluate the gradient of the PDF of the @var{distribution} at
@var{x}.
The result is stored in the double array @var{result}.
Both @var{result} and @var{x} must be pointer to double arrays of
appropriate size (i.e. of the same size as given to the
@ifhtml
@ref{funct:unur_distr_cvec_new,@command{unur_distr_cvec_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_new}
@end ifnothtml
call).

Notice that @var{distribution} must not be the @code{NULL} pointer.
If the corresponding function is not available for the
@var{distribution}, an error code is returned and @code{unur_errno}
is set to @code{UNUR_ERR_DISTR_DATA} (@var{result} is left unmodified).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_eval_dpdf}
@deftypefn {} {int} unur_distr_cvec_eval_dpdf (double* @var{result}, const @var{double* x}, UNUR_DISTR* @var{distribution})
Evaluate the gradient of the PDF of the @var{distribution} at
@var{x}.
The result is stored in the double array @var{result}.
Both @var{result} and @var{x} must be pointer to double arrays of
appropriate size (i.e. of the same size as given to the
@ifhtml
@ref{funct:unur_distr_cvec_new,@command{unur_distr_cvec_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_new}
@end ifnothtml
call).

Notice that @var{distribution} must not be the @code{NULL} pointer.
If the corresponding function is not available for the
@var{distribution}, an error code is returned and @code{unur_errno}
is set to @code{UNUR_ERR_DISTR_DATA} (@var{result} is left unmodified).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_eval_pdpdf}
@deftypefn Function {double} unur_distr_cvec_eval_pdpdf (const @var{double* x}, int @var{coord}, UNUR_DISTR* @var{distribution})
Evaluate the partial derivative of the PDF of the @var{distribution}
at @var{x} for the coordinate @var{coord}.
@var{x} must be a pointer to a double array of appropriate size
(i.e. of the same size as given to the
@ifhtml
@ref{funct:unur_distr_cvec_new,@command{unur_distr_cvec_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_new}
@end ifnothtml
call)
that contains the vector for which the function has to be evaluated.

Notice that @var{coord} must be an integer from @{0,@dots{},dim-1@}.

Notice that @var{distribution} must not be the @code{NULL} pointer.
If the corresponding function is not available for the
@var{distribution}, @code{UNUR_INFINITY} is returned and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_DATA}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_eval_pdpdf}
@deftypefn {} {double} unur_distr_cvec_eval_pdpdf (const @var{double* x}, int @var{coord}, UNUR_DISTR* @var{distribution})
Evaluate the partial derivative of the PDF of the @var{distribution}
at @var{x} for the coordinate @var{coord}.
@var{x} must be a pointer to a double array of appropriate size
(i.e. of the same size as given to the
@ifhtml
@ref{funct:unur_distr_cvec_new,@command{unur_distr_cvec_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_new}
@end ifnothtml
call)
that contains the vector for which the function has to be evaluated.

Notice that @var{coord} must be an integer from @{0,@dots{},dim-1@}.

Notice that @var{distribution} must not be the @code{NULL} pointer.
If the corresponding function is not available for the
@var{distribution}, @code{UNUR_INFINITY} is returned and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_DATA}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_set_logpdf}
@anchor{funct:unur_distr_cvec_set_dlogpdf}
@anchor{funct:unur_distr_cvec_set_pdlogpdf}
@anchor{funct:unur_distr_cvec_get_logpdf}
@anchor{funct:unur_distr_cvec_get_dlogpdf}
@anchor{funct:unur_distr_cvec_eval_logpdf}
@anchor{funct:unur_distr_cvec_eval_dlogpdf}
@anchor{funct:unur_distr_cvec_eval_pdlogpdf}
@deftypefn Function {int} unur_distr_cvec_set_logpdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_CVEC* @var{logpdf})
@deftypefnx Function {int} unur_distr_cvec_set_dlogpdf (UNUR_DISTR* @var{distribution}, UNUR_VFUNCT_CVEC* @var{dlogpdf})
@deftypefnx Function {int} unur_distr_cvec_set_pdlogpdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCTD_CVEC* @var{pdlogpdf})
@deftypefnx Function {UNUR_FUNCT_CVEC*} unur_distr_cvec_get_logpdf (const @var{UNUR_DISTR* distribution})
@deftypefnx Function {UNUR_VFUNCT_CVEC*} unur_distr_cvec_get_dlogpdf (const @var{UNUR_DISTR* distribution})
@deftypefnx Function {double} unur_distr_cvec_eval_logpdf (const @var{double* x}, UNUR_DISTR* @var{distribution})
@deftypefnx Function {int} unur_distr_cvec_eval_dlogpdf (double* @var{result}, const @var{double* x}, UNUR_DISTR* @var{distribution})
@deftypefnx Function {double} unur_distr_cvec_eval_pdlogpdf (const @var{double* x}, int @var{coord}, UNUR_DISTR* @var{distribution})
Analogous calls for the logarithm of the density function.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_set_logpdf}
@anchor{funct:unur_distr_cvec_set_dlogpdf}
@anchor{funct:unur_distr_cvec_set_pdlogpdf}
@anchor{funct:unur_distr_cvec_get_logpdf}
@anchor{funct:unur_distr_cvec_get_dlogpdf}
@anchor{funct:unur_distr_cvec_eval_logpdf}
@anchor{funct:unur_distr_cvec_eval_dlogpdf}
@anchor{funct:unur_distr_cvec_eval_pdlogpdf}
@deftypefn {} {int} unur_distr_cvec_set_logpdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_CVEC* @var{logpdf})
@deftypefnx {} {int} unur_distr_cvec_set_dlogpdf (UNUR_DISTR* @var{distribution}, UNUR_VFUNCT_CVEC* @var{dlogpdf})
@deftypefnx {} {int} unur_distr_cvec_set_pdlogpdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCTD_CVEC* @var{pdlogpdf})
@deftypefnx {} {UNUR_FUNCT_CVEC*} unur_distr_cvec_get_logpdf (const @var{UNUR_DISTR* distribution})
@deftypefnx {} {UNUR_VFUNCT_CVEC*} unur_distr_cvec_get_dlogpdf (const @var{UNUR_DISTR* distribution})
@deftypefnx {} {double} unur_distr_cvec_eval_logpdf (const @var{double* x}, UNUR_DISTR* @var{distribution})
@deftypefnx {} {int} unur_distr_cvec_eval_dlogpdf (double* @var{result}, const @var{double* x}, UNUR_DISTR* @var{distribution})
@deftypefnx {} {double} unur_distr_cvec_eval_pdlogpdf (const @var{double* x}, int @var{coord}, UNUR_DISTR* @var{distribution})
Analogous calls for the logarithm of the density function.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_set_mean}
@deftypefn Function {int} unur_distr_cvec_set_mean (UNUR_DISTR* @var{distribution}, const @var{double* mean})
Set mean vector for multivariate @var{distribution}.
@var{mean} must be a pointer to an array of size @code{dim}, where
@code{dim} is the dimension returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
A @code{NULL} pointer for @var{mean} is interpreted as the zero
vector (0,@dots{},0).

@strong{Important:} If the parameters of a distribution from the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions})
are changed, then neither its mode nor the normalization
constant are updated. Please use the respective calls
@ifhtml
@ref{funct:unur_distr_cvec_upd_mode,@command{unur_distr_cvec_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_upd_mode}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_distr_cvec_upd_pdfvol,@command{unur_distr_cvec_upd_pdfvol}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_upd_pdfvol}.
@end ifnothtml
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_set_mean}
@deftypefn {} {int} unur_distr_cvec_set_mean (UNUR_DISTR* @var{distribution}, const @var{double* mean})
Set mean vector for multivariate @var{distribution}.
@var{mean} must be a pointer to an array of size @code{dim}, where
@code{dim} is the dimension returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
A @code{NULL} pointer for @var{mean} is interpreted as the zero
vector (0,@dots{},0).

@strong{Important:} If the parameters of a distribution from the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions})
are changed, then neither its mode nor the normalization
constant are updated. Please use the respective calls
@ifhtml
@ref{funct:unur_distr_cvec_upd_mode,@command{unur_distr_cvec_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_upd_mode}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_distr_cvec_upd_pdfvol,@command{unur_distr_cvec_upd_pdfvol}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_upd_pdfvol}.
@end ifnothtml
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_get_mean}
@deftypefn Function {const double*} unur_distr_cvec_get_mean (const @var{UNUR_DISTR* distribution})
Get the mean vector of the @var{distribution}. The function returns a
pointer to an array of size @code{dim}.
If the mean vector is not marked as known the @code{NULL} pointer is
returned and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_GET}.

@emph{Important:} Do @strong{not} modify the array that holds the
mean vector!
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_get_mean}
@deftypefn {} {const double*} unur_distr_cvec_get_mean (const @var{UNUR_DISTR* distribution})
Get the mean vector of the @var{distribution}. The function returns a
pointer to an array of size @code{dim}.
If the mean vector is not marked as known the @code{NULL} pointer is
returned and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_GET}.

@emph{Important:} Do @strong{not} modify the array that holds the
mean vector!
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_set_covar}
@deftypefn Function {int} unur_distr_cvec_set_covar (UNUR_DISTR* @var{distribution}, const @var{double* covar})
Set covariance matrix for multivariate @var{distribution}.
@var{covar} must be a pointer to an array of size
@code{dim} x @code{dim}, where @code{dim} is the dimension returned
by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
The rows of the matrix have to be stored
consecutively in this array.

@var{covar} must be a variance-covariance matrix of the
@var{distribution}, i.e. it must be symmetric and positive definit and
its diagonal entries (i.e. the variance of the components of the
random vector) must be strictly positive.
The Cholesky factor is computed (and stored) to verify the positive
definiteness condition.
Notice that the inverse of the given covariance matrix is
automatically computed when it is requested by some routine.
Notice that the computation of this inverse matrix is unstable in
case of high correlations and/or high dimensions. Thus it might
fail and methods that require this inverse cannot be used.
As an alternative the inverse of the covariance matrix can be
directly set by a
@ifhtml
@ref{funct:unur_distr_cvec_set_covar_inv,@command{unur_distr_cvec_set_covar_inv}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_covar_inv}
@end ifnothtml
call.

A @code{NULL} pointer for @var{covar} is interpreted as the
identity matrix.

@emph{Important:} This entry is abused in some methods which do not
require the covariance matrix. It is then used to perform some
transformation to obtain better performance.

@emph{Important:} In case of an error (e.g. because @var{covar} is
not a valid covariance matrix) an error code is returned.
Moreover, the covariance matrix is not set and is marked as
unknown. A previously set covariance matrix is then no longer
available.

@strong{Important:} If the parameters of a distribution from the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions})
are changed, then neither its mode nor the normalization
constant are updated. Please use the respective calls
@ifhtml
@ref{funct:unur_distr_cvec_upd_mode,@command{unur_distr_cvec_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_upd_mode}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_distr_cvec_upd_pdfvol,@command{unur_distr_cvec_upd_pdfvol}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_upd_pdfvol}.
@end ifnothtml
@emph{Remark:} UNU.RAN does not check whether the an eventually
set covariance matrix and a rank-correlation matrix do not
contradict each other.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_set_covar}
@deftypefn {} {int} unur_distr_cvec_set_covar (UNUR_DISTR* @var{distribution}, const @var{double* covar})
Set covariance matrix for multivariate @var{distribution}.
@var{covar} must be a pointer to an array of size
@code{dim} x @code{dim}, where @code{dim} is the dimension returned
by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
The rows of the matrix have to be stored
consecutively in this array.

@var{covar} must be a variance-covariance matrix of the
@var{distribution}, i.e. it must be symmetric and positive definit and
its diagonal entries (i.e. the variance of the components of the
random vector) must be strictly positive.
The Cholesky factor is computed (and stored) to verify the positive
definiteness condition.
Notice that the inverse of the given covariance matrix is
automatically computed when it is requested by some routine.
Notice that the computation of this inverse matrix is unstable in
case of high correlations and/or high dimensions. Thus it might
fail and methods that require this inverse cannot be used.
As an alternative the inverse of the covariance matrix can be
directly set by a
@ifhtml
@ref{funct:unur_distr_cvec_set_covar_inv,@command{unur_distr_cvec_set_covar_inv}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_covar_inv}
@end ifnothtml
call.

A @code{NULL} pointer for @var{covar} is interpreted as the
identity matrix.

@emph{Important:} This entry is abused in some methods which do not
require the covariance matrix. It is then used to perform some
transformation to obtain better performance.

@emph{Important:} In case of an error (e.g. because @var{covar} is
not a valid covariance matrix) an error code is returned.
Moreover, the covariance matrix is not set and is marked as
unknown. A previously set covariance matrix is then no longer
available.

@strong{Important:} If the parameters of a distribution from the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions})
are changed, then neither its mode nor the normalization
constant are updated. Please use the respective calls
@ifhtml
@ref{funct:unur_distr_cvec_upd_mode,@command{unur_distr_cvec_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_upd_mode}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_distr_cvec_upd_pdfvol,@command{unur_distr_cvec_upd_pdfvol}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_upd_pdfvol}.
@end ifnothtml
@emph{Remark:} UNU.RAN does not check whether the an eventually
set covariance matrix and a rank-correlation matrix do not
contradict each other.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_set_covar_inv}
@deftypefn Function {int} unur_distr_cvec_set_covar_inv (UNUR_DISTR* @var{distribution}, const @var{double* covar_inv})
Set inverse of the covariance matrix for multivariate @var{distribution}.
@var{covar_inv} must be a pointer to an array of size
@code{dim} x @code{dim}, where @code{dim} is the dimension returned
by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
The rows of the matrix have to be stored
consecutively in this array.

@var{covar_inv} must be symmetric and positive definit. Only the
symmetry of the matrix is checked.

A @code{NULL} pointer for @var{covar_inv} is interpreted as the identity matrix.

@emph{Important:} In case of an error (because @var{covar_inv} is
not symetric) an error code is returned.
Moreover, the inverse of the covariance matrix is not set and is
marked as unknown. A previously set inverse matrix is then no longer
available.

@emph{Remark:} UNU.RAN does not check whether the given matrix is
positive definit.

@emph{Remark:} UNU.RAN does not check whether the matrix
@var{covar_inv} is the inverse of the eventually set covariance
matrix.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_set_covar_inv}
@deftypefn {} {int} unur_distr_cvec_set_covar_inv (UNUR_DISTR* @var{distribution}, const @var{double* covar_inv})
Set inverse of the covariance matrix for multivariate @var{distribution}.
@var{covar_inv} must be a pointer to an array of size
@code{dim} x @code{dim}, where @code{dim} is the dimension returned
by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
The rows of the matrix have to be stored
consecutively in this array.

@var{covar_inv} must be symmetric and positive definit. Only the
symmetry of the matrix is checked.

A @code{NULL} pointer for @var{covar_inv} is interpreted as the identity matrix.

@emph{Important:} In case of an error (because @var{covar_inv} is
not symetric) an error code is returned.
Moreover, the inverse of the covariance matrix is not set and is
marked as unknown. A previously set inverse matrix is then no longer
available.

@emph{Remark:} UNU.RAN does not check whether the given matrix is
positive definit.

@emph{Remark:} UNU.RAN does not check whether the matrix
@var{covar_inv} is the inverse of the eventually set covariance
matrix.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_get_covar}
@anchor{funct:unur_distr_cvec_get_cholesky}
@anchor{funct:unur_distr_cvec_get_covar_inv}
@deftypefn Function {const double*} unur_distr_cvec_get_covar (const @var{UNUR_DISTR* distribution})
@deftypefnx Function {const double*} unur_distr_cvec_get_cholesky (const @var{UNUR_DISTR* distribution})
@deftypefnx Function {const double*} unur_distr_cvec_get_covar_inv (UNUR_DISTR* @var{distribution})
Get covariance matrix of @var{distribution}, its Cholesky factor,
and its inverse, respectively. The function returns a
pointer to an array of size @code{dim} x @code{dim}.
The rows of the matrix are stored consecutively in this array.
If the requested matrix is not marked as known the @code{NULL}
pointer is returned and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_GET}.

@emph{Important:} Do @strong{not} modify the array that holds the
covariance matrix!

@emph{Remark:} The inverse of the covariance matrix is computed
if it is not already stored.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_get_covar}
@anchor{funct:unur_distr_cvec_get_cholesky}
@anchor{funct:unur_distr_cvec_get_covar_inv}
@deftypefn {} {const double*} unur_distr_cvec_get_covar (const @var{UNUR_DISTR* distribution})
@deftypefnx {} {const double*} unur_distr_cvec_get_cholesky (const @var{UNUR_DISTR* distribution})
@deftypefnx {} {const double*} unur_distr_cvec_get_covar_inv (UNUR_DISTR* @var{distribution})
Get covariance matrix of @var{distribution}, its Cholesky factor,
and its inverse, respectively. The function returns a
pointer to an array of size @code{dim} x @code{dim}.
The rows of the matrix are stored consecutively in this array.
If the requested matrix is not marked as known the @code{NULL}
pointer is returned and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_GET}.

@emph{Important:} Do @strong{not} modify the array that holds the
covariance matrix!

@emph{Remark:} The inverse of the covariance matrix is computed
if it is not already stored.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_set_rankcorr}
@deftypefn Function {int} unur_distr_cvec_set_rankcorr (UNUR_DISTR* @var{distribution}, const @var{double* rankcorr})
Set rank-correlation matrix (Spearman's correlation) for
multivariate @var{distribution}.
@var{rankcorr} must be a pointer to an array of size
@code{dim} x @code{dim}, where @code{dim} is the dimension returned
by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
The rows of the matrix have to be stored
consecutively in this array.

@var{rankcorr} must be a rank-correlation matrix of the
@var{distribution}, i.e. it must be symmetric and positive definite
and its diagonal entries must be equal to @code{1}.

The Cholesky factor is computed (and stored) to verify the
positive definiteness condition.

A @code{NULL} pointer for @var{rankcorr} is interpreted as the identity matrix.

@emph{Important:} In case of an error (e.g. because @var{rankcorr} is
not a valid rank-correlation matrix) an error code is returned.
Moreover, the rank-correlation matrix is not set and is marked as
unknown. A previously set rank-correlation matrix is then no longer
available.

@emph{Remark:} UNU.RAN does not check whether the an eventually
set covariance matrix and a rank-correlation matrix do not
contradict each other.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_set_rankcorr}
@deftypefn {} {int} unur_distr_cvec_set_rankcorr (UNUR_DISTR* @var{distribution}, const @var{double* rankcorr})
Set rank-correlation matrix (Spearman's correlation) for
multivariate @var{distribution}.
@var{rankcorr} must be a pointer to an array of size
@code{dim} x @code{dim}, where @code{dim} is the dimension returned
by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
The rows of the matrix have to be stored
consecutively in this array.

@var{rankcorr} must be a rank-correlation matrix of the
@var{distribution}, i.e. it must be symmetric and positive definite
and its diagonal entries must be equal to @code{1}.

The Cholesky factor is computed (and stored) to verify the
positive definiteness condition.

A @code{NULL} pointer for @var{rankcorr} is interpreted as the identity matrix.

@emph{Important:} In case of an error (e.g. because @var{rankcorr} is
not a valid rank-correlation matrix) an error code is returned.
Moreover, the rank-correlation matrix is not set and is marked as
unknown. A previously set rank-correlation matrix is then no longer
available.

@emph{Remark:} UNU.RAN does not check whether the an eventually
set covariance matrix and a rank-correlation matrix do not
contradict each other.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_get_rankcorr}
@anchor{funct:unur_distr_cvec_get_rk_cholesky}
@deftypefn Function {const double*} unur_distr_cvec_get_rankcorr (const @var{UNUR_DISTR* distribution})
@deftypefnx Function {const double*} unur_distr_cvec_get_rk_cholesky (const @var{UNUR_DISTR* distribution})
Get rank-correlation matrix and its cholesky factor, respectively,
of @var{distribution}. The function
returns a pointer to an array of size @code{dim} x @code{dim}.
The rows of the matrix are stored consecutively in this array.
If the requested matrix is not marked as known the @code{NULL}
pointer is returned and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_GET}.

@emph{Important:} Do @strong{not} modify the array that holds the
rank-correlation matrix!
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_get_rankcorr}
@anchor{funct:unur_distr_cvec_get_rk_cholesky}
@deftypefn {} {const double*} unur_distr_cvec_get_rankcorr (const @var{UNUR_DISTR* distribution})
@deftypefnx {} {const double*} unur_distr_cvec_get_rk_cholesky (const @var{UNUR_DISTR* distribution})
Get rank-correlation matrix and its cholesky factor, respectively,
of @var{distribution}. The function
returns a pointer to an array of size @code{dim} x @code{dim}.
The rows of the matrix are stored consecutively in this array.
If the requested matrix is not marked as known the @code{NULL}
pointer is returned and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_GET}.

@emph{Important:} Do @strong{not} modify the array that holds the
rank-correlation matrix!
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_set_marginals}
@deftypefn Function {int} unur_distr_cvec_set_marginals (UNUR_DISTR* @var{distribution}, UNUR_DISTR* @var{marginal})
Sets marginal distributions of the given @var{distribution} to the
same @var{marginal} distribution object. The @var{marginal}
distribution must be an instance of a continuous univariate
distribution object. Notice that the marginal distribution is
copied into the @var{distribution} object.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_set_marginals}
@deftypefn {} {int} unur_distr_cvec_set_marginals (UNUR_DISTR* @var{distribution}, UNUR_DISTR* @var{marginal})
Sets marginal distributions of the given @var{distribution} to the
same @var{marginal} distribution object. The @var{marginal}
distribution must be an instance of a continuous univariate
distribution object. Notice that the marginal distribution is
copied into the @var{distribution} object.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_set_marginal_array}
@deftypefn Function {int} unur_distr_cvec_set_marginal_array (UNUR_DISTR* @var{distribution}, UNUR_DISTR** @var{marginals})
Analogously to the above
@ifhtml
@ref{funct:unur_distr_cvec_set_marginals,@command{unur_distr_cvec_set_marginals}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_marginals}
@end ifnothtml
call.
However, now an array @var{marginals} of the pointers to each of
the marginal distributions must be given. It @strong{must} be an
array of size @code{dim}, where @code{dim} is the dimension
returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
@emph{Notice}: Local copies for each of the entries are stored in
the @var{distribution} object. If some of these entries are
identical (i.e. contain the same pointer), then for each of these a
new copy is made.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_set_marginal_array}
@deftypefn {} {int} unur_distr_cvec_set_marginal_array (UNUR_DISTR* @var{distribution}, UNUR_DISTR** @var{marginals})
Analogously to the above
@ifhtml
@ref{funct:unur_distr_cvec_set_marginals,@command{unur_distr_cvec_set_marginals}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_marginals}
@end ifnothtml
call.
However, now an array @var{marginals} of the pointers to each of
the marginal distributions must be given. It @strong{must} be an
array of size @code{dim}, where @code{dim} is the dimension
returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
@emph{Notice}: Local copies for each of the entries are stored in
the @var{distribution} object. If some of these entries are
identical (i.e. contain the same pointer), then for each of these a
new copy is made.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_set_marginal_list}
@deftypefn Function {int} unur_distr_cvec_set_marginal_list (UNUR_DISTR* @var{distribution}, ...)
Similar to the above
@ifhtml
@ref{funct:unur_distr_cvec_set_marginal_array,@command{unur_distr_cvec_set_marginal_array}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_marginal_array}
@end ifnothtml
call.
However, now the pointers to the particular marginal distributions
can be given as parameter and does not require an array of
pointers. Additionally the given distribution objects are
immediately destroyed. Thus calls like
@ifhtml
@ref{funct:unur_distr_normal,@command{unur_distr_normal}}
@end ifhtml
@ifnothtml
@command{unur_distr_normal}
@end ifnothtml
can be
used as arguments.
(With
@ifhtml
@ref{funct:unur_distr_cvec_set_marginal_array,@command{unur_distr_cvec_set_marginal_array}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_marginal_array}
@end ifnothtml
the result of such call
has to be stored in a pointer since it has to be freed afterwarts
to avoid memory leaks!)

The number of pointers to in the list of function arguments
@strong{must} be equal to the dimension of the @var{distribution},
i.e. the dimension returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
If one of the given pointer to marginal distributions is the @code{NULL}
pointer then the marginal distributions of @var{distribution} are
not set (or previous settings are not changed) and an error code is
returned.

@strong{Important:} All distribution objects given in the argument
list are destroyed!
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_set_marginal_list}
@deftypefn {} {int} unur_distr_cvec_set_marginal_list (UNUR_DISTR* @var{distribution}, ...)
Similar to the above
@ifhtml
@ref{funct:unur_distr_cvec_set_marginal_array,@command{unur_distr_cvec_set_marginal_array}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_marginal_array}
@end ifnothtml
call.
However, now the pointers to the particular marginal distributions
can be given as parameter and does not require an array of
pointers. Additionally the given distribution objects are
immediately destroyed. Thus calls like
@ifhtml
@ref{funct:unur_distr_normal,@command{unur_distr_normal}}
@end ifhtml
@ifnothtml
@command{unur_distr_normal}
@end ifnothtml
can be
used as arguments.
(With
@ifhtml
@ref{funct:unur_distr_cvec_set_marginal_array,@command{unur_distr_cvec_set_marginal_array}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_marginal_array}
@end ifnothtml
the result of such call
has to be stored in a pointer since it has to be freed afterwarts
to avoid memory leaks!)

The number of pointers to in the list of function arguments
@strong{must} be equal to the dimension of the @var{distribution},
i.e. the dimension returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
If one of the given pointer to marginal distributions is the @code{NULL}
pointer then the marginal distributions of @var{distribution} are
not set (or previous settings are not changed) and an error code is
returned.

@strong{Important:} All distribution objects given in the argument
list are destroyed!
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_get_marginal}
@deftypefn Function {const UNUR_DISTR*} unur_distr_cvec_get_marginal (const @var{UNUR_DISTR* distribution}, int @var{n})
Get pointer to the @var{n}-th marginal distribution
object from the given multivariate @var{distribution}.
If this does not exist, @code{NULL} is returned.
The marginal distributions are enumerated from @code{1}
to @code{dim}, where @code{dim} is the dimension
returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_get_marginal}
@deftypefn {} {const UNUR_DISTR*} unur_distr_cvec_get_marginal (const @var{UNUR_DISTR* distribution}, int @var{n})
Get pointer to the @var{n}-th marginal distribution
object from the given multivariate @var{distribution}.
If this does not exist, @code{NULL} is returned.
The marginal distributions are enumerated from @code{1}
to @code{dim}, where @code{dim} is the dimension
returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_set_pdfparams}
@deftypefn Function {int} unur_distr_cvec_set_pdfparams (UNUR_DISTR* @var{distribution}, const @var{double* params}, int @var{n_params})
Sets array of parameters for @var{distribution}. There is an upper limit
for the number of parameters @code{n_params}. It is given by the
macro @code{UNUR_DISTR_MAXPARAMS} in @file{unuran_config.h}. (It is set to
5 by default but can be changed to any appropriate nonnegative number.)
If @var{n_params} is negative or exceeds this limit no parameters
are copied into the distribution object and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_NPARAMS}.

For standard distributions from the UNU.RAN library the parameters
are checked. Moreover, the domain is updated automatically.
If the given parameters are invalid for the standard distribution,
then no parameters are set and an error code is returned.
Notice that the given parameter list for such a distribution is
handled in the same way as in the corresponding @command{new}
calls, i.e. optional parameters for the PDF that are not present in
the given list are (re-)set to their default values.

@strong{Important:} If the parameters of a distribution from the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions})
are changed, then neither its mode nor the normalization
constant are updated. Please use the respective calls
@ifhtml
@ref{funct:unur_distr_cvec_upd_mode,@command{unur_distr_cvec_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_upd_mode}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_distr_cvec_upd_pdfvol,@command{unur_distr_cvec_upd_pdfvol}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_upd_pdfvol}.
@end ifnothtml
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_set_pdfparams}
@deftypefn {} {int} unur_distr_cvec_set_pdfparams (UNUR_DISTR* @var{distribution}, const @var{double* params}, int @var{n_params})
Sets array of parameters for @var{distribution}. There is an upper limit
for the number of parameters @code{n_params}. It is given by the
macro @code{UNUR_DISTR_MAXPARAMS} in @file{unuran_config.h}. (It is set to
5 by default but can be changed to any appropriate nonnegative number.)
If @var{n_params} is negative or exceeds this limit no parameters
are copied into the distribution object and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_NPARAMS}.

For standard distributions from the UNU.RAN library the parameters
are checked. Moreover, the domain is updated automatically.
If the given parameters are invalid for the standard distribution,
then no parameters are set and an error code is returned.
Notice that the given parameter list for such a distribution is
handled in the same way as in the corresponding @command{new}
calls, i.e. optional parameters for the PDF that are not present in
the given list are (re-)set to their default values.

@strong{Important:} If the parameters of a distribution from the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions})
are changed, then neither its mode nor the normalization
constant are updated. Please use the respective calls
@ifhtml
@ref{funct:unur_distr_cvec_upd_mode,@command{unur_distr_cvec_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_upd_mode}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_distr_cvec_upd_pdfvol,@command{unur_distr_cvec_upd_pdfvol}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_upd_pdfvol}.
@end ifnothtml
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_get_pdfparams}
@deftypefn Function {int} unur_distr_cvec_get_pdfparams (const @var{UNUR_DISTR* distribution}, const @var{double** params})
Get number of parameters of the PDF and set pointer @var{params} to
array of parameters. If no parameters are stored in the object, an
error code is returned and @code{params} is set to @code{NULL}.

@emph{Important:} Do @strong{not} change the entries in @var{params}!
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_get_pdfparams}
@deftypefn {} {int} unur_distr_cvec_get_pdfparams (const @var{UNUR_DISTR* distribution}, const @var{double** params})
Get number of parameters of the PDF and set pointer @var{params} to
array of parameters. If no parameters are stored in the object, an
error code is returned and @code{params} is set to @code{NULL}.

@emph{Important:} Do @strong{not} change the entries in @var{params}!
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_set_pdfparams_vec}
@deftypefn Function {int} unur_distr_cvec_set_pdfparams_vec (UNUR_DISTR* @var{distribution}, int @var{par}, const @var{double* param_vec}, int @var{n_params})
This function provides an interface for additional vector parameters for a
multivariate @var{distribution} besides mean vector and covariance
matrix which have their own calls.

It sets the parameter with number @var{par}.
@var{par} indicates directly which of the parameters is set and
must be a number between @code{0} and @code{UNUR_DISTR_MAXPARAMS}-1
(the upper limit of possible parameters defined in
@file{unuran_config.h}; it is set to 5 but can be changed to any
appropriate nonnegative number.)

The entries of a this parameter are given by the array @var{param_vec}
of size @var{n_params}. Notice that using this interface an
An (@i{n} x @i{m})-matrix has to be stored in an array of length
@var{n_params} = @i{n} times @i{m}; where the rows of the matrix
are stored consecutively in this array.

Due to great variety of possible parameters for a multivariate
@var{distribution} there is no simpler interface.

If @var{param_vec} is @code{NULL} then the corresponding entry is cleared.

@strong{Important:} If the parameters of a distribution from the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions})
are changed, then neither its mode nor the normalization
constant are updated. Please use the respective calls
@ifhtml
@ref{funct:unur_distr_cvec_upd_mode,@command{unur_distr_cvec_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_upd_mode}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_distr_cvec_upd_pdfvol,@command{unur_distr_cvec_upd_pdfvol}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_upd_pdfvol}.
@end ifnothtml
If an error occurs no parameters are copied into the parameter
object @code{unur_errno} is set to @code{UNUR_ERR_DISTR_DATA}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_set_pdfparams_vec}
@deftypefn {} {int} unur_distr_cvec_set_pdfparams_vec (UNUR_DISTR* @var{distribution}, int @var{par}, const @var{double* param_vec}, int @var{n_params})
This function provides an interface for additional vector parameters for a
multivariate @var{distribution} besides mean vector and covariance
matrix which have their own calls.

It sets the parameter with number @var{par}.
@var{par} indicates directly which of the parameters is set and
must be a number between @code{0} and @code{UNUR_DISTR_MAXPARAMS}-1
(the upper limit of possible parameters defined in
@file{unuran_config.h}; it is set to 5 but can be changed to any
appropriate nonnegative number.)

The entries of a this parameter are given by the array @var{param_vec}
of size @var{n_params}. Notice that using this interface an
An (@i{n} x @i{m})-matrix has to be stored in an array of length
@var{n_params} = @i{n} times @i{m}; where the rows of the matrix
are stored consecutively in this array.

Due to great variety of possible parameters for a multivariate
@var{distribution} there is no simpler interface.

If @var{param_vec} is @code{NULL} then the corresponding entry is cleared.

@strong{Important:} If the parameters of a distribution from the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions})
are changed, then neither its mode nor the normalization
constant are updated. Please use the respective calls
@ifhtml
@ref{funct:unur_distr_cvec_upd_mode,@command{unur_distr_cvec_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_upd_mode}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_distr_cvec_upd_pdfvol,@command{unur_distr_cvec_upd_pdfvol}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_upd_pdfvol}.
@end ifnothtml
If an error occurs no parameters are copied into the parameter
object @code{unur_errno} is set to @code{UNUR_ERR_DISTR_DATA}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_get_pdfparams_vec}
@deftypefn Function {int} unur_distr_cvec_get_pdfparams_vec (const @var{UNUR_DISTR* distribution}, int @var{par}, const @var{double** param_vecs})
Get parameter of the PDF with number @var{par}.
The pointer to the parameter array is stored in @var{param_vecs}, its
size is returned by the function.
If the requested parameter is not set, then an error code is returned
and @code{params} is set to @code{NULL}.

@emph{Important:} Do @strong{not} change the entries in @var{param_vecs}!
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_get_pdfparams_vec}
@deftypefn {} {int} unur_distr_cvec_get_pdfparams_vec (const @var{UNUR_DISTR* distribution}, int @var{par}, const @var{double** param_vecs})
Get parameter of the PDF with number @var{par}.
The pointer to the parameter array is stored in @var{param_vecs}, its
size is returned by the function.
If the requested parameter is not set, then an error code is returned
and @code{params} is set to @code{NULL}.

@emph{Important:} Do @strong{not} change the entries in @var{param_vecs}!
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_set_domain_rect}
@deftypefn Function {int} unur_distr_cvec_set_domain_rect (UNUR_DISTR* @var{distribution}, const @var{double* lowerleft}, const @var{double* upperright})
Set rectangular domain for @var{distribution} with @var{lowerleft}
and @var{upperright} vertices. Both must be pointer to an
array of the size returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
A @code{NULL} pointer is interpreted as the zero vector (0,@dots{},0).
For setting a coordinate of the boundary to
@math{+/- infinity}
use @code{+/- UNUR_INFINITY}.
The @var{lowerleft} vertex must be strictly smaller than
@var{upperright} in each component. Otherwise no domain
is set and @code{unur_errno} is set to @code{UNUR_ERR_DISTR_SET}.

By default the domain of a distribution is unbounded. Thus one can
use this call to truncate an existing distribution.

@emph{Important:} Changing the domain of @var{distribution}
marks derived parameters like the mode or the center as unknown and
must be set @emph{after} changing the domain. This is important for
the already set (or default) value for the center does not
fall into the given domain.
Notice that calls of the PDF and derived functions return @code{0.}
when the parameter is not contained in the domain.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_set_domain_rect}
@deftypefn {} {int} unur_distr_cvec_set_domain_rect (UNUR_DISTR* @var{distribution}, const @var{double* lowerleft}, const @var{double* upperright})
Set rectangular domain for @var{distribution} with @var{lowerleft}
and @var{upperright} vertices. Both must be pointer to an
array of the size returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
A @code{NULL} pointer is interpreted as the zero vector (0,@dots{},0).
For setting a coordinate of the boundary to
@iftex
@math{\pm\infty}
@end iftex
@ifhtml
@html
+/- infinity
@end html
@end ifhtml
use @code{+/- UNUR_INFINITY}.
The @var{lowerleft} vertex must be strictly smaller than
@var{upperright} in each component. Otherwise no domain
is set and @code{unur_errno} is set to @code{UNUR_ERR_DISTR_SET}.

By default the domain of a distribution is unbounded. Thus one can
use this call to truncate an existing distribution.

@emph{Important:} Changing the domain of @var{distribution}
marks derived parameters like the mode or the center as unknown and
must be set @emph{after} changing the domain. This is important for
the already set (or default) value for the center does not
fall into the given domain.
Notice that calls of the PDF and derived functions return @code{0.}
when the parameter is not contained in the domain.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_is_indomain}
@deftypefn Function {int} unur_distr_cvec_is_indomain (const @var{double* x}, const @var{UNUR_DISTR* distribution})
Check whether @var{x} falls into the domain of @var{distribution}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_is_indomain}
@deftypefn {} {int} unur_distr_cvec_is_indomain (const @var{double* x}, const @var{UNUR_DISTR* distribution})
Check whether @var{x} falls into the domain of @var{distribution}.
@end deftypefn
@end ifnotinfo

@subsubheading Derived parameters

The following paramters @strong{must} be set whenever one of the
essential parameters has been set or changed (and the parameter is
required for the chosen method).

@ifinfo
@anchor{funct:unur_distr_cvec_set_mode}
@deftypefn Function {int} unur_distr_cvec_set_mode (UNUR_DISTR* @var{distribution}, const @var{double* mode})
Set mode of the @var{distribution}. @var{mode} must be a pointer to an
array of the size returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
A @code{NULL} pointer for @var{mode} is interpreted as the zero
vector (0,@dots{},0).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_set_mode}
@deftypefn {} {int} unur_distr_cvec_set_mode (UNUR_DISTR* @var{distribution}, const @var{double* mode})
Set mode of the @var{distribution}. @var{mode} must be a pointer to an
array of the size returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
A @code{NULL} pointer for @var{mode} is interpreted as the zero
vector (0,@dots{},0).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_upd_mode}
@deftypefn Function {int} unur_distr_cvec_upd_mode (UNUR_DISTR* @var{distribution})
Recompute the mode of the @var{distribution}. This call works
properly for distribution objects from the UNU.RAN library of
standard distributions when the corresponding function is
available. If it failes @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_DATA}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_upd_mode}
@deftypefn {} {int} unur_distr_cvec_upd_mode (UNUR_DISTR* @var{distribution})
Recompute the mode of the @var{distribution}. This call works
properly for distribution objects from the UNU.RAN library of
standard distributions when the corresponding function is
available. If it failes @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_DATA}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_get_mode}
@deftypefn Function {const double*} unur_distr_cvec_get_mode (UNUR_DISTR* @var{distribution})
Get mode of the @var{distribution}. The function returns a pointer to
an array of the size returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
If the mode is not marked as known the @code{NULL} pointer is returned and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_GET}.
(There is no difference between the case where no routine for
computing the mode is available and the case where no mode exists
for the @var{distribution} at all.)

@emph{Important:} Do @strong{not} modify the array that holds the mode!
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_get_mode}
@deftypefn {} {const double*} unur_distr_cvec_get_mode (UNUR_DISTR* @var{distribution})
Get mode of the @var{distribution}. The function returns a pointer to
an array of the size returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
If the mode is not marked as known the @code{NULL} pointer is returned and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_GET}.
(There is no difference between the case where no routine for
computing the mode is available and the case where no mode exists
for the @var{distribution} at all.)

@emph{Important:} Do @strong{not} modify the array that holds the mode!
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_set_center}
@deftypefn Function {int} unur_distr_cvec_set_center (UNUR_DISTR* @var{distribution}, const @var{double* center})
Set center of the @var{distribution}. @var{center} must be a pointer to an
array of the size returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
A @code{NULL} pointer for @var{center} is interpreted as the zero
vector (0,@dots{},0).

The center is used by some methods to shift the distribution in
order to decrease numerical round-off error.
If not given explicitly a default is used.
Moreover, it is used as starting point for several numerical search
algorithm (e.g. for the mode). Then @var{center} must be a pointer
where the call to the PDF returns a non-zero value.
In particular @var{center} must contained in the domain of the distribution.

Default: The mode, if given by a
@ifhtml
@ref{funct:unur_distr_cvec_set_mode,@command{unur_distr_cvec_set_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_mode}
@end ifnothtml
call;
else the mean, if given by a
@ifhtml
@ref{funct:unur_distr_cvec_set_mean,@command{unur_distr_cvec_set_mean}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_mean}
@end ifnothtml
call;
otherwise the null vector (0,@dots{},0).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_set_center}
@deftypefn {} {int} unur_distr_cvec_set_center (UNUR_DISTR* @var{distribution}, const @var{double* center})
Set center of the @var{distribution}. @var{center} must be a pointer to an
array of the size returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
A @code{NULL} pointer for @var{center} is interpreted as the zero
vector (0,@dots{},0).

The center is used by some methods to shift the distribution in
order to decrease numerical round-off error.
If not given explicitly a default is used.
Moreover, it is used as starting point for several numerical search
algorithm (e.g. for the mode). Then @var{center} must be a pointer
where the call to the PDF returns a non-zero value.
In particular @var{center} must contained in the domain of the distribution.

Default: The mode, if given by a
@ifhtml
@ref{funct:unur_distr_cvec_set_mode,@command{unur_distr_cvec_set_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_mode}
@end ifnothtml
call;
else the mean, if given by a
@ifhtml
@ref{funct:unur_distr_cvec_set_mean,@command{unur_distr_cvec_set_mean}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_mean}
@end ifnothtml
call;
otherwise the null vector (0,@dots{},0).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_get_center}
@deftypefn Function {const double*} unur_distr_cvec_get_center (UNUR_DISTR* @var{distribution})
Get center of the @var{distribution}. The function returns a pointer to
an array of the size returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
It always returns some point as there always exists a default for
the center, see
@ifhtml
@ref{funct:unur_distr_cvec_set_center,@command{unur_distr_cvec_set_center}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_center}.
@end ifnothtml
@emph{Important:} Do @strong{not} modify the array that holds the center!
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_get_center}
@deftypefn {} {const double*} unur_distr_cvec_get_center (UNUR_DISTR* @var{distribution})
Get center of the @var{distribution}. The function returns a pointer to
an array of the size returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
It always returns some point as there always exists a default for
the center, see
@ifhtml
@ref{funct:unur_distr_cvec_set_center,@command{unur_distr_cvec_set_center}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_center}.
@end ifnothtml
@emph{Important:} Do @strong{not} modify the array that holds the center!
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_set_pdfvol}
@deftypefn Function {int} unur_distr_cvec_set_pdfvol (UNUR_DISTR* @var{distribution}, double @var{volume})
Set the volume below the PDF. If @var{vol} is non-positive, no
volume is set and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_SET}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_set_pdfvol}
@deftypefn {} {int} unur_distr_cvec_set_pdfvol (UNUR_DISTR* @var{distribution}, double @var{volume})
Set the volume below the PDF. If @var{vol} is non-positive, no
volume is set and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_SET}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_upd_pdfvol}
@deftypefn Function {int} unur_distr_cvec_upd_pdfvol (UNUR_DISTR* @var{distribution})
Recompute the volume below the PDF of the distribution.
It only works for distribution objects from the
UNU.RAN library of standard distributions when the
corresponding function is available. Otherwise @code{unur_errno} is
set to @code{UNUR_ERR_DISTR_DATA}.

This call also sets the normalization constant such that the given
PDF is the derivative of a given CDF, i.e. the volume is 1.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_upd_pdfvol}
@deftypefn {} {int} unur_distr_cvec_upd_pdfvol (UNUR_DISTR* @var{distribution})
Recompute the volume below the PDF of the distribution.
It only works for distribution objects from the
UNU.RAN library of standard distributions when the
corresponding function is available. Otherwise @code{unur_errno} is
set to @code{UNUR_ERR_DISTR_DATA}.

This call also sets the normalization constant such that the given
PDF is the derivative of a given CDF, i.e. the volume is 1.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvec_get_pdfvol}
@deftypefn Function {double} unur_distr_cvec_get_pdfvol (UNUR_DISTR* @var{distribution})
Get the volume below the PDF of the @var{distribution}. If this volume is
not known,@*
@ifhtml
@ref{funct:unur_distr_cont_upd_pdfarea,@command{unur_distr_cont_upd_pdfarea}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_pdfarea}
@end ifnothtml
is called to compute
it. If this is not successful @code{UNUR_INFINITY} is returned and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_GET}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvec_get_pdfvol}
@deftypefn {} {double} unur_distr_cvec_get_pdfvol (UNUR_DISTR* @var{distribution})
Get the volume below the PDF of the @var{distribution}. If this volume is
not known,@*
@ifhtml
@ref{funct:unur_distr_cont_upd_pdfarea,@command{unur_distr_cont_upd_pdfarea}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_pdfarea}
@end ifnothtml
is called to compute
it. If this is not successful @code{UNUR_INFINITY} is returned and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_GET}.
@end deftypefn
@end ifnotinfo




@c
@c end of cvec.h
@c -------------------------------------
@c -------------------------------------
@c condi.h
@c

@page
@node CONDI
@section   Continuous univariate full conditional distribution


Full conditional distribution for a given continuous
multivariate distributiion. The condition is a position vector
and either a variable that is variated or a vector that
indicates the direction on which the random vector can variate.

There is a subtle difference between using direction
vector and using the @var{k}-th variable.
When a direction vector is given the PDF of the conditional
distribution is defined by
@iftex
@math{f(t) = PDF(pos + t\cdot dir).}
@end iftex
@ifhtml
@html
<I>f</I>(<I>t</I>) = <I>PDF</I>(<I>pos</I> + <I>t</I> * <I>dir</I>).
@end html
@end ifhtml
@ifinfo
@math{f(t) = PDF(pos + t * dir).}
@end ifinfo
When a variable is selected the full conditional distribution
with all other variables fixed is used.

This is a special case of a continuous univariate distribution
and thus they have most of these parameters (with the exception
that functions cannot be changed). Additionally,

@itemize @minus
@item there is a call to extract the underlying multivariate
distribution,

@item and a call to handle the variables that are fixed and the
direction for changing the random vector.

@end itemize

This distibution type is primarily used for evaluation the
conditional distribution and its derivative (as required for,
e.g., the Gibbs sampler). The density is not normalized (i.e. does
not integrate to one). Mode and area are not available and it
does not make sense to use any call to set or change parameters
except the ones given below.


@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_distr_condi_new,unur_distr_condi_new}
@item @ref{funct:unur_distr_condi_set_condition,unur_distr_condi_set_condition}
@item @ref{funct:unur_distr_condi_get_condition,unur_distr_condi_get_condition}
@item @ref{funct:unur_distr_condi_get_distribution,unur_distr_condi_get_distribution}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_distr_condi_new}
@deftypefn Function {UNUR_DISTR*} unur_distr_condi_new (const @var{UNUR_DISTR* distribution}, const @var{double* pos}, const @var{double* dir}, int @var{k})
Create an object for full conditional distribution for the given
@var{distribution}. The condition is given by a position vector
@var{pos} and either the @var{k}-th variable that is variated or
the vector @var{dir} that contains the direction on which the
random vector can variate.

@var{distribution} must be a pointer to a multivariate continuous
distribution.
@var{pos} must be a pointer to an array of size @code{dim}, where
@code{dim} is the dimension of the underlying distribution object.
@var{dir} must be a pointer to an array if size @code{dim} or @code{NULL}.
@var{k} must be in the range @code{0, @dots{}, dim-1}.
If the @var{k}-th variable is used, @var{dir} must be set to @code{NULL}.

@emph{Notice:} There is a subtle difference between using direction
vector @var{dir} and using the @var{k}-th variable.
When @var{dir} is given, the current position @var{pos} is mapped into
0 of the conditional distribution and the derivative is taken from
the function PDF(@var{pos}+t*@var{dir}) w.r.t. @i{t}.
On the other hand, when the coordinate @var{k} is used (i.e., when
@var{dir} is set to @code{NULL}), the full conditional distribution of the
distribution is considered (as used for the Gibbs sampler).
In particular, the current point is just projected into the
one-dimensional subspace without mapping it into the point 0.

@emph{Notice:} If a coordinate @var{k} is used, then the @var{k}-th
partial derivative is used if it as available. Otherwise the
gradient is computed and the @var{k}-th component is returned.

The resulting generator object is of the same type as of a
@ifhtml
@ref{funct:unur_distr_cont_new,@command{unur_distr_cont_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_new}
@end ifnothtml
call.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_condi_new}
@deftypefn {} {UNUR_DISTR*} unur_distr_condi_new (const @var{UNUR_DISTR* distribution}, const @var{double* pos}, const @var{double* dir}, int @var{k})
Create an object for full conditional distribution for the given
@var{distribution}. The condition is given by a position vector
@var{pos} and either the @var{k}-th variable that is variated or
the vector @var{dir} that contains the direction on which the
random vector can variate.

@var{distribution} must be a pointer to a multivariate continuous
distribution.
@var{pos} must be a pointer to an array of size @code{dim}, where
@code{dim} is the dimension of the underlying distribution object.
@var{dir} must be a pointer to an array if size @code{dim} or @code{NULL}.
@var{k} must be in the range @code{0, @dots{}, dim-1}.
If the @var{k}-th variable is used, @var{dir} must be set to @code{NULL}.

@emph{Notice:} There is a subtle difference between using direction
vector @var{dir} and using the @var{k}-th variable.
When @var{dir} is given, the current position @var{pos} is mapped into
0 of the conditional distribution and the derivative is taken from
the function PDF(@var{pos}+t*@var{dir}) w.r.t. @i{t}.
On the other hand, when the coordinate @var{k} is used (i.e., when
@var{dir} is set to @code{NULL}), the full conditional distribution of the
distribution is considered (as used for the Gibbs sampler).
In particular, the current point is just projected into the
one-dimensional subspace without mapping it into the point 0.

@emph{Notice:} If a coordinate @var{k} is used, then the @var{k}-th
partial derivative is used if it as available. Otherwise the
gradient is computed and the @var{k}-th component is returned.

The resulting generator object is of the same type as of a
@ifhtml
@ref{funct:unur_distr_cont_new,@command{unur_distr_cont_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_new}
@end ifnothtml
call.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_condi_set_condition}
@deftypefn Function {int} unur_distr_condi_set_condition (struct @var{unur_distr* distribution}, const @var{double* pos}, const @var{double* dir}, int @var{k})
Set/change condition for conditional @var{distribution}.
Change values of fixed variables to @var{pos} and use direction
@var{dir} or @var{k}-th variable of conditional @var{distribution}.

@var{pos} must be a pointer to an array of size @code{dim}, where
@code{dim} is the dimension of the underlying distribution object.
@var{dir} must be a pointer to an array if size @code{dim} or @code{NULL}.
@var{k} must be in the range @code{0, @dots{}, dim-1}.
If the @var{k}-th variable is used, @var{dir} must be set to @code{NULL}.

@emph{Notice:} There is a subtle difference between using direction
vector @var{dir} and using the @var{k}-th variable.
When @var{dir} is given, the current position @var{pos} is mapped into
0 of the conditional distribution and the derivative is taken from
the function PDF(@var{pos}+t*@var{dir}) w.r.t. @i{t}.
On the other hand, when the coordinate @var{k} is used (i.e., when
@var{dir} is set to @code{NULL}), the full conditional distribution of the
distribution is considered (as used for the Gibbs sampler).
In particular, the current point is just projected into the
one-dimensional subspace without mapping it into the point 0.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_condi_set_condition}
@deftypefn {} {int} unur_distr_condi_set_condition (struct @var{unur_distr* distribution}, const @var{double* pos}, const @var{double* dir}, int @var{k})
Set/change condition for conditional @var{distribution}.
Change values of fixed variables to @var{pos} and use direction
@var{dir} or @var{k}-th variable of conditional @var{distribution}.

@var{pos} must be a pointer to an array of size @code{dim}, where
@code{dim} is the dimension of the underlying distribution object.
@var{dir} must be a pointer to an array if size @code{dim} or @code{NULL}.
@var{k} must be in the range @code{0, @dots{}, dim-1}.
If the @var{k}-th variable is used, @var{dir} must be set to @code{NULL}.

@emph{Notice:} There is a subtle difference between using direction
vector @var{dir} and using the @var{k}-th variable.
When @var{dir} is given, the current position @var{pos} is mapped into
0 of the conditional distribution and the derivative is taken from
the function PDF(@var{pos}+t*@var{dir}) w.r.t. @i{t}.
On the other hand, when the coordinate @var{k} is used (i.e., when
@var{dir} is set to @code{NULL}), the full conditional distribution of the
distribution is considered (as used for the Gibbs sampler).
In particular, the current point is just projected into the
one-dimensional subspace without mapping it into the point 0.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_condi_get_condition}
@deftypefn Function {int} unur_distr_condi_get_condition (struct @var{unur_distr* distribution}, const @var{double** pos}, const @var{double** dir}, int* @var{k})
Get condition for conditional @var{distribution}.
The values for the fixed variables are stored in @var{pos}, which
must be a pointer to an array of size @code{dim}.
The condition is stored in @var{dir} and @var{k}, respectively.

@emph{Important:} Do @strong{not} change the entries in @var{pos}
and @var{dir}!
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_condi_get_condition}
@deftypefn {} {int} unur_distr_condi_get_condition (struct @var{unur_distr* distribution}, const @var{double** pos}, const @var{double** dir}, int* @var{k})
Get condition for conditional @var{distribution}.
The values for the fixed variables are stored in @var{pos}, which
must be a pointer to an array of size @code{dim}.
The condition is stored in @var{dir} and @var{k}, respectively.

@emph{Important:} Do @strong{not} change the entries in @var{pos}
and @var{dir}!
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_condi_get_distribution}
@deftypefn Function {const UNUR_DISTR*} unur_distr_condi_get_distribution (const @var{UNUR_DISTR* distribution})
Get pointer to distribution object for underlying distribution.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_condi_get_distribution}
@deftypefn {} {const UNUR_DISTR*} unur_distr_condi_get_distribution (const @var{UNUR_DISTR* distribution})
Get pointer to distribution object for underlying distribution.
@end deftypefn
@end ifnotinfo




@c
@c end of condi.h
@c -------------------------------------
@c -------------------------------------
@c cvemp.h
@c

@page
@node CVEMP
@section   Continuous empirical multivariate distributions


Empirical multivariate distributions are just lists of vectors
(with the same dimension).
Thus there are only calls to insert these data.
How these data are used to sample from the empirical distribution
depends from the chosen generation method.


@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_distr_cvemp_new,unur_distr_cvemp_new}
@item @ref{funct:unur_distr_cvemp_set_data,unur_distr_cvemp_set_data}
@item @ref{funct:unur_distr_cvemp_read_data,unur_distr_cvemp_read_data}
@item @ref{funct:unur_distr_cvemp_get_data,unur_distr_cvemp_get_data}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_distr_cvemp_new}
@deftypefn Function {UNUR_DISTR*} unur_distr_cvemp_new (int @var{dim})
Create a new (empty) object for an empirical multivariate
continuous distribution. @var{dim} is the number of components of
the random vector (i.e. its dimension). It must be at least 2;
otherwise
@ifhtml
@ref{funct:unur_distr_cemp_new,@command{unur_distr_cemp_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cemp_new}
@end ifnothtml
should be used to create an object
for an empirical univariate distribution.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvemp_new}
@deftypefn {} {UNUR_DISTR*} unur_distr_cvemp_new (int @var{dim})
Create a new (empty) object for an empirical multivariate
continuous distribution. @var{dim} is the number of components of
the random vector (i.e. its dimension). It must be at least 2;
otherwise
@ifhtml
@ref{funct:unur_distr_cemp_new,@command{unur_distr_cemp_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cemp_new}
@end ifnothtml
should be used to create an object
for an empirical univariate distribution.
@end deftypefn
@end ifnotinfo

@subsubheading Essential parameters

@ifinfo
@anchor{funct:unur_distr_cvemp_set_data}
@deftypefn Function {int} unur_distr_cvemp_set_data (UNUR_DISTR* @var{distribution}, const @var{double* sample}, int @var{n_sample})
Set observed sample for empirical @var{distribution}.
@var{sample} is an array of doubles of size
@code{dim} x @var{n_sample}, where
@code{dim} is the dimension of the @var{distribution} returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
The data points must be stored consecutively in @var{sample}, i.e.,
data points (x1, y1), (x2, y2), @dots{} are given as an array
@{x1, y1, x2, y2, @dots{}@}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvemp_set_data}
@deftypefn {} {int} unur_distr_cvemp_set_data (UNUR_DISTR* @var{distribution}, const @var{double* sample}, int @var{n_sample})
Set observed sample for empirical @var{distribution}.
@var{sample} is an array of doubles of size
@code{dim} x @var{n_sample}, where
@code{dim} is the dimension of the @var{distribution} returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
The data points must be stored consecutively in @var{sample}, i.e.,
data points (x1, y1), (x2, y2), @dots{} are given as an array
@{x1, y1, x2, y2, @dots{}@}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvemp_read_data}
@deftypefn Function {int} unur_distr_cvemp_read_data (UNUR_DISTR* @var{distribution}, const @var{char* filename})
Read data from file @file{filename}.
It reads the first @code{dim} numbers from each line, where
@code{dim} is the dimension of the @var{distribution} returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
Numbers are parsed by means of the C standard routine @command{strtod}.
Lines that do not start with @code{+}, @code{-}, @code{.}, or a
digit are ignored. (Beware of lines starting with a blank!)

In case of an error (file cannot be opened, too few entries in a
line, invalid string for double in line) no data are copied into
the distribution object and an error code is returned.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvemp_read_data}
@deftypefn {} {int} unur_distr_cvemp_read_data (UNUR_DISTR* @var{distribution}, const @var{char* filename})
Read data from file @file{filename}.
It reads the first @code{dim} numbers from each line, where
@code{dim} is the dimension of the @var{distribution} returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}.}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}.
@end ifnothtml
Numbers are parsed by means of the C standard routine @command{strtod}.
Lines that do not start with @code{+}, @code{-}, @code{.}, or a
digit are ignored. (Beware of lines starting with a blank!)

In case of an error (file cannot be opened, too few entries in a
line, invalid string for double in line) no data are copied into
the distribution object and an error code is returned.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_cvemp_get_data}
@deftypefn Function {int} unur_distr_cvemp_get_data (const @var{UNUR_DISTR* distribution}, const @var{double** sample})
Get number of samples and set pointer @var{sample} to array of
observations. If no sample has been given, an error code
is returned and @var{sample} is set to @code{NULL}.
If successful @var{sample} points to an array of length
@code{dim} x @code{n_sample}, where
@code{dim} is the dimension of the distribution returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}
@end ifnothtml
and @code{n_sample} the return value of the
function.

@emph{Important:} Do @strong{not} modify the array @var{sample}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_cvemp_get_data}
@deftypefn {} {int} unur_distr_cvemp_get_data (const @var{UNUR_DISTR* distribution}, const @var{double** sample})
Get number of samples and set pointer @var{sample} to array of
observations. If no sample has been given, an error code
is returned and @var{sample} is set to @code{NULL}.
If successful @var{sample} points to an array of length
@code{dim} x @code{n_sample}, where
@code{dim} is the dimension of the distribution returned by
@ifhtml
@ref{funct:unur_distr_get_dim,@command{unur_distr_get_dim}}
@end ifhtml
@ifnothtml
@command{unur_distr_get_dim}
@end ifnothtml
and @code{n_sample} the return value of the
function.

@emph{Important:} Do @strong{not} modify the array @var{sample}.
@end deftypefn
@end ifnotinfo




@c
@c end of cvemp.h
@c -------------------------------------
@c -------------------------------------
@c matr.h
@c

@page
@node MATR
@section   MATRix distributions


Distributions for random matrices. Notice that UNU.RAN uses
arrays of @code{double}s to handle matrices. The rows of
the matrix are stored consecutively.


@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_distr_matr_new,unur_distr_matr_new}
@item @ref{funct:unur_distr_matr_get_dim,unur_distr_matr_get_dim}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_distr_matr_new}
@deftypefn Function {UNUR_DISTR*} unur_distr_matr_new (int @var{n_rows}, int @var{n_cols})
Create a new (empty) object for a matrix distribution. @var{n_rows}
and @var{n_cols} are the respective numbers of rows and columns of
the random matrix (i.e. its dimensions). It is also possible to
have only one number or rows and/or columns.
Notice, however, that this is treated as a distribution of random
matrices with only one row or column or component and not as a
distribution of vectors or real numbers. For the latter
@ifhtml
@ref{funct:unur_distr_cont_new,@command{unur_distr_cont_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_new}
@end ifnothtml
or
@ifhtml
@ref{funct:unur_distr_cvec_new,@command{unur_distr_cvec_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_new}
@end ifnothtml
should be
used to create an object for a univariate distribution and a
multivariate (vector) distribution, respectively.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_matr_new}
@deftypefn {} {UNUR_DISTR*} unur_distr_matr_new (int @var{n_rows}, int @var{n_cols})
Create a new (empty) object for a matrix distribution. @var{n_rows}
and @var{n_cols} are the respective numbers of rows and columns of
the random matrix (i.e. its dimensions). It is also possible to
have only one number or rows and/or columns.
Notice, however, that this is treated as a distribution of random
matrices with only one row or column or component and not as a
distribution of vectors or real numbers. For the latter
@ifhtml
@ref{funct:unur_distr_cont_new,@command{unur_distr_cont_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_new}
@end ifnothtml
or
@ifhtml
@ref{funct:unur_distr_cvec_new,@command{unur_distr_cvec_new}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_new}
@end ifnothtml
should be
used to create an object for a univariate distribution and a
multivariate (vector) distribution, respectively.
@end deftypefn
@end ifnotinfo

@subsubheading Essential parameters

@ifinfo
@anchor{funct:unur_distr_matr_get_dim}
@deftypefn Function {int} unur_distr_matr_get_dim (const @var{UNUR_DISTR* distribution}, int* @var{n_rows}, int* @var{n_cols})
Get number of rows and columns of random matrix (its dimension).
It returns the total number of components. If successfull
@code{UNUR_SUCCESS} is returned.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_matr_get_dim}
@deftypefn {} {int} unur_distr_matr_get_dim (const @var{UNUR_DISTR* distribution}, int* @var{n_rows}, int* @var{n_cols})
Get number of rows and columns of random matrix (its dimension).
It returns the total number of components. If successfull
@code{UNUR_SUCCESS} is returned.
@end deftypefn
@end ifnotinfo




@c
@c end of matr.h
@c -------------------------------------
@c -------------------------------------
@c discr.h
@c

@page
@node DISCR
@section   Discrete univariate distributions


The calls in this section can be applied to discrete
univariate distributions.

@itemize @minus
@item Create a @command{new} instance of a discrete univariate
distribution.

@item Handle and evaluate
distribution function (CDF, @command{cdf}) and
probability mass function (PMF, @command{pmf}).
The following is important:
@itemize .
@item @command{pmf} need not be normalized, i.e.,
any summable nonnegative function on the set of intergers can be
used.
@item @command{cdf} must be a distribution function, i.e. it
must be monotonically increasing with range [0,1].
@item If @command{cdf} and @command{pdf} are used together for a
pariticular generation method, then @command{pmf} must be
normalized, i.e. it must sum to 1.
@end itemize

@item Alternatively, @command{cdf} and @command{pdf} can be
provided as @command{str}ings instead of function pointers.

@item Some generation methods require a (finite) probability
vector (PV, @command{pv}), i.e. an array of @code{double}s.
It can be automatically computed if the @command{pmf} is
given but @command{pv} is not.

@item Set (and change) parameters (@command{pmfparams}) and the
total sum (@command{pmfsum}) of the given PMF or PV.

@item Set the @command{mode} of the distribution.

@item Set the @command{domain} of the distribution.

@end itemize


@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_distr_discr_new,unur_distr_discr_new}
@item @ref{funct:unur_distr_discr_set_pv,unur_distr_discr_set_pv}
@item @ref{funct:unur_distr_discr_make_pv,unur_distr_discr_make_pv}
@item @ref{funct:unur_distr_discr_get_pv,unur_distr_discr_get_pv}
@item @ref{funct:unur_distr_discr_set_pmf,unur_distr_discr_set_pmf}
@item @ref{funct:unur_distr_discr_set_cdf,unur_distr_discr_set_cdf}
@item @ref{funct:unur_distr_discr_set_invcdf,unur_distr_discr_set_invcdf}
@item @ref{funct:unur_distr_discr_eval_pv,unur_distr_discr_eval_pv}
@item @ref{funct:unur_distr_discr_eval_pmf,unur_distr_discr_eval_pmf}
@item @ref{funct:unur_distr_discr_eval_cdf,unur_distr_discr_eval_cdf}
@item @ref{funct:unur_distr_discr_eval_invcdf,unur_distr_discr_eval_invcdf}
@item @ref{funct:unur_distr_discr_set_pmfstr,unur_distr_discr_set_pmfstr}
@item @ref{funct:unur_distr_discr_set_cdfstr,unur_distr_discr_set_cdfstr}
@item @ref{funct:unur_distr_discr_get_pmfstr,unur_distr_discr_get_pmfstr}
@item @ref{funct:unur_distr_discr_get_cdfstr,unur_distr_discr_get_cdfstr}
@item @ref{funct:unur_distr_discr_set_pmfparams,unur_distr_discr_set_pmfparams}
@item @ref{funct:unur_distr_discr_get_pmfparams,unur_distr_discr_get_pmfparams}
@item @ref{funct:unur_distr_discr_set_domain,unur_distr_discr_set_domain}
@item @ref{funct:unur_distr_discr_get_domain,unur_distr_discr_get_domain}
@item @ref{funct:unur_distr_discr_set_mode,unur_distr_discr_set_mode}
@item @ref{funct:unur_distr_discr_upd_mode,unur_distr_discr_upd_mode}
@item @ref{funct:unur_distr_discr_get_mode,unur_distr_discr_get_mode}
@item @ref{funct:unur_distr_discr_set_pmfsum,unur_distr_discr_set_pmfsum}
@item @ref{funct:unur_distr_discr_upd_pmfsum,unur_distr_discr_upd_pmfsum}
@item @ref{funct:unur_distr_discr_get_pmfsum,unur_distr_discr_get_pmfsum}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_distr_discr_new}
@deftypefn Function {UNUR_DISTR*} unur_distr_discr_new (void)
Create a new (empty) object for a univariate discrete distribution.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_new}
@deftypefn {} {UNUR_DISTR*} unur_distr_discr_new (void)
Create a new (empty) object for a univariate discrete distribution.
@end deftypefn
@end ifnotinfo

@subsubheading Essential parameters

There are two interfaces for discrete univariate distributions:
Either provide a (finite) probability vector (PV).
Or provide a probability mass function (PMF). For the latter
case there are also a couple of derived parameters that are not
required when a PV is given.

It is not possible to set both a PMF and a PV directly. However, the
PV can be computed from the PMF (or the CDF if no PMF is available)
by means of a
@ifhtml
@ref{funct:unur_distr_discr_make_pv,@command{unur_distr_discr_make_pv}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_make_pv}
@end ifnothtml
call.
If both the PV and the PMF are given in the distribution object it
depends on the generation method which of these is used.

@ifinfo
@anchor{funct:unur_distr_discr_set_pv}
@deftypefn Function {int} unur_distr_discr_set_pv (UNUR_DISTR* @var{distribution}, const @var{double* pv}, int @var{n_pv})
Set finite probability vector (PV) for the @var{distribution}. It is not
necessary that the entries in the given PV sum to 1.
@var{n_pv} must be positive. However, there is no testing
whether all entries in @var{pv} are non-negative.

If no domain has been set, then the left boundary is set to
@code{0}, by default. If @var{n_pv} is too large, e.g. because
left boundary + @var{n_pv} exceeds the range of integers,
then the call fails.

Notice that it is not possible to set both a PV and a PMF or CDF.
If the PMF or CDF is set first one cannot set the PV.
If the PMF or CDF is set first after a PV is set, the latter is
removed (and recomputed using
@ifhtml
@ref{funct:unur_distr_discr_make_pv,@command{unur_distr_discr_make_pv}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_make_pv}
@end ifnothtml
when required).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_set_pv}
@deftypefn {} {int} unur_distr_discr_set_pv (UNUR_DISTR* @var{distribution}, const @var{double* pv}, int @var{n_pv})
Set finite probability vector (PV) for the @var{distribution}. It is not
necessary that the entries in the given PV sum to 1.
@var{n_pv} must be positive. However, there is no testing
whether all entries in @var{pv} are non-negative.

If no domain has been set, then the left boundary is set to
@code{0}, by default. If @var{n_pv} is too large, e.g. because
left boundary + @var{n_pv} exceeds the range of integers,
then the call fails.

Notice that it is not possible to set both a PV and a PMF or CDF.
If the PMF or CDF is set first one cannot set the PV.
If the PMF or CDF is set first after a PV is set, the latter is
removed (and recomputed using
@ifhtml
@ref{funct:unur_distr_discr_make_pv,@command{unur_distr_discr_make_pv}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_make_pv}
@end ifnothtml
when required).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_discr_make_pv}
@deftypefn Function {int} unur_distr_discr_make_pv (UNUR_DISTR* @var{distribution})
Compute a PV when a PMF or CDF is given. However, when the
domain is not given or is too large and the sum over the PMF is given
then the (right) tail of the @var{distribution} is chopped off such that
the probability for the tail region is less than 1.e-8.
If the sum over the PMF is not given a PV of maximal length is
computed.

The maximal size of the created PV is bounded by the macro
@code{UNUR_MAX_AUTO_PV} that is defined in @file{unuran_config.h}.

If successful, the length of the generated PV is returned.
If the sum over the PMF on the chopped tail is not neglible small
(i.e. greater than 1.e-8 or unknown) than the
negative of the length of the PV is returned and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_SET}.

Notice that the left boundary of the PV is set to @code{0} by
default when a discrete distribution object is created from
scratch.

If computing a PV fails for some reasons, an error code is returned and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_SET}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_make_pv}
@deftypefn {} {int} unur_distr_discr_make_pv (UNUR_DISTR* @var{distribution})
Compute a PV when a PMF or CDF is given. However, when the
domain is not given or is too large and the sum over the PMF is given
then the (right) tail of the @var{distribution} is chopped off such that
the probability for the tail region is less than 1.e-8.
If the sum over the PMF is not given a PV of maximal length is
computed.

The maximal size of the created PV is bounded by the macro
@code{UNUR_MAX_AUTO_PV} that is defined in @file{unuran_config.h}.

If successful, the length of the generated PV is returned.
If the sum over the PMF on the chopped tail is not neglible small
(i.e. greater than 1.e-8 or unknown) than the
negative of the length of the PV is returned and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_SET}.

Notice that the left boundary of the PV is set to @code{0} by
default when a discrete distribution object is created from
scratch.

If computing a PV fails for some reasons, an error code is returned and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_SET}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_discr_get_pv}
@deftypefn Function {int} unur_distr_discr_get_pv (const @var{UNUR_DISTR* distribution}, const @var{double** pv})
Get length of PV of the @var{distribution} and set pointer
@var{pv} to array of probabilities. If no PV is given,
an error code is returned and @var{pv} is set to @code{NULL}.@*
(It does not call
@ifhtml
@ref{funct:unur_distr_discr_make_pv,@command{unur_distr_discr_make_pv}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_make_pv}
@end ifnothtml
!)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_get_pv}
@deftypefn {} {int} unur_distr_discr_get_pv (const @var{UNUR_DISTR* distribution}, const @var{double** pv})
Get length of PV of the @var{distribution} and set pointer
@var{pv} to array of probabilities. If no PV is given,
an error code is returned and @var{pv} is set to @code{NULL}.@*
(It does not call
@ifhtml
@ref{funct:unur_distr_discr_make_pv,@command{unur_distr_discr_make_pv}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_make_pv}
@end ifnothtml
!)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_discr_set_pmf}
@anchor{funct:unur_distr_discr_set_cdf}
@deftypefn Function {int} unur_distr_discr_set_pmf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_DISCR* @var{pmf})
@deftypefnx Function {int} unur_distr_discr_set_cdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_DISCR* @var{cdf})
Set respective pointer to the PMF and the CDF of the @var{distribution}.
These functions must be of type
@code{double funct(int k, const UNUR_DISTR *distr)}.

It is important to note that all these functions must return a
result for all integers @var{k}. E.g., if the domain of a given
PMF is the interval @{1,2,3,@dots{},100@}, than the given function
must return @code{0.0} for all points outside this interval.

The default domain for the PMF or CDF is [@code{0}, @code{INT_MAX}].
The domain can be changed using a
@ifhtml
@ref{funct:unur_distr_discr_set_domain,@command{unur_distr_discr_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_set_domain}
@end ifnothtml
call.

It is not possible to change such a function. Once the PMF or
CDF is set it cannot be overwritten. A new distribution object
has to be used instead.

Notice that it is not possible to set both a PV and a PMF or CDF.
If the PMF or CDF is set first one cannot set the PV.
If the PMF or CDF is set first after a PV is set, the latter is
removed (and recomputed using
@ifhtml
@ref{funct:unur_distr_discr_make_pv,@command{unur_distr_discr_make_pv}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_make_pv}
@end ifnothtml
when required).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_set_pmf}
@anchor{funct:unur_distr_discr_set_cdf}
@deftypefn {} {int} unur_distr_discr_set_pmf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_DISCR* @var{pmf})
@deftypefnx {} {int} unur_distr_discr_set_cdf (UNUR_DISTR* @var{distribution}, UNUR_FUNCT_DISCR* @var{cdf})
Set respective pointer to the PMF and the CDF of the @var{distribution}.
These functions must be of type
@code{double funct(int k, const UNUR_DISTR *distr)}.

It is important to note that all these functions must return a
result for all integers @var{k}. E.g., if the domain of a given
PMF is the interval @{1,2,3,@dots{},100@}, than the given function
must return @code{0.0} for all points outside this interval.

The default domain for the PMF or CDF is [@code{0}, @code{INT_MAX}].
The domain can be changed using a
@ifhtml
@ref{funct:unur_distr_discr_set_domain,@command{unur_distr_discr_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_set_domain}
@end ifnothtml
call.

It is not possible to change such a function. Once the PMF or
CDF is set it cannot be overwritten. A new distribution object
has to be used instead.

Notice that it is not possible to set both a PV and a PMF or CDF.
If the PMF or CDF is set first one cannot set the PV.
If the PMF or CDF is set first after a PV is set, the latter is
removed (and recomputed using
@ifhtml
@ref{funct:unur_distr_discr_make_pv,@command{unur_distr_discr_make_pv}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_make_pv}
@end ifnothtml
when required).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_discr_set_invcdf}
@deftypefn Function {int} unur_distr_discr_set_invcdf (UNUR_DISTR* @var{distribution}, UNUR_IFUNCT_DISCR* @var{invcdf})
Set inverse CDF of the @var{distribution}.
@var{invcdf} must be a pointer must be of type
@code{int funct(double x, const UNUR_DISTR *distr)},
i.e., it should return a @code{double}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_set_invcdf}
@deftypefn {} {int} unur_distr_discr_set_invcdf (UNUR_DISTR* @var{distribution}, UNUR_IFUNCT_DISCR* @var{invcdf})
Set inverse CDF of the @var{distribution}.
@var{invcdf} must be a pointer must be of type
@code{int funct(double x, const UNUR_DISTR *distr)},
i.e., it should return a @code{double}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_discr_eval_pv}
@anchor{funct:unur_distr_discr_eval_pmf}
@anchor{funct:unur_distr_discr_eval_cdf}
@deftypefn Function {double} unur_distr_discr_eval_pv (int @var{k}, const @var{UNUR_DISTR* distribution})
@deftypefnx Function {double} unur_distr_discr_eval_pmf (int @var{k}, const @var{UNUR_DISTR* distribution})
@deftypefnx Function {double} unur_distr_discr_eval_cdf (int @var{k}, const @var{UNUR_DISTR* distribution})
Evaluate the PV, PMF, and the CDF, respectively, at k.
Notice that @var{distribution} must not be the @code{NULL} pointer.
If no PV is set for the @var{distribution}, then
@ifhtml
@ref{funct:unur_distr_discr_eval_pv,@command{unur_distr_discr_eval_pv}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_eval_pv}
@end ifnothtml
behaves like
@ifhtml
@ref{funct:unur_distr_discr_eval_pmf,@command{unur_distr_discr_eval_pmf}.}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_eval_pmf}.
@end ifnothtml
If the corresponding function is not available for the @var{distribution},
@code{UNUR_INFINITY} is returned and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_DATA}.

@emph{IMPORTANT:}
In the case of a truncated standard distribution these calls always
return the respective values of the @emph{untruncated} distribution!
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_eval_pv}
@anchor{funct:unur_distr_discr_eval_pmf}
@anchor{funct:unur_distr_discr_eval_cdf}
@deftypefn {} {double} unur_distr_discr_eval_pv (int @var{k}, const @var{UNUR_DISTR* distribution})
@deftypefnx {} {double} unur_distr_discr_eval_pmf (int @var{k}, const @var{UNUR_DISTR* distribution})
@deftypefnx {} {double} unur_distr_discr_eval_cdf (int @var{k}, const @var{UNUR_DISTR* distribution})
Evaluate the PV, PMF, and the CDF, respectively, at k.
Notice that @var{distribution} must not be the @code{NULL} pointer.
If no PV is set for the @var{distribution}, then
@ifhtml
@ref{funct:unur_distr_discr_eval_pv,@command{unur_distr_discr_eval_pv}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_eval_pv}
@end ifnothtml
behaves like
@ifhtml
@ref{funct:unur_distr_discr_eval_pmf,@command{unur_distr_discr_eval_pmf}.}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_eval_pmf}.
@end ifnothtml
If the corresponding function is not available for the @var{distribution},
@code{UNUR_INFINITY} is returned and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_DATA}.

@emph{IMPORTANT:}
In the case of a truncated standard distribution these calls always
return the respective values of the @emph{untruncated} distribution!
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_discr_eval_invcdf}
@deftypefn Function {int} unur_distr_discr_eval_invcdf (double @var{u}, const @var{UNUR_DISTR* distribution})
Evaluate the inverse CDF at @var{u}.
Notice that @var{distribution} must not be the @code{NULL} pointer.
If the corresponding function is not available for the distribution,
@code{INT_MAX} is returned and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_DATA}.

@emph{IMPORTANT:}
In the case of a truncated standard distribution these calls always
return the respective values of the @emph{untruncated} distribution!
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_eval_invcdf}
@deftypefn {} {int} unur_distr_discr_eval_invcdf (double @var{u}, const @var{UNUR_DISTR* distribution})
Evaluate the inverse CDF at @var{u}.
Notice that @var{distribution} must not be the @code{NULL} pointer.
If the corresponding function is not available for the distribution,
@code{INT_MAX} is returned and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_DATA}.

@emph{IMPORTANT:}
In the case of a truncated standard distribution these calls always
return the respective values of the @emph{untruncated} distribution!
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_discr_set_pmfstr}
@deftypefn Function {int} unur_distr_discr_set_pmfstr (UNUR_DISTR* @var{distribution}, const @var{char* pmfstr})
This function provides an alternative way to set a PMF of the
@var{distribution}.
@var{pmfstr} is a character string that contains the formula
for the PMF, see @ref{StringFunct,,Function String}, for details.
See also the remarks for the
@ifhtml
@ref{funct:unur_distr_discr_set_pmf,@command{unur_distr_discr_set_pmf}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_set_pmf}
@end ifnothtml
call.

It is not possible to call this funtion twice or to call this
function after a
@ifhtml
@ref{funct:unur_distr_discr_set_pmf,@command{unur_distr_discr_set_pmf}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_set_pmf}
@end ifnothtml
call.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_set_pmfstr}
@deftypefn {} {int} unur_distr_discr_set_pmfstr (UNUR_DISTR* @var{distribution}, const @var{char* pmfstr})
This function provides an alternative way to set a PMF of the
@var{distribution}.
@var{pmfstr} is a character string that contains the formula
for the PMF, see @ref{StringFunct,,Function String}, for details.
See also the remarks for the
@ifhtml
@ref{funct:unur_distr_discr_set_pmf,@command{unur_distr_discr_set_pmf}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_set_pmf}
@end ifnothtml
call.

It is not possible to call this funtion twice or to call this
function after a
@ifhtml
@ref{funct:unur_distr_discr_set_pmf,@command{unur_distr_discr_set_pmf}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_set_pmf}
@end ifnothtml
call.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_discr_set_cdfstr}
@deftypefn Function {int} unur_distr_discr_set_cdfstr (UNUR_DISTR* @var{distribution}, const @var{char* cdfstr})
This function provides an alternative way to set a CDF; analogously
to the
@ifhtml
@ref{funct:unur_distr_discr_set_pmfstr,@command{unur_distr_discr_set_pmfstr}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_set_pmfstr}
@end ifnothtml
call.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_set_cdfstr}
@deftypefn {} {int} unur_distr_discr_set_cdfstr (UNUR_DISTR* @var{distribution}, const @var{char* cdfstr})
This function provides an alternative way to set a CDF; analogously
to the
@ifhtml
@ref{funct:unur_distr_discr_set_pmfstr,@command{unur_distr_discr_set_pmfstr}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_set_pmfstr}
@end ifnothtml
call.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_discr_get_pmfstr}
@anchor{funct:unur_distr_discr_get_cdfstr}
@deftypefn Function {char*} unur_distr_discr_get_pmfstr (const @var{UNUR_DISTR* distribution})
@deftypefnx Function {char*} unur_distr_discr_get_cdfstr (const @var{UNUR_DISTR* distribution})
Get pointer to respective string for PMF and CDF
of @var{distribution} that is given via the string interface.
This call allocates memory to produce this string. It should be
freed when it is not used any more.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_get_pmfstr}
@anchor{funct:unur_distr_discr_get_cdfstr}
@deftypefn {} {char*} unur_distr_discr_get_pmfstr (const @var{UNUR_DISTR* distribution})
@deftypefnx {} {char*} unur_distr_discr_get_cdfstr (const @var{UNUR_DISTR* distribution})
Get pointer to respective string for PMF and CDF
of @var{distribution} that is given via the string interface.
This call allocates memory to produce this string. It should be
freed when it is not used any more.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_discr_set_pmfparams}
@deftypefn Function {int} unur_distr_discr_set_pmfparams (UNUR_DISTR* @var{distribution}, const @var{double* params}, int @var{n_params})
Set array of parameters for @var{distribution}. There is an upper limit
for the number of parameters @var{n_params}. It is given by the
macro @code{UNUR_DISTR_MAXPARAMS} in @file{unuran_config.h}. (It is set to
5 but can be changed to any appropriate nonnegative number.)
If @var{n_params} is negative or exceeds this limit no parameters
are copied into the @var{distribution} object and @code{unur_errno}
is set to @code{UNUR_ERR_DISTR_NPARAMS}.

For standard distributions from the UNU.RAN library the parameters
are checked. Moreover, the domain is updated automatically unless it
has been changed before by a
@ifhtml
@ref{funct:unur_distr_discr_set_domain,@command{unur_distr_discr_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_set_domain}
@end ifnothtml
call.
If the given parameters are invalid for the standard distribution,
then no parameters are set and an error code is returned.
Notice that the given parameter list for such a distribution is
handled in the same way as in the corresponding @command{new}
calls, i.e. optional parameters for the PDF that are not present in
the given list are (re-)set to their default values.

@emph{Important:} Integer parameter must be given as @code{double}s.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_set_pmfparams}
@deftypefn {} {int} unur_distr_discr_set_pmfparams (UNUR_DISTR* @var{distribution}, const @var{double* params}, int @var{n_params})
Set array of parameters for @var{distribution}. There is an upper limit
for the number of parameters @var{n_params}. It is given by the
macro @code{UNUR_DISTR_MAXPARAMS} in @file{unuran_config.h}. (It is set to
5 but can be changed to any appropriate nonnegative number.)
If @var{n_params} is negative or exceeds this limit no parameters
are copied into the @var{distribution} object and @code{unur_errno}
is set to @code{UNUR_ERR_DISTR_NPARAMS}.

For standard distributions from the UNU.RAN library the parameters
are checked. Moreover, the domain is updated automatically unless it
has been changed before by a
@ifhtml
@ref{funct:unur_distr_discr_set_domain,@command{unur_distr_discr_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_set_domain}
@end ifnothtml
call.
If the given parameters are invalid for the standard distribution,
then no parameters are set and an error code is returned.
Notice that the given parameter list for such a distribution is
handled in the same way as in the corresponding @command{new}
calls, i.e. optional parameters for the PDF that are not present in
the given list are (re-)set to their default values.

@emph{Important:} Integer parameter must be given as @code{double}s.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_discr_get_pmfparams}
@deftypefn Function {int} unur_distr_discr_get_pmfparams (const @var{UNUR_DISTR* distribution}, const @var{double** params})
Get number of parameters of the PMF and set pointer
@var{params} to array of parameters. If no parameters are stored
in the object, an error code is returned and @code{params} is set to
@code{NULL}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_get_pmfparams}
@deftypefn {} {int} unur_distr_discr_get_pmfparams (const @var{UNUR_DISTR* distribution}, const @var{double** params})
Get number of parameters of the PMF and set pointer
@var{params} to array of parameters. If no parameters are stored
in the object, an error code is returned and @code{params} is set to
@code{NULL}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_discr_set_domain}
@deftypefn Function {int} unur_distr_discr_set_domain (UNUR_DISTR* @var{distribution}, int @var{left}, int @var{right})
Set the left and right borders of the domain of the
@var{distribution}. This can also be used to truncate an existing
distribution. For setting the boundary to
@math{+/- infinity}
use
@code{INT_MIN} and @code{INT_MAX}, respectively.
If @var{right} is not strictly greater than @var{left} no domain
is set and @code{unur_errno} is set to @code{UNUR_ERR_DISTR_SET}.
It is allowed to use this call to increase the domain.
If the PV of the discrete distribution is used,
than the right boudary is ignored (and internally set to
@var{left} + size of PV @math{- 1}).
Notice that @code{INT_MIN} and @code{INT_MAX} are interpreted as
(minus/plus) infinity.

Default: [@code{0}, @code{INT_MAX}].
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_set_domain}
@deftypefn {} {int} unur_distr_discr_set_domain (UNUR_DISTR* @var{distribution}, int @var{left}, int @var{right})
Set the left and right borders of the domain of the
@var{distribution}. This can also be used to truncate an existing
distribution. For setting the boundary to
@iftex
@math{\pm\infty}
@end iftex
@ifhtml
@html
+/- infinity
@end html
@end ifhtml
use
@code{INT_MIN} and @code{INT_MAX}, respectively.
If @var{right} is not strictly greater than @var{left} no domain
is set and @code{unur_errno} is set to @code{UNUR_ERR_DISTR_SET}.
It is allowed to use this call to increase the domain.
If the PV of the discrete distribution is used,
than the right boudary is ignored (and internally set to
@var{left} + size of PV @math{- 1}).
Notice that @code{INT_MIN} and @code{INT_MAX} are interpreted as
(minus/plus) infinity.

Default: [@code{0}, @code{INT_MAX}].
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_discr_get_domain}
@deftypefn Function {int} unur_distr_discr_get_domain (const @var{UNUR_DISTR* distribution}, int* @var{left}, int* @var{right})
Get the left and right borders of the domain of the
@var{distribution}. If the domain is not set explicitly
the interval [@code{INT_MIN}, @code{INT_MAX}] is assumed and returned.
When a PV is given then the domain is set automatically to
[@code{0},size of PV @math{- 1}].
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_get_domain}
@deftypefn {} {int} unur_distr_discr_get_domain (const @var{UNUR_DISTR* distribution}, int* @var{left}, int* @var{right})
Get the left and right borders of the domain of the
@var{distribution}. If the domain is not set explicitly
the interval [@code{INT_MIN}, @code{INT_MAX}] is assumed and returned.
When a PV is given then the domain is set automatically to
[@code{0},size of PV @math{- 1}].
@end deftypefn
@end ifnotinfo

@subsubheading Derived parameters

The following paramters @strong{must} be set whenever one of the essential
parameters has been set or changed (and the parameter is required
for the chosen method).

@ifinfo
@anchor{funct:unur_distr_discr_set_mode}
@deftypefn Function {int} unur_distr_discr_set_mode (UNUR_DISTR* @var{distribution}, int @var{mode})
Set mode of @var{distribution}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_set_mode}
@deftypefn {} {int} unur_distr_discr_set_mode (UNUR_DISTR* @var{distribution}, int @var{mode})
Set mode of @var{distribution}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_discr_upd_mode}
@deftypefn Function {int} unur_distr_discr_upd_mode (UNUR_DISTR* @var{distribution})
Recompute the mode of the @var{distribution}. This call works properly
for distribution objects from the
UNU.RAN library of standard distributions
when the corresponding function is available.
Otherwise a (slow) numerical mode finder is used. It only works properly
for unimodal probability mass functions. If it failes
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_DATA}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_upd_mode}
@deftypefn {} {int} unur_distr_discr_upd_mode (UNUR_DISTR* @var{distribution})
Recompute the mode of the @var{distribution}. This call works properly
for distribution objects from the
UNU.RAN library of standard distributions
when the corresponding function is available.
Otherwise a (slow) numerical mode finder is used. It only works properly
for unimodal probability mass functions. If it failes
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_DATA}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_discr_get_mode}
@deftypefn Function {int} unur_distr_discr_get_mode (UNUR_DISTR* @var{distribution})
Get mode of @var{distribution}. If the mode is not marked as known,
@ifhtml
@ref{funct:unur_distr_discr_upd_mode,@command{unur_distr_discr_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_upd_mode}
@end ifnothtml
is called to compute the mode. If this
is not successful @code{INT_MAX} is returned and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_GET}.
(There is no difference between the case where no routine for
computing the mode is available and the case where no mode exists
for the distribution at all.)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_get_mode}
@deftypefn {} {int} unur_distr_discr_get_mode (UNUR_DISTR* @var{distribution})
Get mode of @var{distribution}. If the mode is not marked as known,
@ifhtml
@ref{funct:unur_distr_discr_upd_mode,@command{unur_distr_discr_upd_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_upd_mode}
@end ifnothtml
is called to compute the mode. If this
is not successful @code{INT_MAX} is returned and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_GET}.
(There is no difference between the case where no routine for
computing the mode is available and the case where no mode exists
for the distribution at all.)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_discr_set_pmfsum}
@deftypefn Function {int} unur_distr_discr_set_pmfsum (UNUR_DISTR* @var{distribution}, double @var{sum})
Set the sum over the PMF. If @code{sum} is non-positive, no
sum is set and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_SET}.

For a distribution object created by the
UNU.RAN library of standard distributions you always should use
the
@ifhtml
@ref{funct:unur_distr_discr_upd_pmfsum,@command{unur_distr_discr_upd_pmfsum}.}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_upd_pmfsum}.
@end ifnothtml
Otherwise there might be
ambiguous side-effects.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_set_pmfsum}
@deftypefn {} {int} unur_distr_discr_set_pmfsum (UNUR_DISTR* @var{distribution}, double @var{sum})
Set the sum over the PMF. If @code{sum} is non-positive, no
sum is set and @code{unur_errno} is set to
@code{UNUR_ERR_DISTR_SET}.

For a distribution object created by the
UNU.RAN library of standard distributions you always should use
the
@ifhtml
@ref{funct:unur_distr_discr_upd_pmfsum,@command{unur_distr_discr_upd_pmfsum}.}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_upd_pmfsum}.
@end ifnothtml
Otherwise there might be
ambiguous side-effects.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_discr_upd_pmfsum}
@deftypefn Function {int} unur_distr_discr_upd_pmfsum (UNUR_DISTR* @var{distribution})
Recompute the sum over the PMF of the @var{distribution}.
In most cases the normalization constant is recomputed and thus the
sum is 1. This call works for distribution objects from the UNU.RAN
library of standard distributions when the corresponding function
is available. When a PV, a PMF with finite domain, or a CDF is
given, a simple generic function which uses a naive summation loop
is used. If this computation is not possible, an error code is
returned and @code{unur_errno} is set to @code{UNUR_ERR_DISTR_DATA}.

The call does not work for distributions from the
UNU.RAN library of standard distributions with truncated
domain when the CDF is not available.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_upd_pmfsum}
@deftypefn {} {int} unur_distr_discr_upd_pmfsum (UNUR_DISTR* @var{distribution})
Recompute the sum over the PMF of the @var{distribution}.
In most cases the normalization constant is recomputed and thus the
sum is 1. This call works for distribution objects from the UNU.RAN
library of standard distributions when the corresponding function
is available. When a PV, a PMF with finite domain, or a CDF is
given, a simple generic function which uses a naive summation loop
is used. If this computation is not possible, an error code is
returned and @code{unur_errno} is set to @code{UNUR_ERR_DISTR_DATA}.

The call does not work for distributions from the
UNU.RAN library of standard distributions with truncated
domain when the CDF is not available.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_distr_discr_get_pmfsum}
@deftypefn Function {double} unur_distr_discr_get_pmfsum (UNUR_DISTR* @var{distribution})
Get the sum over the PMF of the @var{distribution}. If this sum is
not known,
@ifhtml
@ref{funct:unur_distr_discr_upd_pmfsum,@command{unur_distr_discr_upd_pmfsum}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_upd_pmfsum}
@end ifnothtml
is called to compute
it. If this is not successful @code{UNUR_INFINITY} is returned and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_GET}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_distr_discr_get_pmfsum}
@deftypefn {} {double} unur_distr_discr_get_pmfsum (UNUR_DISTR* @var{distribution})
Get the sum over the PMF of the @var{distribution}. If this sum is
not known,
@ifhtml
@ref{funct:unur_distr_discr_upd_pmfsum,@command{unur_distr_discr_upd_pmfsum}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_upd_pmfsum}
@end ifnothtml
is called to compute
it. If this is not successful @code{UNUR_INFINITY} is returned and
@code{unur_errno} is set to @code{UNUR_ERR_DISTR_GET}.
@end deftypefn
@end ifnotinfo




@c
@c end of discr.h
@c -------------------------------------
@c -------------------------------------
@c methods.dh
@c

@node Methods
@chapter   Methods for generating non-uniform random variates

@menu
* Methods_all:: Routines for all generator objects
* AUTO:: Select method automatically
* Methods_for_CONT:: Methods for continuous univariate distributions
* Methods_for_CEMP:: Methods for continuous empirical univariate distributions
* Methods_for_CVEC:: Methods for continuous multivariate distributions
* MCMC_Methods_for_CVEC:: Markov chain samplers for continuous multivariate distributions
* Methods_for_CVEMP:: Methods for continuous empirical multivariate distributions
* Methods_for_DISCR:: Methods for discrete univariate distributions
* Methods_for_MATR:: Methods for random matrices
* Methods_for_UNID:: Methods for uniform univariate distributions
* Meta_Methods:: Meta Methods for univariate distributions
@end menu



Sampling from a particular distribution with UNU.RAN requires the
following steps:

@enumerate
@item
Create a distribution object
(@pxref{Distribution_objects,,Handling distribution objects}).

@item
Select a method and create a parameter object.

@item
Initizialize the generator object using
@ifhtml
@ref{funct:unur_init,@command{unur_init}.}
@end ifhtml
@ifnothtml
@command{unur_init}.
@end ifnothtml
@emph{Important}: Initialization of the generator object might fail.
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
returns a @code{NULL} pointer then, which @strong{must} not be
used for sampling.

@item
Draw a sample from the generator object using the
corresponding sampling function (depending on the type of
distribution:
univariate continuous, univariate discrete, multivariate
continuous, and random matrix).

@item
It is possible for a generator object to change the parameters and the
domain of the underlying distribution. This must be done by extracting
this object by means of a
@ifhtml
@ref{funct:unur_get_distr,@command{unur_get_distr}}
@end ifhtml
@ifnothtml
@command{unur_get_distr}
@end ifnothtml
call and
changing the distribution using the correspondig set calls,
see @ref{Distribution_objects,,Handling distribution objects}.
The generator object @strong{must} then be reinitialized by means of
the
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
call.

@emph{Important}: Currently not all methods allow reinitialization,
see the description of the particular method (keyword @i{Reinit}).

@emph{Important}: Reinitialization of the generator object might fail.
Thus one @strong{must} check the return code of the
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
call.

@emph{Important}: When reinitialization fails then sampling routines
always return @code{UNUR_INFINITY} (for continuous distributions) or @code{0} (for
discrete distributions), respectively.
However, it is still possible to change the underlying distribution
and try to reinitialize again.

@end enumerate



@c
@c end of methods.dh
@c -------------------------------------
@c -------------------------------------
@c x_gen.h
@c

@node Methods_all
@section   Routines for all generator objects


Routines for all generator objects.


@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_init,unur_init}
@item @ref{funct:unur_reinit,unur_reinit}
@item @ref{funct:unur_sample_discr,unur_sample_discr}
@item @ref{funct:unur_sample_cont,unur_sample_cont}
@item @ref{funct:unur_sample_vec,unur_sample_vec}
@item @ref{funct:unur_sample_matr,unur_sample_matr}
@item @ref{funct:unur_quantile,unur_quantile}
@item @ref{funct:unur_free,unur_free}
@item @ref{funct:unur_gen_info,unur_gen_info}
@item @ref{funct:unur_get_dimension,unur_get_dimension}
@item @ref{funct:unur_get_genid,unur_get_genid}
@item @ref{funct:unur_get_method,unur_get_method}
@item @ref{funct:unur_gen_is_inversion,unur_gen_is_inversion}
@item @ref{funct:unur_get_distr,unur_get_distr}
@item @ref{funct:unur_set_use_distr_privatecopy,unur_set_use_distr_privatecopy}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_init}
@deftypefn Function {UNUR_GEN*} unur_init (UNUR_PAR* @var{parameters})
Initialize a generator object. All necessary information must be
stored in the parameter object.

@strong{Important:} If an error has occurred a @code{NULL} pointer is
return. This must not be used for the sampling routines (this causes a
segmentation fault).

@strong{Always} check whether the call was successful or not!

@emph{Important:} This call destroys the @var{parameter} object
automatically. Thus it is not necessary/allowed to free it.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_init}
@deftypefn {} {UNUR_GEN*} unur_init (UNUR_PAR* @var{parameters})
Initialize a generator object. All necessary information must be
stored in the parameter object.

@strong{Important:} If an error has occurred a @code{NULL} pointer is
return. This must not be used for the sampling routines (this causes a
segmentation fault).

@strong{Always} check whether the call was successful or not!

@emph{Important:} This call destroys the @var{parameter} object
automatically. Thus it is not necessary/allowed to free it.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_reinit}
@deftypefn Function {int} unur_reinit (UNUR_GEN* @var{generator})
Update an existing generator object after the underlying
distribution has been modified (using
@ifhtml
@ref{funct:unur_get_distr,@command{unur_get_distr}}
@end ifhtml
@ifnothtml
@command{unur_get_distr}
@end ifnothtml
together
with corresponding set calls.
It @strong{must} be executed before sampling using this generator
object is continued as otherwise it produces an invalid sample or
might even cause a segmentation fault.

@emph{Important}: Currently not all methods allow reinitialization,
see the description of the particular method (keyword @i{Reinit}).

@emph{Important}: Reinitialization of the generator object might fail.
Thus one @strong{must} check the return code:

@table @asis
@item @code{UNUR_SUCCESS (0x0u)}
success (no error)
@item @code{UNUR_ERR_NO_REINIT}
reinit routine not implemented.
@item other values
some error has occured while trying to reinitialize the generator
object.
@end table

@emph{Important}: When reinitialization fails then sampling routines
always return @code{UNUR_INFINITY} (for continuous distributions)
or @code{0} (for discrete distributions), respectively.
However, it is still possible to change the underlying distribution
and try to reinitialize again.

@emph{Important}: When one tries to run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit},}
@end ifhtml
@ifnothtml
@command{unur_reinit},
@end ifnothtml
but reinitialization
is not implemented, then the generator object cannot be used any more
and must be destroyed and a new one has to be built from scratch.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_reinit}
@deftypefn {} {int} unur_reinit (UNUR_GEN* @var{generator})
Update an existing generator object after the underlying
distribution has been modified (using
@ifhtml
@ref{funct:unur_get_distr,@command{unur_get_distr}}
@end ifhtml
@ifnothtml
@command{unur_get_distr}
@end ifnothtml
together
with corresponding set calls.
It @strong{must} be executed before sampling using this generator
object is continued as otherwise it produces an invalid sample or
might even cause a segmentation fault.

@emph{Important}: Currently not all methods allow reinitialization,
see the description of the particular method (keyword @i{Reinit}).

@emph{Important}: Reinitialization of the generator object might fail.
Thus one @strong{must} check the return code:

@table @asis
@item @code{UNUR_SUCCESS (0x0u)}
success (no error)
@item @code{UNUR_ERR_NO_REINIT}
reinit routine not implemented.
@item other values
some error has occured while trying to reinitialize the generator
object.
@end table

@emph{Important}: When reinitialization fails then sampling routines
always return @code{UNUR_INFINITY} (for continuous distributions)
or @code{0} (for discrete distributions), respectively.
However, it is still possible to change the underlying distribution
and try to reinitialize again.

@emph{Important}: When one tries to run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit},}
@end ifhtml
@ifnothtml
@command{unur_reinit},
@end ifnothtml
but reinitialization
is not implemented, then the generator object cannot be used any more
and must be destroyed and a new one has to be built from scratch.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_sample_discr}
@anchor{funct:unur_sample_cont}
@anchor{funct:unur_sample_vec}
@anchor{funct:unur_sample_matr}
@deftypefn Function {int   } unur_sample_discr (UNUR_GEN* @var{generator})
@deftypefnx Function {double} unur_sample_cont (UNUR_GEN* @var{generator})
@deftypefnx Function {int   } unur_sample_vec (UNUR_GEN* @var{generator}, double* @var{vector})
@deftypefnx Function {int   } unur_sample_matr (UNUR_GEN* @var{generator}, double* @var{matrix})
Sample from generator object. The three routines depend on the type
of the generator object (discrete or continuous univariate
distribution, multivariate distribution, or random matrix).

@emph{Notice:} UNU.RAN uses arrays of @code{double}s to handle
matrices. There the rows of the matrix are stored consecutively.

@emph{Notice:} The routines
@ifhtml
@ref{funct:unur_sample_vec,@command{unur_sample_vec}}
@end ifhtml
@ifnothtml
@command{unur_sample_vec}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_sample_matr,@command{unur_sample_matr}}
@end ifhtml
@ifnothtml
@command{unur_sample_matr}
@end ifnothtml
return @code{UNUR_SUCCESS} if generation was successful and
some error code otherwise.

@strong{Important:} These routines do @strong{not} check whether
@var{generator} is an invalid @code{NULL} pointer.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_sample_discr}
@anchor{funct:unur_sample_cont}
@anchor{funct:unur_sample_vec}
@anchor{funct:unur_sample_matr}
@deftypefn {} {int   } unur_sample_discr (UNUR_GEN* @var{generator})
@deftypefnx {} {double} unur_sample_cont (UNUR_GEN* @var{generator})
@deftypefnx {} {int   } unur_sample_vec (UNUR_GEN* @var{generator}, double* @var{vector})
@deftypefnx {} {int   } unur_sample_matr (UNUR_GEN* @var{generator}, double* @var{matrix})
Sample from generator object. The three routines depend on the type
of the generator object (discrete or continuous univariate
distribution, multivariate distribution, or random matrix).

@emph{Notice:} UNU.RAN uses arrays of @code{double}s to handle
matrices. There the rows of the matrix are stored consecutively.

@emph{Notice:} The routines
@ifhtml
@ref{funct:unur_sample_vec,@command{unur_sample_vec}}
@end ifhtml
@ifnothtml
@command{unur_sample_vec}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_sample_matr,@command{unur_sample_matr}}
@end ifhtml
@ifnothtml
@command{unur_sample_matr}
@end ifnothtml
return @code{UNUR_SUCCESS} if generation was successful and
some error code otherwise.

@strong{Important:} These routines do @strong{not} check whether
@var{generator} is an invalid @code{NULL} pointer.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_quantile}
@deftypefn Function {double} unur_quantile (UNUR_GEN* @var{generator}, double @var{U})
Compute the @var{U} quantile of a continuous distribution using a
@var{generator} object that implements an (approximate) inversion
methods.

The following methods are currently available:
@itemize
@item
HINV, @pxref{HINV}.
@item
NINV, @pxref{NINV}.
@item
PINV, @pxref{PINV}.
@item
CSTD, @pxref{CSTD}. @*
This requires that @var{generator} implements an inversion method.
@item
DGT, @pxref{DGT}. @*
The return value is (of course) type casted to @code{double}.
@end itemize

@strong{Important:} This routine does @strong{not} check whether
@var{generator} is an invalid @code{NULL} pointer.

In case of an error UNUR_INFINITY or INT_MAX
(depending on the type of @var{generator}) is returned.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_quantile}
@deftypefn {} {double} unur_quantile (UNUR_GEN* @var{generator}, double @var{U})
Compute the @var{U} quantile of a continuous distribution using a
@var{generator} object that implements an (approximate) inversion
methods.

The following methods are currently available:
@itemize
@item
HINV, @pxref{HINV}.
@item
NINV, @pxref{NINV}.
@item
PINV, @pxref{PINV}.
@item
CSTD, @pxref{CSTD}. @*
This requires that @var{generator} implements an inversion method.
@item
DGT, @pxref{DGT}. @*
The return value is (of course) type casted to @code{double}.
@end itemize

@strong{Important:} This routine does @strong{not} check whether
@var{generator} is an invalid @code{NULL} pointer.

In case of an error UNUR_INFINITY or INT_MAX
(depending on the type of @var{generator}) is returned.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_free}
@deftypefn Function {void } unur_free (UNUR_GEN* @var{generator})
Destroy (free) the given generator object.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_free}
@deftypefn {} {void } unur_free (UNUR_GEN* @var{generator})
Destroy (free) the given generator object.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_gen_info}
@deftypefn Function {const char*} unur_gen_info (UNUR_GEN* @var{generator}, int @var{help})
Get a string with informations about the given @var{generator}.
These informations allow some fine tuning of the generation method.
If @var{help} is @code{TRUE}, some hints on setting parameters are given.

This function is intented for using in interactive environments
(like @t{R}).

If an error occurs, then @code{NULL} is returned.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_gen_info}
@deftypefn {} {const char*} unur_gen_info (UNUR_GEN* @var{generator}, int @var{help})
Get a string with informations about the given @var{generator}.
These informations allow some fine tuning of the generation method.
If @var{help} is @code{TRUE}, some hints on setting parameters are given.

This function is intented for using in interactive environments
(like @t{R}).

If an error occurs, then @code{NULL} is returned.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_get_dimension}
@deftypefn Function {int} unur_get_dimension (const @var{UNUR_GEN* generator})
Get the number of dimension of a (multivariate) distribution.
For a univariate distribution @code{1} is return.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_get_dimension}
@deftypefn {} {int} unur_get_dimension (const @var{UNUR_GEN* generator})
Get the number of dimension of a (multivariate) distribution.
For a univariate distribution @code{1} is return.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_get_genid}
@deftypefn Function {const char*} unur_get_genid (const @var{UNUR_GEN* generator})
Get identifier string for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_get_genid}
@deftypefn {} {const char*} unur_get_genid (const @var{UNUR_GEN* generator})
Get identifier string for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_get_method}
@deftypefn Function {unsigned int} unur_get_method (const @var{UNUR_GEN* generator})
Get identifier for generating method.
These identifiers are declared in @file{src/methods/unur_metthods.h}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_get_method}
@deftypefn {} {unsigned int} unur_get_method (const @var{UNUR_GEN* generator})
Get identifier for generating method.
These identifiers are declared in @file{src/methods/unur_metthods.h}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_gen_is_inversion}
@deftypefn Function {int} unur_gen_is_inversion (const @var{UNUR_GEN* gen})
Return @code{TRUE} if the generator object implements an inversion method,
and @code{FALSE} otherwise.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_gen_is_inversion}
@deftypefn {} {int} unur_gen_is_inversion (const @var{UNUR_GEN* gen})
Return @code{TRUE} if the generator object implements an inversion method,
and @code{FALSE} otherwise.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_get_distr}
@deftypefn Function {UNUR_DISTR*} unur_get_distr (const @var{UNUR_GEN* generator})
Get pointer to distribution object from generator object.
This function can be used to change the parameters of the distribution
and reinitialize the generator object.
Notice that currently @strong{not all} generating methods have a
reinitialize routine.
This function should be used with extreme care. Changing the distribution
is changed and using the generator object without reinitializing
might cause wrong samples or segmentation faults.
Moreover, if the corresponding generator object is freed, the
pointer must not be used.

@strong{Important:} The returned distribution object must not
be freed. If the distribution object is changed then one @strong{must}
run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
!
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_get_distr}
@deftypefn {} {UNUR_DISTR*} unur_get_distr (const @var{UNUR_GEN* generator})
Get pointer to distribution object from generator object.
This function can be used to change the parameters of the distribution
and reinitialize the generator object.
Notice that currently @strong{not all} generating methods have a
reinitialize routine.
This function should be used with extreme care. Changing the distribution
is changed and using the generator object without reinitializing
might cause wrong samples or segmentation faults.
Moreover, if the corresponding generator object is freed, the
pointer must not be used.

@strong{Important:} The returned distribution object must not
be freed. If the distribution object is changed then one @strong{must}
run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
!
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_set_use_distr_privatecopy}
@deftypefn Function {int} unur_set_use_distr_privatecopy (UNUR_PAR* @var{parameters}, int @var{use_privatecopy})
Set flag whether the generator object should make a private copy of
the given distribution object or just stores the pointer to this
distribution object. Values for @var{use_privatecopy}:
@table @code
@item @code{TRUE}
make a private copy (default)
@item @code{FALSE}
do not make a private copy and store pointer to given (external)
distribution object.
@end table

By default, generator objects keep their own private copy of the
given distribution object. Thus the generator object can be handled
independently from other UNU.RAN objects (with uniform random number
generators as the only exception). When the generator object is
initialized the given distribution object is cloned and stored.

However, in some rare situations it can be useful when only the
pointer to the given distribution object is stored without making a
private copy. A possible example is when only one random variate has
to be drawn from the distribution.
This behavior can be achieved when @var{use_localcopy} is set to
@code{FALSE}.

@strong{Warning!}
Using a pointer to the external distribution object instead of a
private copy must be done with @strong{extreme care}!
When the distrubtion object is changed or freed then the generator
object does not work any more, might case a segmentation fault, or
(even worse) produces garbage.
On the other hand, when the generator object is initialized or used
to draw a random sampling the distribution object may be changed.

@emph{Notice:}
The prototypes of all @code{unur_<method>_new} calls use a
@code{const} qualifier for the distribution argument.
However, if @var{use_privatecopy} is set to @code{FALSE} this qualifier is
discarded and the distribution might be changed.

@strong{Important!}
If @var{use_localcopy} is set to @code{FALSE} and the corresponding
distribution object is changed then one must run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
on the generator object.
(Notice that currently not all generation methods support
reinitialization.)

Default: @var{use_privatecopy} is @code{TRUE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_set_use_distr_privatecopy}
@deftypefn {} {int} unur_set_use_distr_privatecopy (UNUR_PAR* @var{parameters}, int @var{use_privatecopy})
Set flag whether the generator object should make a private copy of
the given distribution object or just stores the pointer to this
distribution object. Values for @var{use_privatecopy}:
@table @code
@item @code{TRUE}
make a private copy (default)
@item @code{FALSE}
do not make a private copy and store pointer to given (external)
distribution object.
@end table

By default, generator objects keep their own private copy of the
given distribution object. Thus the generator object can be handled
independently from other UNU.RAN objects (with uniform random number
generators as the only exception). When the generator object is
initialized the given distribution object is cloned and stored.

However, in some rare situations it can be useful when only the
pointer to the given distribution object is stored without making a
private copy. A possible example is when only one random variate has
to be drawn from the distribution.
This behavior can be achieved when @var{use_localcopy} is set to
@code{FALSE}.

@strong{Warning!}
Using a pointer to the external distribution object instead of a
private copy must be done with @strong{extreme care}!
When the distrubtion object is changed or freed then the generator
object does not work any more, might case a segmentation fault, or
(even worse) produces garbage.
On the other hand, when the generator object is initialized or used
to draw a random sampling the distribution object may be changed.

@emph{Notice:}
The prototypes of all @code{unur_<method>_new} calls use a
@code{const} qualifier for the distribution argument.
However, if @var{use_privatecopy} is set to @code{FALSE} this qualifier is
discarded and the distribution might be changed.

@strong{Important!}
If @var{use_localcopy} is set to @code{FALSE} and the corresponding
distribution object is changed then one must run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
on the generator object.
(Notice that currently not all generation methods support
reinitialization.)

Default: @var{use_privatecopy} is @code{TRUE}.
@end deftypefn
@end ifnotinfo




@c
@c end of x_gen.h
@c -------------------------------------
@c -------------------------------------
@c auto.h
@c

@page
@node AUTO
@section   AUTO  --  Select method automatically


AUTO selects a an appropriate method for the given distribution
object automatically. There are no parameters for this method,
yet. But it is planned to give some parameter to describe the
task for which the random variate generator is used for and thus
make the choice of the generating method more appropriate.
Notice that the required sampling routine for the generator
object depends on the type of the given distribution object.

The chosen method also depends on the sample size for which the
generator object will be used. If only a few random variates
the order of magnitude of the sample size should be set via a
@ifhtml
@ref{funct:unur_auto_set_logss,@command{unur_auto_set_logss}}
@end ifhtml
@ifnothtml
@command{unur_auto_set_logss}
@end ifnothtml
call.

IMPORTANT: This is an experimental version and the method chosen
may change in future releases of UNU.RAN.

For an example see @ref{Example_0,As short as possible,Example: As short as possible}.


@subsubheading How To Use


Create a generator object for the given distribution object.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_auto_new,unur_auto_new}
@item @ref{funct:unur_auto_set_logss,unur_auto_set_logss}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_auto_new}
@deftypefn Function {UNUR_PAR*} unur_auto_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_auto_new}
@deftypefn {} {UNUR_PAR*} unur_auto_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_auto_set_logss}
@deftypefn Function {int} unur_auto_set_logss (UNUR_PAR* @var{parameters}, int @var{logss})
Set the order of magnitude for the size of the sample that will be
generated by the generator, i.e., the the common logarithm of the
sample size.

Default is 10.

Notice: This feature will be used in future releases of UNU.RAN only.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_auto_set_logss}
@deftypefn {} {int} unur_auto_set_logss (UNUR_PAR* @var{parameters}, int @var{logss})
Set the order of magnitude for the size of the sample that will be
generated by the generator, i.e., the the common logarithm of the
sample size.

Default is 10.

Notice: This feature will be used in future releases of UNU.RAN only.
@end deftypefn
@end ifnotinfo




@c
@c end of auto.h
@c -------------------------------------
@c -------------------------------------
@c methods.dh
@c

@page
@node Methods_for_CONT
@section   Methods for continuous univariate distributions

@menu
* AROU:: Automatic Ratio-Of-Uniforms method
* ARS:: Adaptive Rejection Sampling
* CEXT:: wrapper for Continuous EXTernal generators
* CSTD:: Continuous STandarD distributions
* HINV:: Hermite interpolation based INVersion of CDF
* HRB:: Hazard Rate Bounded
* HRD:: Hazard Rate Decreasing
* HRI:: Hazard Rate Increasing
* ITDR:: Inverse Transformed Density Rejection
* NINV:: Numerical INVersion
* NROU:: Naive Ratio-Of-Uniforms method
* PINV:: Polynomial interpolation based INVersion of CDF
* SROU:: Simple Ratio-Of-Uniforms method
* SSR:: Simple Setup Rejection
* TABL:: a TABLe method with piecewise constant hats
* TDR:: Transformed Density Rejection
* UTDR:: Universal Transformed Density Rejection
@end menu



@subheading Overview of methods

@include methods_cont.texi

@subheading Example

@smallexample
@include ref_example_cont.texi
@end smallexample

@subheading Example (String API)

@smallexample
@include ref_example_cont_str.texi
@end smallexample



@c
@c end of methods.dh
@c -------------------------------------
@c -------------------------------------
@c arou.h
@c

@page
@node AROU
@subsection   AROU  --  Automatic Ratio-Of-Uniforms method

@table @i
@item Required:
T-concave PDF, dPDF
@item Optional:
mode
@item Speed:
Set-up: slow, Sampling: fast
@item Reinit:
not implemented
@item Reference:
@ifhtml
@ref{bib:LJa00,, [LJa00]}
@end ifhtml
@ifnothtml
[LJa00]
@end ifnothtml

@end table


AROU is a variant of the ratio-of-uniforms method that uses the
fact that the transformed region is convex for many distributions.
It works for all T-concave distributions with T(x) = -1/sqrt(x).

It is possible to use this method for correlation induction by
setting an auxiliary uniform random number generator via the
@ifhtml
@ref{funct:unur_set_urng_aux,@command{unur_set_urng_aux}}
@end ifhtml
@ifnothtml
@command{unur_set_urng_aux}
@end ifnothtml
call. (Notice that this must be done after a
possible
@ifhtml
@ref{funct:unur_set_urng,@command{unur_set_urng}}
@end ifhtml
@ifnothtml
@command{unur_set_urng}
@end ifnothtml
call.)
When an auxiliary generator is used then the number of used
uniform random numbers that is used up for one generated random
variate is constant and equal to 1.

There exists a test mode that verifies whether the conditions for
the method are satisfied or not while sampling. It can be
switched on by calling
@ifhtml
@ref{funct:unur_arou_set_verify,@command{unur_arou_set_verify}}
@end ifhtml
@ifnothtml
@command{unur_arou_set_verify}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_arou_chg_verify,@command{unur_arou_chg_verify},}
@end ifhtml
@ifnothtml
@command{unur_arou_chg_verify},
@end ifnothtml
respectively.
Notice however that sampling is (much) slower then.

For densities with modes not close to 0 it is suggested to set
either the mode or the center of the distribution by the
@ifhtml
@ref{funct:unur_distr_cont_set_mode,@command{unur_distr_cont_set_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_mode}
@end ifnothtml
or
@ifhtml
@ref{funct:unur_distr_cont_set_center,@command{unur_distr_cont_set_center}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_center}
@end ifnothtml
call.
The latter is the approximate location of the mode or the mean
of the distribution. This location provides some information
about the main part of the PDF and is used to avoid numerical
problems.


@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_arou_new,unur_arou_new}
@item @ref{funct:unur_arou_set_usedars,unur_arou_set_usedars}
@item @ref{funct:unur_arou_set_darsfactor,unur_arou_set_darsfactor}
@item @ref{funct:unur_arou_set_max_sqhratio,unur_arou_set_max_sqhratio}
@item @ref{funct:unur_arou_get_sqhratio,unur_arou_get_sqhratio}
@item @ref{funct:unur_arou_get_hatarea,unur_arou_get_hatarea}
@item @ref{funct:unur_arou_get_squeezearea,unur_arou_get_squeezearea}
@item @ref{funct:unur_arou_set_max_segments,unur_arou_set_max_segments}
@item @ref{funct:unur_arou_set_cpoints,unur_arou_set_cpoints}
@item @ref{funct:unur_arou_set_usecenter,unur_arou_set_usecenter}
@item @ref{funct:unur_arou_set_guidefactor,unur_arou_set_guidefactor}
@item @ref{funct:unur_arou_set_verify,unur_arou_set_verify}
@item @ref{funct:unur_arou_chg_verify,unur_arou_chg_verify}
@item @ref{funct:unur_arou_set_pedantic,unur_arou_set_pedantic}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_arou_new}
@deftypefn Function {UNUR_PAR*} unur_arou_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_arou_new}
@deftypefn {} {UNUR_PAR*} unur_arou_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_arou_set_usedars}
@deftypefn Function {int} unur_arou_set_usedars (UNUR_PAR* @var{parameters}, int @var{usedars})
If @var{usedars} is set to @code{TRUE}, ``derandomized adaptive rejection
sampling'' (DARS) is used in setup.
Segments where the area between hat and squeeze is too
large compared to the average area between hat and squeeze
over all intervals are split.
This procedure is repeated until the ratio between area below squeeze
and area below hat exceeds the bound given by
@ifhtml
@ref{funct:unur_arou_set_max_sqhratio,@command{unur_arou_set_max_sqhratio}}
@end ifhtml
@ifnothtml
@command{unur_arou_set_max_sqhratio}
@end ifnothtml
call or the maximum number of segments is
reached. Moreover, it also aborts when no more segments can be
found for splitting.

Segments are split such that the angle of the segments are halved
(corresponds to arc-mean rule of method TDR (@pxref{TDR})).

Default is @code{TRUE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_arou_set_usedars}
@deftypefn {} {int} unur_arou_set_usedars (UNUR_PAR* @var{parameters}, int @var{usedars})
If @var{usedars} is set to @code{TRUE}, ``derandomized adaptive rejection
sampling'' (DARS) is used in setup.
Segments where the area between hat and squeeze is too
large compared to the average area between hat and squeeze
over all intervals are split.
This procedure is repeated until the ratio between area below squeeze
and area below hat exceeds the bound given by
@ifhtml
@ref{funct:unur_arou_set_max_sqhratio,@command{unur_arou_set_max_sqhratio}}
@end ifhtml
@ifnothtml
@command{unur_arou_set_max_sqhratio}
@end ifnothtml
call or the maximum number of segments is
reached. Moreover, it also aborts when no more segments can be
found for splitting.

Segments are split such that the angle of the segments are halved
(corresponds to arc-mean rule of method TDR (@pxref{TDR})).

Default is @code{TRUE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_arou_set_darsfactor}
@deftypefn Function {int} unur_arou_set_darsfactor (UNUR_PAR* @var{parameters}, double @var{factor})
Set factor for ``derandomized adaptive rejection sampling''.
This factor is used to determine the segments that are ``too
large'', that is, all segments where the area between squeeze and
hat is larger than @var{factor} times the average area over all
intervals between squeeze and hat.
Notice that all segments are split when @var{factor} is set to
@code{0.}, and that there is no splitting at all when @var{factor}
is set to @code{UNUR_INFINITY}.

Default is @code{0.99}. There is no need to change this parameter.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_arou_set_darsfactor}
@deftypefn {} {int} unur_arou_set_darsfactor (UNUR_PAR* @var{parameters}, double @var{factor})
Set factor for ``derandomized adaptive rejection sampling''.
This factor is used to determine the segments that are ``too
large'', that is, all segments where the area between squeeze and
hat is larger than @var{factor} times the average area over all
intervals between squeeze and hat.
Notice that all segments are split when @var{factor} is set to
@code{0.}, and that there is no splitting at all when @var{factor}
is set to @code{UNUR_INFINITY}.

Default is @code{0.99}. There is no need to change this parameter.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_arou_set_max_sqhratio}
@deftypefn Function {int} unur_arou_set_max_sqhratio (UNUR_PAR* @var{parameters}, double @var{max_ratio})
Set upper bound for the
ratio (area inside squeeze) / (area inside envelope).
It must be a number between 0 and 1.
When the ratio exceeds the given number no further construction
points are inserted via adaptive rejection sampling.
Use @code{0} if no construction points should be added after the
setup.
Use @code{1} if adding new construction points should not be
stopped until the maximum number of construction points is reached.

Default is @code{0.99}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_arou_set_max_sqhratio}
@deftypefn {} {int} unur_arou_set_max_sqhratio (UNUR_PAR* @var{parameters}, double @var{max_ratio})
Set upper bound for the
ratio (area inside squeeze) / (area inside envelope).
It must be a number between 0 and 1.
When the ratio exceeds the given number no further construction
points are inserted via adaptive rejection sampling.
Use @code{0} if no construction points should be added after the
setup.
Use @code{1} if adding new construction points should not be
stopped until the maximum number of construction points is reached.

Default is @code{0.99}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_arou_get_sqhratio}
@deftypefn Function {double} unur_arou_get_sqhratio (const @var{UNUR_GEN* generator})
Get the current ratio (area inside squeeze) / (area inside envelope)
for the generator.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_arou_get_sqhratio}
@deftypefn {} {double} unur_arou_get_sqhratio (const @var{UNUR_GEN* generator})
Get the current ratio (area inside squeeze) / (area inside envelope)
for the generator.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_arou_get_hatarea}
@deftypefn Function {double} unur_arou_get_hatarea (const @var{UNUR_GEN* generator})
Get the area below the hat for the generator.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_arou_get_hatarea}
@deftypefn {} {double} unur_arou_get_hatarea (const @var{UNUR_GEN* generator})
Get the area below the hat for the generator.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_arou_get_squeezearea}
@deftypefn Function {double} unur_arou_get_squeezearea (const @var{UNUR_GEN* generator})
Get the area below the squeeze for the generator.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_arou_get_squeezearea}
@deftypefn {} {double} unur_arou_get_squeezearea (const @var{UNUR_GEN* generator})
Get the area below the squeeze for the generator.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_arou_set_max_segments}
@deftypefn Function {int} unur_arou_set_max_segments (UNUR_PAR* @var{parameters}, int @var{max_segs})
Set maximum number of segements.
No construction points are added @emph{after} the setup when the
number of segments succeeds @var{max_segs}.

Default is @code{100}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_arou_set_max_segments}
@deftypefn {} {int} unur_arou_set_max_segments (UNUR_PAR* @var{parameters}, int @var{max_segs})
Set maximum number of segements.
No construction points are added @emph{after} the setup when the
number of segments succeeds @var{max_segs}.

Default is @code{100}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_arou_set_cpoints}
@deftypefn Function {int} unur_arou_set_cpoints (UNUR_PAR* @var{parameters}, int @var{n_stp}, const @var{double* stp})
Set construction points for enveloping polygon.
If @var{stp} is @code{NULL}, then a heuristical rule of thumb is used to
get @var{n_stp} construction points.
This is the default behavior when this routine is not called.
The (default) number of construction points is @code{30}, then.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_arou_set_cpoints}
@deftypefn {} {int} unur_arou_set_cpoints (UNUR_PAR* @var{parameters}, int @var{n_stp}, const @var{double* stp})
Set construction points for enveloping polygon.
If @var{stp} is @code{NULL}, then a heuristical rule of thumb is used to
get @var{n_stp} construction points.
This is the default behavior when this routine is not called.
The (default) number of construction points is @code{30}, then.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_arou_set_usecenter}
@deftypefn Function {int} unur_arou_set_usecenter (UNUR_PAR* @var{parameters}, int @var{usecenter})
Use the center as construction point.
Default is @code{TRUE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_arou_set_usecenter}
@deftypefn {} {int} unur_arou_set_usecenter (UNUR_PAR* @var{parameters}, int @var{usecenter})
Use the center as construction point.
Default is @code{TRUE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_arou_set_guidefactor}
@deftypefn Function {int} unur_arou_set_guidefactor (UNUR_PAR* @var{parameters}, double @var{factor})
Set factor for relative size of the guide table for indexed search
(see also method DGT @ref{DGT}). It must be greater than or equal
to @code{0}.
When set to @code{0}, then sequential search is used.

Default is @code{2}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_arou_set_guidefactor}
@deftypefn {} {int} unur_arou_set_guidefactor (UNUR_PAR* @var{parameters}, double @var{factor})
Set factor for relative size of the guide table for indexed search
(see also method DGT @ref{DGT}). It must be greater than or equal
to @code{0}.
When set to @code{0}, then sequential search is used.

Default is @code{2}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_arou_set_verify}
@anchor{funct:unur_arou_chg_verify}
@deftypefn Function {int} unur_arou_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx Function {int} unur_arou_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the condition squeeze(@i{x}) <= PDF(@i{x}) <= hat(@i{x}) is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_arou_set_verify}
@anchor{funct:unur_arou_chg_verify}
@deftypefn {} {int} unur_arou_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx {} {int} unur_arou_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the condition squeeze(@i{x}) <= PDF(@i{x}) <= hat(@i{x}) is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_arou_set_pedantic}
@deftypefn Function {int} unur_arou_set_pedantic (UNUR_PAR* @var{parameters}, int @var{pedantic})
Sometimes it might happen that
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
has been executed
successfully. But when additional construction points are added by
adaptive rejection sampling, the algorithm detects that the
PDF is not T-concave.

With @var{pedantic} being @code{TRUE}, the
sampling routine is then exchanged by a routine that simply returns
@code{UNUR_INFINITY}. Otherwise the new point is not added to the
list of construction points. At least the hat function remains
T-concave.

Setting @var{pedantic} to @code{FALSE} allows sampling from a
distribution which is ``almost'' T-concave and small errors are
tolerated. However it might happen that the hat function cannot be
improved significantly. When the hat function that has been
constructed by the
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
call is extremely large then it
might happen that the generation times are extremely high
(even hours are possible in extremely rare cases).

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_arou_set_pedantic}
@deftypefn {} {int} unur_arou_set_pedantic (UNUR_PAR* @var{parameters}, int @var{pedantic})
Sometimes it might happen that
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
has been executed
successfully. But when additional construction points are added by
adaptive rejection sampling, the algorithm detects that the
PDF is not T-concave.

With @var{pedantic} being @code{TRUE}, the
sampling routine is then exchanged by a routine that simply returns
@code{UNUR_INFINITY}. Otherwise the new point is not added to the
list of construction points. At least the hat function remains
T-concave.

Setting @var{pedantic} to @code{FALSE} allows sampling from a
distribution which is ``almost'' T-concave and small errors are
tolerated. However it might happen that the hat function cannot be
improved significantly. When the hat function that has been
constructed by the
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
call is extremely large then it
might happen that the generation times are extremely high
(even hours are possible in extremely rare cases).

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo




@c
@c end of arou.h
@c -------------------------------------
@c -------------------------------------
@c ars.h
@c

@page
@node ARS
@subsection   ARS  --  Adaptive Rejection Sampling

@table @i
@item Required:
concave logPDF, derivative of logPDF
@item Optional:
mode
@item Speed:
Set-up: fast, Sampling: slow
@item Reinit:
supported
@item Reference:
@ifhtml
@ref{bib:GWa92,, [GWa92]}
@end ifhtml
@ifnothtml
[GWa92]
@end ifnothtml
@ifhtml
@ref{bib:HLD04,, [HLD04: Cha.4]}
@end ifhtml
@ifnothtml
[HLD04: Cha.4]
@end ifnothtml

@end table


ARS is an acceptance/rejection method that uses the concavity
of the log-density function to construct hat function and
squeezes automatically.
It is very similar to method TDR (@pxref{TDR}) with variant GW,
parameter @code{c = 0}, and DARS switched off.
Moreover, method ARS requires the logPDF and its derivative
dlogPDF to run. On the other hand, it is designed to draw only a
(very) small samples and it is much more robust against
densities with very large or small areas below the PDF as
it occurs, for example, in conditional distributions of
(high dimensional) multivariate distributions.
Additionally, it can be re-initialized when the underlying
distribution has been modified.
Thus it is well suited for Gibbs sampling.

Notice, that method ARS is a restricted version of TDR. If the
full functionally of Transformed Density Rejection is needed use
method @ref{TDR}.


@subsubheading How To Use


Method ARS is designed for distributions with log-concave
densities. To use this method you need a distribution object
with the logarithm of the PDF and its derivative given.

The number of construction points as well as a set of such
points can be provided using
@ifhtml
@ref{funct:unur_ars_set_cpoints,@command{unur_ars_set_cpoints}.}
@end ifhtml
@ifnothtml
@command{unur_ars_set_cpoints}.
@end ifnothtml
Notice that addition construction points are added by means of
adaptive rejection sampling until the maximal number of
intervals given by
@ifhtml
@ref{funct:unur_ars_set_max_intervals,@command{unur_ars_set_max_intervals}}
@end ifhtml
@ifnothtml
@command{unur_ars_set_max_intervals}
@end ifnothtml
is reached.

A generated distribution object can be reinitialized using the
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
call. When
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
is called construction
points for the new generator are necessary. There are two options:
Either the same construction points as for the initial generator
(given by a
@ifhtml
@ref{funct:unur_ars_set_cpoints,@command{unur_ars_set_cpoints}}
@end ifhtml
@ifnothtml
@command{unur_ars_set_cpoints}
@end ifnothtml
call) are used (this is the
default), or percentiles of the old hat function can be used.
This can be set or changed using
@ifhtml
@ref{funct:unur_ars_set_reinit_percentiles,@command{unur_ars_set_reinit_percentiles}}
@end ifhtml
@ifnothtml
@command{unur_ars_set_reinit_percentiles}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_ars_chg_reinit_percentiles,@command{unur_ars_chg_reinit_percentiles}.}
@end ifhtml
@ifnothtml
@command{unur_ars_chg_reinit_percentiles}.
@end ifnothtml
This feature is usefull when the underlying distribution object
is only moderately changed. (An example is Gibbs sampling with
small correlations.)

There exists a test mode that verifies whether the conditions for
the method are satisfied or not. It can be switched on by calling
@ifhtml
@ref{funct:unur_ars_set_verify,@command{unur_ars_set_verify}}
@end ifhtml
@ifnothtml
@command{unur_ars_set_verify}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_ars_chg_verify,@command{unur_ars_chg_verify},}
@end ifhtml
@ifnothtml
@command{unur_ars_chg_verify},
@end ifnothtml
respectively.
Notice however that sampling is (much) slower then.

Method ARS aborts after a given number of iterations and return
UNUR_INFINITY to prevent (almost) infinite loops. This might
happen when the starting hat is much too large and it is not
possible to insert new construction points due to severe
numerical errors or (more likely) the given PDF is not
log-concave. This maximum number of iterations can be set by
means of a
@ifhtml
@ref{funct:unur_ars_set_max_iter,@command{unur_ars_set_max_iter}}
@end ifhtml
@ifnothtml
@command{unur_ars_set_max_iter}
@end ifnothtml
call.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_ars_new,unur_ars_new}
@item @ref{funct:unur_ars_set_max_intervals,unur_ars_set_max_intervals}
@item @ref{funct:unur_ars_set_cpoints,unur_ars_set_cpoints}
@item @ref{funct:unur_ars_set_reinit_percentiles,unur_ars_set_reinit_percentiles}
@item @ref{funct:unur_ars_chg_reinit_percentiles,unur_ars_chg_reinit_percentiles}
@item @ref{funct:unur_ars_set_reinit_ncpoints,unur_ars_set_reinit_ncpoints}
@item @ref{funct:unur_ars_chg_reinit_ncpoints,unur_ars_chg_reinit_ncpoints}
@item @ref{funct:unur_ars_set_max_iter,unur_ars_set_max_iter}
@item @ref{funct:unur_ars_set_verify,unur_ars_set_verify}
@item @ref{funct:unur_ars_chg_verify,unur_ars_chg_verify}
@item @ref{funct:unur_ars_set_pedantic,unur_ars_set_pedantic}
@item @ref{funct:unur_ars_get_loghatarea,unur_ars_get_loghatarea}
@item @ref{funct:unur_ars_eval_invcdfhat,unur_ars_eval_invcdfhat}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_ars_new}
@deftypefn Function {UNUR_PAR*} unur_ars_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ars_new}
@deftypefn {} {UNUR_PAR*} unur_ars_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ars_set_max_intervals}
@deftypefn Function {int} unur_ars_set_max_intervals (UNUR_PAR* @var{parameters}, int @var{max_ivs})
Set maximum number of intervals.
No construction points are added after the setup when the number of
intervals suceeds @var{max_ivs}.
It is increased automatically to twice the number of construction
points if this is larger.

Default is @code{200}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ars_set_max_intervals}
@deftypefn {} {int} unur_ars_set_max_intervals (UNUR_PAR* @var{parameters}, int @var{max_ivs})
Set maximum number of intervals.
No construction points are added after the setup when the number of
intervals suceeds @var{max_ivs}.
It is increased automatically to twice the number of construction
points if this is larger.

Default is @code{200}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ars_set_cpoints}
@deftypefn Function {int} unur_ars_set_cpoints (UNUR_PAR* @var{parameters}, int @var{n_cpoints}, const @var{double* cpoints})
Set construction points for the hat function. If @var{cpoints} is
@code{NULL} then a heuristic rule of thumb is used to get @var{n_cpoints}
construction points. This is the default behavior.
@var{n_cpoints} should be at least @code{2}, otherwise defaults are used.

The default number of construction points is 2.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ars_set_cpoints}
@deftypefn {} {int} unur_ars_set_cpoints (UNUR_PAR* @var{parameters}, int @var{n_cpoints}, const @var{double* cpoints})
Set construction points for the hat function. If @var{cpoints} is
@code{NULL} then a heuristic rule of thumb is used to get @var{n_cpoints}
construction points. This is the default behavior.
@var{n_cpoints} should be at least @code{2}, otherwise defaults are used.

The default number of construction points is 2.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ars_set_reinit_percentiles}
@anchor{funct:unur_ars_chg_reinit_percentiles}
@deftypefn Function {int} unur_ars_set_reinit_percentiles (UNUR_PAR* @var{parameters}, int @var{n_percentiles}, const @var{double* percentiles})
@deftypefnx Function {int} unur_ars_chg_reinit_percentiles (UNUR_GEN* @var{generator}, int @var{n_percentiles}, const @var{double* percentiles})
By default, when the @var{generator} object is reinitialized, it
used the same construction points as for the initialization
procedure.
Often the underlying distribution object has been changed only
moderately. For example, the full conditional distribution of a
multivariate distribution.
In this case it might be more appropriate to use
percentilesm of the hat function for the last (unchanged)
distribution. @var{percentiles} must then be a pointer to an
ordered array of numbers between @code{0.01} and @code{0.99}.
If @var{percentiles} is @code{NULL}, then a heuristic rule of thumb is
used to get @var{n_percentiles} values for these percentiles.
Notice that @var{n_percentiles} must be at least @code{2},
otherwise defaults are used.
(Then the first and third quartiles are used by default.)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ars_set_reinit_percentiles}
@anchor{funct:unur_ars_chg_reinit_percentiles}
@deftypefn {} {int} unur_ars_set_reinit_percentiles (UNUR_PAR* @var{parameters}, int @var{n_percentiles}, const @var{double* percentiles})
@deftypefnx {} {int} unur_ars_chg_reinit_percentiles (UNUR_GEN* @var{generator}, int @var{n_percentiles}, const @var{double* percentiles})
By default, when the @var{generator} object is reinitialized, it
used the same construction points as for the initialization
procedure.
Often the underlying distribution object has been changed only
moderately. For example, the full conditional distribution of a
multivariate distribution.
In this case it might be more appropriate to use
percentilesm of the hat function for the last (unchanged)
distribution. @var{percentiles} must then be a pointer to an
ordered array of numbers between @code{0.01} and @code{0.99}.
If @var{percentiles} is @code{NULL}, then a heuristic rule of thumb is
used to get @var{n_percentiles} values for these percentiles.
Notice that @var{n_percentiles} must be at least @code{2},
otherwise defaults are used.
(Then the first and third quartiles are used by default.)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ars_set_reinit_ncpoints}
@anchor{funct:unur_ars_chg_reinit_ncpoints}
@deftypefn Function {int} unur_ars_set_reinit_ncpoints (UNUR_PAR* @var{parameters}, int @var{ncpoints})
@deftypefnx Function {int} unur_ars_chg_reinit_ncpoints (UNUR_GEN* @var{generator}, int @var{ncpoints})
When reinit fails with the given construction points or the percentiles
of the old hat function, another trial is undertaken with @var{ncpoints}
construction points. @var{ncpoints} must be at least @code{10}.

Default: @code{30}
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ars_set_reinit_ncpoints}
@anchor{funct:unur_ars_chg_reinit_ncpoints}
@deftypefn {} {int} unur_ars_set_reinit_ncpoints (UNUR_PAR* @var{parameters}, int @var{ncpoints})
@deftypefnx {} {int} unur_ars_chg_reinit_ncpoints (UNUR_GEN* @var{generator}, int @var{ncpoints})
When reinit fails with the given construction points or the percentiles
of the old hat function, another trial is undertaken with @var{ncpoints}
construction points. @var{ncpoints} must be at least @code{10}.

Default: @code{30}
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ars_set_max_iter}
@deftypefn Function {int} unur_ars_set_max_iter (UNUR_PAR* @var{parameters}, int @var{max_iter})
The rejection loop stops after @var{max_iter} iterations and return
UNUR_INFINITY.

Default: @code{10000}
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ars_set_max_iter}
@deftypefn {} {int} unur_ars_set_max_iter (UNUR_PAR* @var{parameters}, int @var{max_iter})
The rejection loop stops after @var{max_iter} iterations and return
UNUR_INFINITY.

Default: @code{10000}
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ars_set_verify}
@anchor{funct:unur_ars_chg_verify}
@deftypefn Function {int} unur_ars_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx Function {int} unur_ars_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the condition squeeze(@i{x}) <= PDF(@i{x}) <= hat(@i{x}) is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ars_set_verify}
@anchor{funct:unur_ars_chg_verify}
@deftypefn {} {int} unur_ars_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx {} {int} unur_ars_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the condition squeeze(@i{x}) <= PDF(@i{x}) <= hat(@i{x}) is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ars_set_pedantic}
@deftypefn Function {int} unur_ars_set_pedantic (UNUR_PAR* @var{parameters}, int @var{pedantic})
Sometimes it might happen that
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
has been executed
successfully. But when additional construction points are added by
adaptive rejection sampling, the algorithm detects that the
PDF is not log-concave.

With @var{pedantic} being @code{TRUE}, the
sampling routine is exchanged by a routine that simply returns
@code{UNUR_INFINITY}. Otherwise the new point is not added to the
list of construction points. At least the hat function remains
log-concave.

Setting @var{pedantic} to @code{FALSE} allows sampling from a
distribution which is ``almost'' log-concave and small errors are
tolerated. However it might happen that the hat function cannot be
improved significantly. When the hat functions that has been
constructed by the
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
call is extremely large then it
might happen that the generation times are extremely high
(even hours are possible in extremely rare cases).

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ars_set_pedantic}
@deftypefn {} {int} unur_ars_set_pedantic (UNUR_PAR* @var{parameters}, int @var{pedantic})
Sometimes it might happen that
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
has been executed
successfully. But when additional construction points are added by
adaptive rejection sampling, the algorithm detects that the
PDF is not log-concave.

With @var{pedantic} being @code{TRUE}, the
sampling routine is exchanged by a routine that simply returns
@code{UNUR_INFINITY}. Otherwise the new point is not added to the
list of construction points. At least the hat function remains
log-concave.

Setting @var{pedantic} to @code{FALSE} allows sampling from a
distribution which is ``almost'' log-concave and small errors are
tolerated. However it might happen that the hat function cannot be
improved significantly. When the hat functions that has been
constructed by the
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
call is extremely large then it
might happen that the generation times are extremely high
(even hours are possible in extremely rare cases).

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ars_get_loghatarea}
@deftypefn Function {double} unur_ars_get_loghatarea (const @var{UNUR_GEN* generator})
Get the logarithm of area below the hat for the generator.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ars_get_loghatarea}
@deftypefn {} {double} unur_ars_get_loghatarea (const @var{UNUR_GEN* generator})
Get the logarithm of area below the hat for the generator.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ars_eval_invcdfhat}
@deftypefn Function {double} unur_ars_eval_invcdfhat (const @var{UNUR_GEN* generator}, double @var{u})
Evaluate the inverse of the CDF of the hat distribution at @var{u}.

If @var{u} is out of the domain [0,1] then @code{unur_errno} is set
to @code{UNUR_ERR_DOMAIN} and the respective bound of
the domain of the distribution are returned (which is
@code{-UNUR_INFINITY} or @code{UNUR_INFINITY} in the case of
unbounded domains).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ars_eval_invcdfhat}
@deftypefn {} {double} unur_ars_eval_invcdfhat (const @var{UNUR_GEN* generator}, double @var{u})
Evaluate the inverse of the CDF of the hat distribution at @var{u}.

If @var{u} is out of the domain [0,1] then @code{unur_errno} is set
to @code{UNUR_ERR_DOMAIN} and the respective bound of
the domain of the distribution are returned (which is
@code{-UNUR_INFINITY} or @code{UNUR_INFINITY} in the case of
unbounded domains).
@end deftypefn
@end ifnotinfo




@c
@c end of ars.h
@c -------------------------------------
@c -------------------------------------
@c cext.h
@c

@page
@node CEXT
@subsection   CEXT  --  wrapper for Continuous EXTernal generators

@table @i
@item Required:
routine for sampling continuous random variates
@item Speed:
depends on external generator
@item Reinit:
supported
@end table


Method CEXT is a wrapper for external generators for continuous
univariate distributions. It allows the usage of external
random variate generators within the UNU.RAN framework.


@subsubheading How To Use


The following steps are required to use some external generator
within the UNU.RAN framework (some of these are optional):

@enumerate
@item
Make an empty generator object using a
@ifhtml
@ref{funct:unur_cext_new,@command{unur_cext_new}}
@end ifhtml
@ifnothtml
@command{unur_cext_new}
@end ifnothtml
call.
The argument @var{distribution} is optional and can be replaced
by @code{NULL}. However, it is required if you want to pass
parameters of the generated distribution to the external
generator or for running some validation tests provided by
UNU.RAN.

@item
Create an initialization routine of type
@code{int (*init)(UNUR_GEN *gen)} and plug it into the generator
object using the
@ifhtml
@ref{funct:unur_cext_set_init,@command{unur_cext_set_init}}
@end ifhtml
@ifnothtml
@command{unur_cext_set_init}
@end ifnothtml
call. Notice that the
@var{init} routine must return @code{UNUR_SUCCESS} when it has
been executed successfully and @code{UNUR_FAILURE} otherwise.
It is possible to get the size of and the pointer to the array
of parameters of the underlying distribution object by the
respective calls
@ifhtml
@ref{funct:unur_cext_get_ndistrparams,@command{unur_cext_get_ndistrparams}}
@end ifhtml
@ifnothtml
@command{unur_cext_get_ndistrparams}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_cext_get_distrparams,@command{unur_cext_get_distrparams}.}
@end ifhtml
@ifnothtml
@command{unur_cext_get_distrparams}.
@end ifnothtml
Parameters for the external generator that are computed in the
@var{init} routine can be stored in a single array or structure
which is available by the
@ifhtml
@ref{funct:unur_cext_get_params,@command{unur_cext_get_params}}
@end ifhtml
@ifnothtml
@command{unur_cext_get_params}
@end ifnothtml
call.

Using an @var{init} routine is optional and can be omitted.

@item
Create a sampling routine of type
@code{double (*sample)(UNUR_GEN *gen)} and plug it into the
generator object using the
@ifhtml
@ref{funct:unur_cext_set_sample,@command{unur_cext_set_sample}}
@end ifhtml
@ifnothtml
@command{unur_cext_set_sample}
@end ifnothtml
call.

Uniform random numbers are provided by the
@ifhtml
@ref{funct:unur_sample_urng,@command{unur_sample_urng}}
@end ifhtml
@ifnothtml
@command{unur_sample_urng}
@end ifnothtml
call. Do not use your own implementation of a uniform random
number generator directly. If you want to use your own random
number generator we recommend to use the UNU.RAN interface (see
@pxref{URNG,,Using uniform random number generators}).

The array or structure that contains parameters for the external
generator that are computed in the @var{init} routine are
available using the
@ifhtml
@ref{funct:unur_cext_get_params,@command{unur_cext_get_params}}
@end ifhtml
@ifnothtml
@command{unur_cext_get_params}
@end ifnothtml
call.

Using a @var{sample} routine is of course obligatory.
@end enumerate

It is possible to change the parameters and the domain of the
chosen distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the
generator object. The @var{init} routine is then called again.

Here is a short example that demonstrates the application of
this method by means of the exponential distribution:

@smallexample
@include ref_example_cext.texi
@end smallexample




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_cext_new,unur_cext_new}
@item @ref{funct:unur_cext_set_init,unur_cext_set_init}
@item @ref{funct:unur_cext_set_sample,unur_cext_set_sample}
@item @ref{funct:unur_cext_get_params,unur_cext_get_params}
@item @ref{funct:unur_cext_get_distrparams,unur_cext_get_distrparams}
@item @ref{funct:unur_cext_get_ndistrparams,unur_cext_get_ndistrparams}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_cext_new}
@deftypefn Function {UNUR_PAR*} unur_cext_new (const @var{UNUR_DISTR* distribution})
Get default parameters for new generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_cext_new}
@deftypefn {} {UNUR_PAR*} unur_cext_new (const @var{UNUR_DISTR* distribution})
Get default parameters for new generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_cext_set_init}
@deftypefn Function {int} unur_cext_set_init (UNUR_PAR* @var{parameters}, int (* @var{init})(UNUR_GEN* gen ))
Set initialization routine for external generator. Inside the

@emph{Important:} The routine @var{init} must return
@code{UNUR_SUCCESS} when the generator was initialized successfully
and @code{UNUR_FAILURE} otherwise.

Parameters that are computed in the @var{init} routine can be
stored in an array or structure that is avaiable by means of the
@ifhtml
@ref{funct:unur_cext_get_params,@command{unur_cext_get_params}}
@end ifhtml
@ifnothtml
@command{unur_cext_get_params}
@end ifnothtml
call. Parameters of the underlying
distribution object can be obtained by the
@ifhtml
@ref{funct:unur_cext_get_distrparams,@command{unur_cext_get_distrparams}}
@end ifhtml
@ifnothtml
@command{unur_cext_get_distrparams}
@end ifnothtml
call.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_cext_set_init}
@deftypefn {} {int} unur_cext_set_init (UNUR_PAR* @var{parameters}, int (* @var{init})(UNUR_GEN* gen ))
Set initialization routine for external generator. Inside the

@emph{Important:} The routine @var{init} must return
@code{UNUR_SUCCESS} when the generator was initialized successfully
and @code{UNUR_FAILURE} otherwise.

Parameters that are computed in the @var{init} routine can be
stored in an array or structure that is avaiable by means of the
@ifhtml
@ref{funct:unur_cext_get_params,@command{unur_cext_get_params}}
@end ifhtml
@ifnothtml
@command{unur_cext_get_params}
@end ifnothtml
call. Parameters of the underlying
distribution object can be obtained by the
@ifhtml
@ref{funct:unur_cext_get_distrparams,@command{unur_cext_get_distrparams}}
@end ifhtml
@ifnothtml
@command{unur_cext_get_distrparams}
@end ifnothtml
call.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_cext_set_sample}
@deftypefn Function {int} unur_cext_set_sample (UNUR_PAR* @var{parameters}, double (* @var{sample})(UNUR_GEN* gen ))
Set sampling routine for external generator.

@emph{Important:}
Use @code{unur_sample_urng(gen)} to get a uniform random number.
The pointer to the array or structure that contains the parameters
that are precomputed in the @var{init} routine are available by
@code{unur_cext_get_params(gen,0)}.
Additionally one can use the
@ifhtml
@ref{funct:unur_cext_get_distrparams,@command{unur_cext_get_distrparams}}
@end ifhtml
@ifnothtml
@command{unur_cext_get_distrparams}
@end ifnothtml
call.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_cext_set_sample}
@deftypefn {} {int} unur_cext_set_sample (UNUR_PAR* @var{parameters}, double (* @var{sample})(UNUR_GEN* gen ))
Set sampling routine for external generator.

@emph{Important:}
Use @code{unur_sample_urng(gen)} to get a uniform random number.
The pointer to the array or structure that contains the parameters
that are precomputed in the @var{init} routine are available by
@code{unur_cext_get_params(gen,0)}.
Additionally one can use the
@ifhtml
@ref{funct:unur_cext_get_distrparams,@command{unur_cext_get_distrparams}}
@end ifhtml
@ifnothtml
@command{unur_cext_get_distrparams}
@end ifnothtml
call.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_cext_get_params}
@deftypefn Function {void*} unur_cext_get_params (UNUR_GEN* @var{generator}, size_t @var{size})
Get pointer to memory block for storing parameters of external
generator. A memory block of size @var{size} is automatically (re-)
allocated if necessary and the pointer to this block is stored in
the @var{generator} object. If one only needs the pointer to this
memory block set @var{size} to @code{0}.

Notice, that @var{size} is the size of the memory block and not the
length of an array.

@emph{Important:} This rountine should only be used in the
initialization and sampling routine of the external generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_cext_get_params}
@deftypefn {} {void*} unur_cext_get_params (UNUR_GEN* @var{generator}, size_t @var{size})
Get pointer to memory block for storing parameters of external
generator. A memory block of size @var{size} is automatically (re-)
allocated if necessary and the pointer to this block is stored in
the @var{generator} object. If one only needs the pointer to this
memory block set @var{size} to @code{0}.

Notice, that @var{size} is the size of the memory block and not the
length of an array.

@emph{Important:} This rountine should only be used in the
initialization and sampling routine of the external generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_cext_get_distrparams}
@anchor{funct:unur_cext_get_ndistrparams}
@deftypefn Function {double*} unur_cext_get_distrparams (UNUR_GEN* @var{generator})
@deftypefnx Function {int} unur_cext_get_ndistrparams (UNUR_GEN* @var{generator})
Get size of and pointer to array of parameters of underlying
distribution in @var{generator} object.

@emph{Important:} These rountines should only be used in the
initialization and sampling routine of the external generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_cext_get_distrparams}
@anchor{funct:unur_cext_get_ndistrparams}
@deftypefn {} {double*} unur_cext_get_distrparams (UNUR_GEN* @var{generator})
@deftypefnx {} {int} unur_cext_get_ndistrparams (UNUR_GEN* @var{generator})
Get size of and pointer to array of parameters of underlying
distribution in @var{generator} object.

@emph{Important:} These rountines should only be used in the
initialization and sampling routine of the external generator.
@end deftypefn
@end ifnotinfo




@c
@c end of cext.h
@c -------------------------------------
@c -------------------------------------
@c cstd.h
@c

@page
@node CSTD
@subsection   CSTD  --  Continuous STandarD distributions

@table @i
@item Required:
standard distribution from UNU.RAN library (@pxref{Stddist,,Standard distributions}) or continuous distribution with inverse CDF.
@item Speed:
Set-up: fast, Sampling: depends on distribution and generator
@item Reinit:
supported
@end table


CSTD is a wrapper for special generators for continuous
univariate standard distributions. It only works for
distributions in the UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions})
or for continuous distributions where the inverse CDF is given.
If a distribution object is provided that is build from scratch,
it must provide the inverse CDF. Then CSTD implements the
inversion method. Otherwise, the @code{NULL} pointer is returned.

For some distributions more than one special generator
is possible.


@subsubheading How To Use


Create a distribution object for a standard distribution
from the UNU.RAN library
(@pxref{Stddist,,Standard distributions}),
or create a continuous distribution object and set the function
for the inverse CDF using
@ifhtml
@ref{funct:unur_distr_cont_set_invcdf,@command{unur_distr_cont_set_invcdf}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_invcdf}.
@end ifnothtml
For some distributions more than one special generator
(@emph{variants}) is possible. These can be choosen by a
@ifhtml
@ref{funct:unur_cstd_set_variant,@command{unur_cstd_set_variant}}
@end ifhtml
@ifnothtml
@command{unur_cstd_set_variant}
@end ifnothtml
call. For possible variants
@pxref{Stddist,,Standard distributions}.
However the following are common to all distributions:

@table @code
@item UNUR_STDGEN_DEFAULT
the default generator.
@item UNUR_STDGEN_FAST
the fastest available special generator.
@item UNUR_STDGEN_INVERSION
the inversion method (if available).
@end table

Notice that the variant @code{UNUR_STDGEN_FAST} for a special
generator may be slower than one of the universal algorithms!
Additional variants may exist for particular distributions.

Sampling from truncated distributions (which can be constructed by
changing the default domain of a distribution by means of
@ifhtml
@ref{funct:unur_distr_cont_set_domain,@command{unur_distr_cont_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_domain}
@end ifnothtml
or
@ifhtml
@ref{funct:unur_cstd_chg_truncated,@command{unur_cstd_chg_truncated}}
@end ifhtml
@ifnothtml
@command{unur_cstd_chg_truncated}
@end ifnothtml
calls)
is possible but requires the inversion method. Moreover the CDF
of the distribution must be implemented.

It is possible to change the parameters and the domain of the chosen
distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator object.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_cstd_new,unur_cstd_new}
@item @ref{funct:unur_cstd_set_variant,unur_cstd_set_variant}
@item @ref{funct:unur_cstd_chg_truncated,unur_cstd_chg_truncated}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_cstd_new}
@deftypefn Function {UNUR_PAR*} unur_cstd_new (const @var{UNUR_DISTR* distribution})
Get default parameters for new generator. It requires a distribution object
for a continuous univariant distribution from the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions}).

Using a truncated distribution is allowed only if the inversion method
is available and selected by the
@ifhtml
@ref{funct:unur_cstd_set_variant,@command{unur_cstd_set_variant}}
@end ifhtml
@ifnothtml
@command{unur_cstd_set_variant}
@end ifnothtml
call immediately
after creating the parameter object.
Use a
@ifhtml
@ref{funct:unur_distr_cont_set_domain,@command{unur_distr_cont_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_domain}
@end ifnothtml
call to get a truncated distribution.
To change the domain of a (truncated) distribution of a generator use the
@ifhtml
@ref{funct:unur_cstd_chg_truncated,@command{unur_cstd_chg_truncated}}
@end ifhtml
@ifnothtml
@command{unur_cstd_chg_truncated}
@end ifnothtml
call.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_cstd_new}
@deftypefn {} {UNUR_PAR*} unur_cstd_new (const @var{UNUR_DISTR* distribution})
Get default parameters for new generator. It requires a distribution object
for a continuous univariant distribution from the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions}).

Using a truncated distribution is allowed only if the inversion method
is available and selected by the
@ifhtml
@ref{funct:unur_cstd_set_variant,@command{unur_cstd_set_variant}}
@end ifhtml
@ifnothtml
@command{unur_cstd_set_variant}
@end ifnothtml
call immediately
after creating the parameter object.
Use a
@ifhtml
@ref{funct:unur_distr_cont_set_domain,@command{unur_distr_cont_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_domain}
@end ifnothtml
call to get a truncated distribution.
To change the domain of a (truncated) distribution of a generator use the
@ifhtml
@ref{funct:unur_cstd_chg_truncated,@command{unur_cstd_chg_truncated}}
@end ifhtml
@ifnothtml
@command{unur_cstd_chg_truncated}
@end ifnothtml
call.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_cstd_set_variant}
@deftypefn Function {int} unur_cstd_set_variant (UNUR_PAR* @var{parameters}, unsigned @var{variant})
Set variant (special generator) for sampling from a given distribution.
For possible variants
@pxref{Stddist,,Standard distributions}.

Common variants are @code{UNUR_STDGEN_DEFAULT} for the default generator,
@code{UNUR_STDGEN_FAST} for (one of the) fastest implemented
special generators, and @code{UNUR_STDGEN_INVERSION} for the
inversion method (if available).
If the selected variant number is not implemented, then an error code is
returned and the variant is not changed.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_cstd_set_variant}
@deftypefn {} {int} unur_cstd_set_variant (UNUR_PAR* @var{parameters}, unsigned @var{variant})
Set variant (special generator) for sampling from a given distribution.
For possible variants
@pxref{Stddist,,Standard distributions}.

Common variants are @code{UNUR_STDGEN_DEFAULT} for the default generator,
@code{UNUR_STDGEN_FAST} for (one of the) fastest implemented
special generators, and @code{UNUR_STDGEN_INVERSION} for the
inversion method (if available).
If the selected variant number is not implemented, then an error code is
returned and the variant is not changed.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_cstd_chg_truncated}
@deftypefn Function {int} unur_cstd_chg_truncated (UNUR_GEN* @var{generator}, double @var{left}, double @var{right})
Change left and right border of the domain of the (truncated) distribution.
This is only possible if the inversion method is used.
Otherwise this call has no effect and an error code is returned.

Notice that the given truncated domain must be a subset of the
domain of the given distribution. The generator always uses the
intersection of the domain of the distribution and the truncated
domain given by this call.

It is not required to run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
after this call has been used.

@emph{Important:} If the CDF is (almost) the same for @var{left} and
@var{right} and (almost) equal to @code{0} or @code{1}, then the truncated
domain is not chanced and the call returns an error code.

@emph{Notice:} If the parameters of the distribution has been changed
it is recommended to set the truncated domain again, since the
former call might change the domain of the distribution but not
update the values for the boundaries of the truncated
distribution.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_cstd_chg_truncated}
@deftypefn {} {int} unur_cstd_chg_truncated (UNUR_GEN* @var{generator}, double @var{left}, double @var{right})
Change left and right border of the domain of the (truncated) distribution.
This is only possible if the inversion method is used.
Otherwise this call has no effect and an error code is returned.

Notice that the given truncated domain must be a subset of the
domain of the given distribution. The generator always uses the
intersection of the domain of the distribution and the truncated
domain given by this call.

It is not required to run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
after this call has been used.

@emph{Important:} If the CDF is (almost) the same for @var{left} and
@var{right} and (almost) equal to @code{0} or @code{1}, then the truncated
domain is not chanced and the call returns an error code.

@emph{Notice:} If the parameters of the distribution has been changed
it is recommended to set the truncated domain again, since the
former call might change the domain of the distribution but not
update the values for the boundaries of the truncated
distribution.
@end deftypefn
@end ifnotinfo




@c
@c end of cstd.h
@c -------------------------------------
@c -------------------------------------
@c hinv.h
@c

@page
@node HINV
@subsection   HINV  --  Hermite interpolation based INVersion of CDF

@table @i
@item Required:
CDF
@item Optional:
PDF, dPDF
@item Speed:
Set-up: (very) slow, Sampling: (very) fast
@item Reinit:
supported
@item Reference:
@ifhtml
@ref{bib:HLa03,, [HLa03]}
@end ifhtml
@ifnothtml
[HLa03]
@end ifnothtml
@ifhtml
@ref{bib:HLD04,, [HLD04: Sect.7.2; Alg.7.1]}
@end ifhtml
@ifnothtml
[HLD04: Sect.7.2; Alg.7.1]
@end ifnothtml

@end table


HINV is a variant of numerical inversion, where the inverse CDF
is approximated using Hermite interpolation, i.e., the interval
[0,1] is split into several intervals and in each interval the
inverse CDF is approximated by polynomials constructed by means
of values of the CDF and PDF at interval boundaries. This makes
it possible to improve the accuracy by splitting a particular
interval without recomputations in unaffected intervals. Three
types of splines are implemented: linear, cubic, and quintic
interpolation. For linear interpolation only the CDF is
required. Cubic interpolation also requires PDF and quintic
interpolation PDF and its derivative.

These splines have to be computed in a setup step. However, it
only works for distributions with bounded domain; for
distributions with unbounded domain the tails are chopped off
such that the probability for the tail regions is small compared
to the given u-resolution.

The method is not exact, as it only produces random variates of
the approximated distribution. Nevertheless, the maximal
numerical error in "u-direction" (i.e. |U-CDF(X)|, for
X = "approximate inverse CDF"(U) |U-CDF(X)|) can be set to the
required resolution (within machine precision).
Notice that very small values of the u-resolution are possible
but may increase the cost for the setup step.

As the possible maximal error is only estimated in the setup it
may be necessary to set some special design points for computing
the Hermite interpolation to guarantee that the maximal u-error
can not be bigger than desired. Such points are points where the
density is not differentiable or has a local extremum. Notice
that there is no necessity to do so. However, if you do not
provide these points to the algorithm there might be a small
chance that the approximation error is larger than the given
u-resolution, or that the required number of intervals is larger
than necessary.


@subsubheading How To Use


HINV works for continuous univariate distribution objects with
given CDF and (optional) PDF. It uses Hermite interpolation of
order 1, 3 [default] or 5. The order can be set by means of
@ifhtml
@ref{funct:unur_hinv_set_order,@command{unur_hinv_set_order}.}
@end ifhtml
@ifnothtml
@command{unur_hinv_set_order}.
@end ifnothtml
For distributions with unbounded domains the tails are chopped
off such that the probability for the tail regions is small
compared to the given u-resulution. For finding these cut points
the algorithm starts with the region @code{[-1.e20,1.e20]}. For
the exceptional case where this might be too small (or one knows
this region and wants to avoid this search heuristics) it can be
directly set via a
@ifhtml
@ref{funct:unur_hinv_set_boundary,@command{unur_hinv_set_boundary}}
@end ifhtml
@ifnothtml
@command{unur_hinv_set_boundary}
@end ifnothtml
call.

It is possible to use this method for generating from truncated
distributions. It even can be changed for an existing generator
object by an
@ifhtml
@ref{funct:unur_hinv_chg_truncated,@command{unur_hinv_chg_truncated}}
@end ifhtml
@ifnothtml
@command{unur_hinv_chg_truncated}
@end ifnothtml
call.

This method is not exact, as it only produces random variates of
the approximated distribution. Nevertheless, the numerical error
in "u-direction" (i.e. |U-CDF(X)|, for
X = "approximate inverse CDF"(U) |U-CDF(X)|) can be controlled
by means of
@ifhtml
@ref{funct:unur_hinv_set_u_resolution,@command{unur_hinv_set_u_resolution}.}
@end ifhtml
@ifnothtml
@command{unur_hinv_set_u_resolution}.
@end ifnothtml
The possible maximal error is only estimated in the setup. Thus
it might be necessary to set some special design points for
computing the Hermite interpolation to guarantee that the
maximal u-error can not be bigger than desired. Such points
(e.g. extremal points of the PDF, points with infinite
derivative) can be set using using the
@ifhtml
@ref{funct:unur_hinv_set_cpoints,@command{unur_hinv_set_cpoints}}
@end ifhtml
@ifnothtml
@command{unur_hinv_set_cpoints}
@end ifnothtml
call.
If the mode for a unimodal distribution is set in the distribution
object this mode is automatically used as design-point if the
@ifhtml
@ref{funct:unur_hinv_set_cpoints,@command{unur_hinv_set_cpoints}}
@end ifhtml
@ifnothtml
@command{unur_hinv_set_cpoints}
@end ifnothtml
call is not used.

As already mentioned the maximal error of this approximation is
only estimated. If this error is crucial for an application we
recommend to compute this error using
@ifhtml
@ref{funct:unur_hinv_estimate_error,@command{unur_hinv_estimate_error}}
@end ifhtml
@ifnothtml
@command{unur_hinv_estimate_error}
@end ifnothtml
which runs a small Monte Carlo simulation.

It is possible to change the parameters and the domain of the chosen
distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator object.
The values given by the last
@ifhtml
@ref{funct:unur_hinv_chg_truncated,@command{unur_hinv_chg_truncated}}
@end ifhtml
@ifnothtml
@command{unur_hinv_chg_truncated}
@end ifnothtml
call will be
then changed to the values of the domain of the underlying distribution
object. Moreover, starting construction points (nodes) that are given by
a
@ifhtml
@ref{funct:unur_hinv_set_cpoints,@command{unur_hinv_set_cpoints}}
@end ifhtml
@ifnothtml
@command{unur_hinv_set_cpoints}
@end ifnothtml
call are ignored when
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
is
called.
It is important to note that for a distribution from the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions})
the normalization constant has to be updated using the
@ifhtml
@ref{funct:unur_distr_cont_upd_pdfarea,@command{unur_distr_cont_upd_pdfarea}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_pdfarea}
@end ifnothtml
call whenever its parameters have been
changed by means of a
@ifhtml
@ref{funct:unur_distr_cont_set_pdfparams,@command{unur_distr_cont_set_pdfparams}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_pdfparams}
@end ifnothtml
call.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_hinv_new,unur_hinv_new}
@item @ref{funct:unur_hinv_set_order,unur_hinv_set_order}
@item @ref{funct:unur_hinv_set_u_resolution,unur_hinv_set_u_resolution}
@item @ref{funct:unur_hinv_set_cpoints,unur_hinv_set_cpoints}
@item @ref{funct:unur_hinv_set_boundary,unur_hinv_set_boundary}
@item @ref{funct:unur_hinv_set_guidefactor,unur_hinv_set_guidefactor}
@item @ref{funct:unur_hinv_set_max_intervals,unur_hinv_set_max_intervals}
@item @ref{funct:unur_hinv_get_n_intervals,unur_hinv_get_n_intervals}
@item @ref{funct:unur_hinv_eval_approxinvcdf,unur_hinv_eval_approxinvcdf}
@item @ref{funct:unur_hinv_chg_truncated,unur_hinv_chg_truncated}
@item @ref{funct:unur_hinv_estimate_error,unur_hinv_estimate_error}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_hinv_new}
@deftypefn Function {UNUR_PAR*} unur_hinv_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hinv_new}
@deftypefn {} {UNUR_PAR*} unur_hinv_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hinv_set_order}
@deftypefn Function {int} unur_hinv_set_order (UNUR_PAR* @var{parameters}, int @var{order})
Set order of Hermite interpolation. Valid orders are
@code{1}, @code{3}, and @code{5}.
Notice that @var{order} greater than @code{1} requires the density
of the distribution, and @var{order} greater than @code{3} even
requires the derivative of the density. Using @var{order} @code{1}
results for most distributions in a huge number of intervals
and is therefore not recommended. If the maximal error in
u-direction is very small (say smaller than @code{1.e-10}),
@var{order} @code{5} is recommended as it leads to considerably
fewer design points, as long there are no poles or heavy tails.

@emph{Remark:} When the target distribution has poles or (very) heavy
tails @var{order} @code{5} (i.e., quintic interpolation) is
numerically less stable and more sensitive to round-off errors than
@var{order} @code{3} (i.e., cubic interpolation).

Default is @code{3} if the density is given and @code{1} otherwise.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hinv_set_order}
@deftypefn {} {int} unur_hinv_set_order (UNUR_PAR* @var{parameters}, int @var{order})
Set order of Hermite interpolation. Valid orders are
@code{1}, @code{3}, and @code{5}.
Notice that @var{order} greater than @code{1} requires the density
of the distribution, and @var{order} greater than @code{3} even
requires the derivative of the density. Using @var{order} @code{1}
results for most distributions in a huge number of intervals
and is therefore not recommended. If the maximal error in
u-direction is very small (say smaller than @code{1.e-10}),
@var{order} @code{5} is recommended as it leads to considerably
fewer design points, as long there are no poles or heavy tails.

@emph{Remark:} When the target distribution has poles or (very) heavy
tails @var{order} @code{5} (i.e., quintic interpolation) is
numerically less stable and more sensitive to round-off errors than
@var{order} @code{3} (i.e., cubic interpolation).

Default is @code{3} if the density is given and @code{1} otherwise.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hinv_set_u_resolution}
@deftypefn Function {int} unur_hinv_set_u_resolution (UNUR_PAR* @var{parameters}, double @var{u_resolution})
Set maximal error in u-direction. However, the given u-error must not
be smaller than machine epsilon (@code{DBL_EPSILON}) and should not be
too close to this value. As the resolution of most uniform random
number sources is 2^(-32) = @code{2.3e-10}, a value of @code{1.e-10}
leads to an inversion algorithm that could be called exact. For most
simulations slightly bigger values for the maximal error are enough
as well.

Remark: The u-error might become larger than @var{u_resolution} due
to rescaling of floating point numbers when the domain of the
distribution is truncated by a
@ifhtml
@ref{funct:unur_hinv_chg_truncated,@command{unur_hinv_chg_truncated}}
@end ifhtml
@ifnothtml
@command{unur_hinv_chg_truncated}
@end ifnothtml
call.

Default is @code{1.e-10}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hinv_set_u_resolution}
@deftypefn {} {int} unur_hinv_set_u_resolution (UNUR_PAR* @var{parameters}, double @var{u_resolution})
Set maximal error in u-direction. However, the given u-error must not
be smaller than machine epsilon (@code{DBL_EPSILON}) and should not be
too close to this value. As the resolution of most uniform random
number sources is 2^(-32) = @code{2.3e-10}, a value of @code{1.e-10}
leads to an inversion algorithm that could be called exact. For most
simulations slightly bigger values for the maximal error are enough
as well.

Remark: The u-error might become larger than @var{u_resolution} due
to rescaling of floating point numbers when the domain of the
distribution is truncated by a
@ifhtml
@ref{funct:unur_hinv_chg_truncated,@command{unur_hinv_chg_truncated}}
@end ifhtml
@ifnothtml
@command{unur_hinv_chg_truncated}
@end ifnothtml
call.

Default is @code{1.e-10}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hinv_set_cpoints}
@deftypefn Function {int} unur_hinv_set_cpoints (UNUR_PAR* @var{parameters}, const @var{double* stp}, int @var{n_stp})
Set starting construction points (nodes) for Hermite interpolation.

As the possible maximal error is only estimated in the setup
it may be necessary to set some special design points for
computing the Hermite interpolation to guarantee that the
maximal u-error can not be bigger than desired. We suggest to
include as special design points all local extrema of the density,
all points where the density is not differentiable, and isolated
points inside of the domain with density 0.
If there is an interval with density constant equal to 0 inside of
the given domain of the density, both endpoints of this interval
should be included as special design points. Notice that there is no
necessity to do so. However, if these points are not provided to
the algorithm the approximation error might be larger than the
given u-resolution, or the required number of intervals could be
larger than necessary.

@emph{Important}: Notice that the given points must be in
increasing order and they must be disjoint.

@emph{Important}: The boundary point of the computational region
must not be given in this list!
Points outside the boundary of the computational region are ignored.

Default is for unimodal densities - if known - the mode of the
density, if it is not equal to the border of the domain.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hinv_set_cpoints}
@deftypefn {} {int} unur_hinv_set_cpoints (UNUR_PAR* @var{parameters}, const @var{double* stp}, int @var{n_stp})
Set starting construction points (nodes) for Hermite interpolation.

As the possible maximal error is only estimated in the setup
it may be necessary to set some special design points for
computing the Hermite interpolation to guarantee that the
maximal u-error can not be bigger than desired. We suggest to
include as special design points all local extrema of the density,
all points where the density is not differentiable, and isolated
points inside of the domain with density 0.
If there is an interval with density constant equal to 0 inside of
the given domain of the density, both endpoints of this interval
should be included as special design points. Notice that there is no
necessity to do so. However, if these points are not provided to
the algorithm the approximation error might be larger than the
given u-resolution, or the required number of intervals could be
larger than necessary.

@emph{Important}: Notice that the given points must be in
increasing order and they must be disjoint.

@emph{Important}: The boundary point of the computational region
must not be given in this list!
Points outside the boundary of the computational region are ignored.

Default is for unimodal densities - if known - the mode of the
density, if it is not equal to the border of the domain.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hinv_set_boundary}
@deftypefn Function {int} unur_hinv_set_boundary (UNUR_PAR* @var{parameters}, double @var{left}, double @var{right})
Set the left and right boundary of the computational interval.
Of course @code{+/- UNUR_INFINITY} is not allowed.
If the CDF at @var{left} and @var{right} is not close to the
respective values @code{0.} and @code{1.} then this interval is
increased by a (rather slow) search algorithm.

@emph{Important}: This call does not change the domain of the
given distribution itself. But it restricts the domain for the
resulting random variates.

Default is @code{1.e20}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hinv_set_boundary}
@deftypefn {} {int} unur_hinv_set_boundary (UNUR_PAR* @var{parameters}, double @var{left}, double @var{right})
Set the left and right boundary of the computational interval.
Of course @code{+/- UNUR_INFINITY} is not allowed.
If the CDF at @var{left} and @var{right} is not close to the
respective values @code{0.} and @code{1.} then this interval is
increased by a (rather slow) search algorithm.

@emph{Important}: This call does not change the domain of the
given distribution itself. But it restricts the domain for the
resulting random variates.

Default is @code{1.e20}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hinv_set_guidefactor}
@deftypefn Function {int} unur_hinv_set_guidefactor (UNUR_PAR* @var{parameters}, double @var{factor})
Set factor for relative size of the guide table for indexed search
(see also method DGT @ref{DGT}). It must be greater than or equal
to @code{0}.
When set to @code{0}, then sequential search is used.

Default is @code{1}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hinv_set_guidefactor}
@deftypefn {} {int} unur_hinv_set_guidefactor (UNUR_PAR* @var{parameters}, double @var{factor})
Set factor for relative size of the guide table for indexed search
(see also method DGT @ref{DGT}). It must be greater than or equal
to @code{0}.
When set to @code{0}, then sequential search is used.

Default is @code{1}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hinv_set_max_intervals}
@deftypefn Function {int} unur_hinv_set_max_intervals (UNUR_PAR* @var{parameters}, int @var{max_ivs})
Set maximum number of intervals. No generator object is created if
the necessary number of intervals for the Hermite interpolation
exceeds @var{max_ivs}. It is used to prevent the algorithm to eat up
all memory for very badly shaped CDFs.

Default is @code{1000000} (1.e6).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hinv_set_max_intervals}
@deftypefn {} {int} unur_hinv_set_max_intervals (UNUR_PAR* @var{parameters}, int @var{max_ivs})
Set maximum number of intervals. No generator object is created if
the necessary number of intervals for the Hermite interpolation
exceeds @var{max_ivs}. It is used to prevent the algorithm to eat up
all memory for very badly shaped CDFs.

Default is @code{1000000} (1.e6).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hinv_get_n_intervals}
@deftypefn Function {int} unur_hinv_get_n_intervals (const @var{UNUR_GEN* generator})
Get number of nodes (design points) used for Hermite interpolation in
the generator object. The number of intervals is the number of
nodes minus 1.
It returns an error code in case of an error.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hinv_get_n_intervals}
@deftypefn {} {int} unur_hinv_get_n_intervals (const @var{UNUR_GEN* generator})
Get number of nodes (design points) used for Hermite interpolation in
the generator object. The number of intervals is the number of
nodes minus 1.
It returns an error code in case of an error.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hinv_eval_approxinvcdf}
@deftypefn Function {double} unur_hinv_eval_approxinvcdf (const @var{UNUR_GEN* generator}, double @var{u})
Evaluate Hermite interpolation of inverse CDF at @var{u}.
If @var{u} is out of the domain [0,1] then @code{unur_errno} is set
to @code{UNUR_ERR_DOMAIN} and the respective bound of
the domain of the distribution are returned (which is
@code{-UNUR_INFINITY} or @code{UNUR_INFINITY} in the case of
unbounded domains).

@emph{Notice}: When the domain has been truncated by a
@ifhtml
@ref{funct:unur_hinv_chg_truncated,@command{unur_hinv_chg_truncated}}
@end ifhtml
@ifnothtml
@command{unur_hinv_chg_truncated}
@end ifnothtml
call then the inverse CDF of the
truncated distribution is returned.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hinv_eval_approxinvcdf}
@deftypefn {} {double} unur_hinv_eval_approxinvcdf (const @var{UNUR_GEN* generator}, double @var{u})
Evaluate Hermite interpolation of inverse CDF at @var{u}.
If @var{u} is out of the domain [0,1] then @code{unur_errno} is set
to @code{UNUR_ERR_DOMAIN} and the respective bound of
the domain of the distribution are returned (which is
@code{-UNUR_INFINITY} or @code{UNUR_INFINITY} in the case of
unbounded domains).

@emph{Notice}: When the domain has been truncated by a
@ifhtml
@ref{funct:unur_hinv_chg_truncated,@command{unur_hinv_chg_truncated}}
@end ifhtml
@ifnothtml
@command{unur_hinv_chg_truncated}
@end ifnothtml
call then the inverse CDF of the
truncated distribution is returned.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hinv_chg_truncated}
@deftypefn Function {int} unur_hinv_chg_truncated (UNUR_GEN* @var{generator}, double @var{left}, double @var{right})
Changes the borders of the domain of the (truncated) distribution.

Notice that the given truncated domain must be a subset of the
domain of the given distribution. The generator always uses the
intersection of the domain of the distribution and the truncated
domain given by this call. The tables of splines are not recomputed.
Thus it might happen that the relative error for the generated variates
from the truncated distribution is greater than the bound for the
non-truncated distribution. This call also fails when the CDF values
of the boundary points are too close, i.e. when only a few different
floating point numbers would be computed due to round-off errors
with floating point arithmetic.

Remark: The u-error might become larger than the @var{u_resolution}
given by a
@ifhtml
@ref{funct:unur_hinv_set_u_resolution,@command{unur_hinv_set_u_resolution}}
@end ifhtml
@ifnothtml
@command{unur_hinv_set_u_resolution}
@end ifnothtml
call due to rescaling of
floating point numbers when the domain of the distribution is
truncated.

When failed an error code is returned.

@emph{Important}: Always check the return code since the domain is
not changed in case of an error.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hinv_chg_truncated}
@deftypefn {} {int} unur_hinv_chg_truncated (UNUR_GEN* @var{generator}, double @var{left}, double @var{right})
Changes the borders of the domain of the (truncated) distribution.

Notice that the given truncated domain must be a subset of the
domain of the given distribution. The generator always uses the
intersection of the domain of the distribution and the truncated
domain given by this call. The tables of splines are not recomputed.
Thus it might happen that the relative error for the generated variates
from the truncated distribution is greater than the bound for the
non-truncated distribution. This call also fails when the CDF values
of the boundary points are too close, i.e. when only a few different
floating point numbers would be computed due to round-off errors
with floating point arithmetic.

Remark: The u-error might become larger than the @var{u_resolution}
given by a
@ifhtml
@ref{funct:unur_hinv_set_u_resolution,@command{unur_hinv_set_u_resolution}}
@end ifhtml
@ifnothtml
@command{unur_hinv_set_u_resolution}
@end ifnothtml
call due to rescaling of
floating point numbers when the domain of the distribution is
truncated.

When failed an error code is returned.

@emph{Important}: Always check the return code since the domain is
not changed in case of an error.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hinv_estimate_error}
@deftypefn Function {int} unur_hinv_estimate_error (const @var{UNUR_GEN* generator}, int @var{samplesize}, double* @var{max_error}, double* @var{MAE})
Estimate maximal u-error and mean absolute error (MAE) for
@var{generator} by means of a (quasi-) Monte-Carlo simulation with
sample size @var{samplesize}.
The results are stored in @var{max_error} and @var{MAE}, respectively.

It returns @code{UNUR_SUCCESS} if successful.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hinv_estimate_error}
@deftypefn {} {int} unur_hinv_estimate_error (const @var{UNUR_GEN* generator}, int @var{samplesize}, double* @var{max_error}, double* @var{MAE})
Estimate maximal u-error and mean absolute error (MAE) for
@var{generator} by means of a (quasi-) Monte-Carlo simulation with
sample size @var{samplesize}.
The results are stored in @var{max_error} and @var{MAE}, respectively.

It returns @code{UNUR_SUCCESS} if successful.
@end deftypefn
@end ifnotinfo




@c
@c end of hinv.h
@c -------------------------------------
@c -------------------------------------
@c hrb.h
@c

@page
@node HRB
@subsection   HRB  --  Hazard Rate Bounded

@table @i
@item Required:
bounded hazard rate
@item Optional:
upper bound for hazard rate
@item Speed:
Set-up: fast, Sampling: slow
@item Reinit:
supported
@item Reference:
@ifhtml
@ref{bib:HLD04,, [HLD04: Sect.9.1.4; Alg.9.4]}
@end ifhtml
@ifnothtml
[HLD04: Sect.9.1.4; Alg.9.4]
@end ifnothtml

@end table


Generates random variate with given hazard rate which must be
bounded from above. It uses the thinning method with a constant
dominating hazard function.


@subsubheading How To Use


HRB requires a hazard function for a continuous distribution
together with an upper bound. The latter has to be set using the
@ifhtml
@ref{funct:unur_hrb_set_upperbound,@command{unur_hrb_set_upperbound}}
@end ifhtml
@ifnothtml
@command{unur_hrb_set_upperbound}
@end ifnothtml
call. If no such upper bound is given
it is assumed that the upper bound can be achieved by evaluating
the hazard rate at the left hand boundary of the domain of the
distribution. Notice, however, that for decreasing hazard rate
the method HRD (@pxref{HRD,,Hazard Rate Decreasing}) is much
faster and thus the prefered method.

It is important to note that the domain of the distribution can
be set via a
@ifhtml
@ref{funct:unur_distr_cont_set_domain,@command{unur_distr_cont_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_domain}
@end ifnothtml
call.
However, the left border must not be negative. Otherwise it is
set to @code{0}. This is also the default if no domain is
given at all. For computational reasons the right border is
always set to @code{UNUR_INFINITY} independently of the given
domain. Thus for domains bounded from right the function for
computing the hazard rate should return @code{UNUR_INFINITY}
right of this domain.

For distributions with increasing hazard rate method HRI
(@pxref{HRI,,Hazard Rate Increasing}) is required.

It is possible to change the parameters and the domain of the chosen
distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator object.
Notice, that the upper bound given by the
@ifhtml
@ref{funct:unur_hrb_set_upperbound,@command{unur_hrb_set_upperbound}}
@end ifhtml
@ifnothtml
@command{unur_hrb_set_upperbound}
@end ifnothtml
call
cannot be changed and must be valid for the changed distribution.



@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_hrb_new,unur_hrb_new}
@item @ref{funct:unur_hrb_set_upperbound,unur_hrb_set_upperbound}
@item @ref{funct:unur_hrb_set_verify,unur_hrb_set_verify}
@item @ref{funct:unur_hrb_chg_verify,unur_hrb_chg_verify}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_hrb_new}
@deftypefn Function {UNUR_PAR*} unur_hrb_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hrb_new}
@deftypefn {} {UNUR_PAR*} unur_hrb_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hrb_set_upperbound}
@deftypefn Function {int} unur_hrb_set_upperbound (UNUR_PAR* @var{parameters}, double @var{upperbound})
Set upper bound for hazard rate. If this call is not used it is
assumed that the the maximum of the hazard rate is achieved at the
left hand boundary of the domain of the distribution.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hrb_set_upperbound}
@deftypefn {} {int} unur_hrb_set_upperbound (UNUR_PAR* @var{parameters}, double @var{upperbound})
Set upper bound for hazard rate. If this call is not used it is
assumed that the the maximum of the hazard rate is achieved at the
left hand boundary of the domain of the distribution.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hrb_set_verify}
@anchor{funct:unur_hrb_chg_verify}
@deftypefn Function {int} unur_hrb_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx Function {int} unur_hrb_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the hazard rate is not bounded by the given bound, then
@code{unur_errno} is set to @code{UNUR_ERR_GEN_CONDITION}.

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hrb_set_verify}
@anchor{funct:unur_hrb_chg_verify}
@deftypefn {} {int} unur_hrb_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx {} {int} unur_hrb_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the hazard rate is not bounded by the given bound, then
@code{unur_errno} is set to @code{UNUR_ERR_GEN_CONDITION}.

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo




@c
@c end of hrb.h
@c -------------------------------------
@c -------------------------------------
@c hrd.h
@c

@page
@node HRD
@subsection   HRD  --  Hazard Rate Decreasing

@table @i
@item Required:
decreasing (non-increasing) hazard rate
@item Speed:
Set-up: fast, Sampling: slow
@item Reinit:
supported
@item Reference:
@ifhtml
@ref{bib:HLD04,, [HLD04: Sect.9.1.5; Alg.9.5]}
@end ifhtml
@ifnothtml
[HLD04: Sect.9.1.5; Alg.9.5]
@end ifnothtml

@end table


Generates random variate with given non-increasing hazard rate.
It is necessary that the distribution object contains this
hazard rate. Decreasing hazard rate implies that the
corresponding PDF of the distribution has heavier tails than the
exponential distribution (which has constant hazard rate).


@subsubheading How To Use


HRD requires a hazard function for a continuous distribution
with non-increasing hazard rate. There are no parameters for
this method.

It is important to note that the domain of the distribution can
be set via a
@ifhtml
@ref{funct:unur_distr_cont_set_domain,@command{unur_distr_cont_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_domain}
@end ifnothtml
call. However, only
the left hand boundary is used. For computational reasons the
right hand boundary is always reset to @code{UNUR_INFINITY}.
If no domain is given by the user then the left hand boundary is
set to @code{0}.

For distributions which do not have decreasing hazard rates but
are bounded from above use method HRB
(@pxref{HRB,,Hazard Rate Bounded}).
For distributions with increasing hazard rate method HRI
(@pxref{HRI,,Hazard Rate Increasing}) is required.

It is possible to change the parameters and the domain of the chosen
distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator object.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_hrd_new,unur_hrd_new}
@item @ref{funct:unur_hrd_set_verify,unur_hrd_set_verify}
@item @ref{funct:unur_hrd_chg_verify,unur_hrd_chg_verify}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_hrd_new}
@deftypefn Function {UNUR_PAR*} unur_hrd_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hrd_new}
@deftypefn {} {UNUR_PAR*} unur_hrd_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hrd_set_verify}
@anchor{funct:unur_hrd_chg_verify}
@deftypefn Function {int} unur_hrd_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx Function {int} unur_hrd_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the hazard rate is not bounded by the given bound, then
@code{unur_errno} is set to @code{UNUR_ERR_GEN_CONDITION}.

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hrd_set_verify}
@anchor{funct:unur_hrd_chg_verify}
@deftypefn {} {int} unur_hrd_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx {} {int} unur_hrd_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the hazard rate is not bounded by the given bound, then
@code{unur_errno} is set to @code{UNUR_ERR_GEN_CONDITION}.

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo




@c
@c end of hrd.h
@c -------------------------------------
@c -------------------------------------
@c hri.h
@c

@page
@node HRI
@subsection   HRI  --  Hazard Rate Increasing

@table @i
@item Required:
increasing (non-decreasing) hazard rate
@item Speed:
Set-up: fast, Sampling: slow
@item Reinit:
supported
@item Reference:
@ifhtml
@ref{bib:HLD04,, [HLD04: Sect.9.1.6; Alg.9.6]}
@end ifhtml
@ifnothtml
[HLD04: Sect.9.1.6; Alg.9.6]
@end ifnothtml

@end table


Generates random variate with given non-increasing hazard rate.
It is necessary that the distribution object contains this hazard rate.
Increasing hazard rate implies that the corresponding PDF of the
distribution has heavier tails than the exponential distribution
(which has constant hazard rate).

The method uses a decomposition of the hazard rate into a main
part which is constant for all @i{x} beyond some point @i{p0}
and a remaining part. From both of these parts points are
sampled using the thinning method and the minimum of both is
returned. Sampling from the first part is easier as we have a
constant dominating hazard rate. Thus @i{p0} should be large. On
the other hand, if @i{p0} is large than the thinning algorithm
needs many iteration. Thus the performance of the the algorithm
deponds on the choice of @i{p0}. We found that values close to
the expectation of the generated distribution result in good
performance.


@subsubheading How To Use


HRI requires a hazard function for a continuous distribution
with non-decreasing hazard rate.
The parameter @i{p0} should be set to a value close to the
expectation of the required distribution using
@ifhtml
@ref{funct:unur_hri_set_p0,@command{unur_hri_set_p0}.}
@end ifhtml
@ifnothtml
@command{unur_hri_set_p0}.
@end ifnothtml
If performance is crucial one may try other
values as well.

It is important to note that the domain of the distribution can
be set via a
@ifhtml
@ref{funct:unur_distr_cont_set_domain,@command{unur_distr_cont_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_domain}
@end ifnothtml
call. However, only
the left hand boundary is used. For computational reasons the
right hand boundary is always reset to @code{UNUR_INFINITY}.
If no domain is given by the user then the left hand boundary is
set to @code{0}.

For distributions with decreasing hazard rate method HRD
(@pxref{HRI,,Hazard Rate Decreasing}) is required.
For distributions which do not have increasing or decreasing
hazard rates but are bounded from above use method HRB
(@pxref{HRB,,Hazard Rate Bounded}).

It is possible to change the parameters and the domain of the chosen
distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator object.


Notice, that the upper bound given by the
@ifhtml
@ref{funct:unur_hrb_set_upperbound,@command{unur_hrb_set_upperbound}}
@end ifhtml
@ifnothtml
@command{unur_hrb_set_upperbound}
@end ifnothtml
call
cannot be changed and must be valid for the changed distribution.
Notice that the parameter @i{p0} which has been set by a
@ifhtml
@ref{funct:unur_hri_set_p0,@command{unur_hri_set_p0}}
@end ifhtml
@ifnothtml
@command{unur_hri_set_p0}
@end ifnothtml
call cannot be changed and must be valid for the changed distribution.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_hri_new,unur_hri_new}
@item @ref{funct:unur_hri_set_p0,unur_hri_set_p0}
@item @ref{funct:unur_hri_set_verify,unur_hri_set_verify}
@item @ref{funct:unur_hri_chg_verify,unur_hri_chg_verify}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_hri_new}
@deftypefn Function {UNUR_PAR*} unur_hri_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hri_new}
@deftypefn {} {UNUR_PAR*} unur_hri_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hri_set_p0}
@deftypefn Function {int} unur_hri_set_p0 (UNUR_PAR* @var{parameters}, double @var{p0})
Set design point for algorithm. It is used to split the domain of the
distribution. Values for @var{p0} close to the expectation of the
distribution results in a relatively good performance of the algorithm.
It is important that the hazard rate at this point must be greater
than @code{0} and less than @code{UNUR_INFINITY}.

Default: left boundary of domain + @code{1.}
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hri_set_p0}
@deftypefn {} {int} unur_hri_set_p0 (UNUR_PAR* @var{parameters}, double @var{p0})
Set design point for algorithm. It is used to split the domain of the
distribution. Values for @var{p0} close to the expectation of the
distribution results in a relatively good performance of the algorithm.
It is important that the hazard rate at this point must be greater
than @code{0} and less than @code{UNUR_INFINITY}.

Default: left boundary of domain + @code{1.}
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hri_set_verify}
@anchor{funct:unur_hri_chg_verify}
@deftypefn Function {int} unur_hri_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx Function {int} unur_hri_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the hazard rate is not bounded by the given bound, then
@code{unur_errno} is set to @code{UNUR_ERR_GEN_CONDITION}.

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hri_set_verify}
@anchor{funct:unur_hri_chg_verify}
@deftypefn {} {int} unur_hri_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx {} {int} unur_hri_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the hazard rate is not bounded by the given bound, then
@code{unur_errno} is set to @code{UNUR_ERR_GEN_CONDITION}.

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo




@c
@c end of hri.h
@c -------------------------------------
@c -------------------------------------
@c itdr.h
@c

@page
@node ITDR
@subsection   ITDR  --  Inverse Transformed Density Rejection

@table @i
@item Required:
monotone PDF, dPDF, pole
@item Optional:
splitting point between pole and tail region, c-values
@item Speed:
Set-up: moderate, Sampling: moderate
@item Reinit:
supported
@item Reference:
@ifhtml
@ref{bib:HLDa07,, [HLDa07]}
@end ifhtml
@ifnothtml
[HLDa07]
@end ifnothtml

@end table


ITDR is an acceptance/rejection method that works for monotone
densities. It is especially designed for PDFs with a single
pole. It uses different hat functions for the pole region and
for the tail region. For the tail region @emph{Transformed Density
Rejection} with a single construction point is used.
For the pole region a variant called @emph{Inverse Transformed
Density Rejection} is used. The optimal splitting point between
the two regions and the respective maximum local concavity and
inverse local concavity (@pxref{Glossary}) that guarantee valid
hat functions for each regions are estimated.
This splitting point is set to the intersection point of local
concavity and inverse local concavity.
However, it is assumed that both, the local concavity and the
inverse local concavity do not have a local minimum in the
interior of the domain (which is the case for all standard
distributions with a single pole).
In other cases (or when the built-in search routines do not
compute non-optimal values) one can provide the splitting point,
and the @i{c}-values.


@subsubheading How To Use


Method ITDR requires a distribution object with given PDF
and its derivative and the location of the pole (or mode).
The PDF must be monotone and may contain a pole.
It must be set via the
@ifhtml
@ref{funct:unur_distr_cont_set_pdf,@command{unur_distr_cont_set_pdf}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_pdf}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_distr_cont_set_dpdf,@command{unur_distr_cont_set_dpdf}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_dpdf}
@end ifnothtml
calls. The PDF should return
UNUR_INFINITY for the pole. Alternatively, one can also
set the logarithm of the PDF and its derivative via the
@ifhtml
@ref{funct:unur_distr_cont_set_logpdf,@command{unur_distr_cont_set_logpdf}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_logpdf}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_distr_cont_set_dlogpdf,@command{unur_distr_cont_set_dlogpdf}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_dlogpdf}
@end ifnothtml
calls. This is in especially useful since then the setup and
search routines are numerically more stable. Moreover, for many
distributions computing the logarithm of the PDF is less
expensive then computing the PDF directly.

The pole of the distribution is given by a
@ifhtml
@ref{funct:unur_distr_cont_set_mode,@command{unur_distr_cont_set_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_mode}
@end ifnothtml
call. Notice that distributions with
``heavy'' poles may have numerical problems caused by the
resultion of the floating point numbers used by computers.
While the minimal distance between two different floating point
numbers is about @code{1.e-320} near @code{0.} it increases
to @code{1.e-16} near @code{1.} Thus any random variate
generator implemented on a digital computer in fact draws samples
from a discrete distribution that approximates the desired
continuous distribution. For distributions with ``heavy'' poles
not at 0 this approximation may be too crude and thus every
goodness-of-fit test will fail.
Besides this theoretic problem that cannot be resolved we
have to take into consideration that round-off errors occur more
frequently when we have PDFs with poles far away from
@code{0.} Method ITDR tries to handles this situation as good as
possible by moving the pole into @code{0.}
Thus do not use a wrapper for your PDF that hides this shift
since the information about the resolution of the floating point
numbers near the pole gets lost.

Method ITDR uses different hats for the pole region and for the
tail region. The splitting point between these two regions, the
optimal @i{c}-value and design points for constructing the hats
using Transformed Density Rejection are computed automatically.
(The results of these computations can be read using the
respective calls
@ifhtml
@ref{funct:unur_itdr_get_xi,@command{unur_itdr_get_xi},}
@end ifhtml
@ifnothtml
@command{unur_itdr_get_xi},
@end ifnothtml
@ifhtml
@ref{funct:unur_itdr_get_cp,@command{unur_itdr_get_cp}}
@end ifhtml
@ifnothtml
@command{unur_itdr_get_cp}
@end ifnothtml
, and
@ifhtml
@ref{funct:unur_itdr_get_ct,@command{unur_itdr_get_ct}}
@end ifhtml
@ifnothtml
@command{unur_itdr_get_ct}
@end ifnothtml
for the intersection point between local
concavity and inverse local concavity, the @i{c}-value for the
pole and the tail region.)
However, one can also analyze the local concavity and inverse
local concavity set the corresponding values using
@ifhtml
@ref{funct:unur_itdr_set_xi,@command{unur_itdr_set_xi},}
@end ifhtml
@ifnothtml
@command{unur_itdr_set_xi},
@end ifnothtml
@ifhtml
@ref{funct:unur_itdr_set_cp,@command{unur_itdr_set_cp}}
@end ifhtml
@ifnothtml
@command{unur_itdr_set_cp}
@end ifnothtml
, and
@ifhtml
@ref{funct:unur_itdr_set_ct,@command{unur_itdr_set_ct}}
@end ifhtml
@ifnothtml
@command{unur_itdr_set_ct}
@end ifnothtml
calls.
Notice, that @i{c}-values greater than -1/2 can be set to
@code{-0.5}. Although this results in smaller acceptance
probabities sampling from the hat distribution is much faster
than for other values of @i{c}. Depending on the expenses of
evaluating the PDF the resulting algorithm is usually faster.

It is possible to change the parameters and the domain of the chosen
distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator object.
However, the values given by
@ifhtml
@ref{funct:unur_itdr_set_xi,@command{unur_itdr_set_xi},}
@end ifhtml
@ifnothtml
@command{unur_itdr_set_xi},
@end ifnothtml
@ifhtml
@ref{funct:unur_itdr_set_cp,@command{unur_itdr_set_cp}}
@end ifhtml
@ifnothtml
@command{unur_itdr_set_cp}
@end ifnothtml
,
or
@ifhtml
@ref{funct:unur_itdr_set_ct,@command{unur_itdr_set_ct}}
@end ifhtml
@ifnothtml
@command{unur_itdr_set_ct}
@end ifnothtml
calls are then ignored when
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
is
called.



@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_itdr_new,unur_itdr_new}
@item @ref{funct:unur_itdr_set_xi,unur_itdr_set_xi}
@item @ref{funct:unur_itdr_set_cp,unur_itdr_set_cp}
@item @ref{funct:unur_itdr_set_ct,unur_itdr_set_ct}
@item @ref{funct:unur_itdr_get_xi,unur_itdr_get_xi}
@item @ref{funct:unur_itdr_get_cp,unur_itdr_get_cp}
@item @ref{funct:unur_itdr_get_ct,unur_itdr_get_ct}
@item @ref{funct:unur_itdr_get_area,unur_itdr_get_area}
@item @ref{funct:unur_itdr_set_verify,unur_itdr_set_verify}
@item @ref{funct:unur_itdr_chg_verify,unur_itdr_chg_verify}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_itdr_new}
@deftypefn Function {UNUR_PAR*} unur_itdr_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_itdr_new}
@deftypefn {} {UNUR_PAR*} unur_itdr_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_itdr_set_xi}
@deftypefn Function {int} unur_itdr_set_xi (UNUR_PAR* @var{parameters}, double @var{xi})
Sets points where local concavity and inverse local concavity
are (almost) equal. It is used to estimate the respective c-values
for pole region and hat regions and to determine the splitting point @i{bx}
between pole and tail region.
If no such point is provided it will be computed automatically.

Default: not set.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_itdr_set_xi}
@deftypefn {} {int} unur_itdr_set_xi (UNUR_PAR* @var{parameters}, double @var{xi})
Sets points where local concavity and inverse local concavity
are (almost) equal. It is used to estimate the respective c-values
for pole region and hat regions and to determine the splitting point @i{bx}
between pole and tail region.
If no such point is provided it will be computed automatically.

Default: not set.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_itdr_set_cp}
@deftypefn Function {int} unur_itdr_set_cp (UNUR_PAR* @var{parameters}, double @var{cp})
Sets parameter @var{cp} for transformation T for inverse
density in pole region.
It must be at most 0 and greater than -1.
A value of @code{-0.5} is treated separately and usually results in
faster marginal generation time (at the expense of smaller
acceptance probabilities.
If no @var{cp}-value is given it is estimated automatically.

Default: not set.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_itdr_set_cp}
@deftypefn {} {int} unur_itdr_set_cp (UNUR_PAR* @var{parameters}, double @var{cp})
Sets parameter @var{cp} for transformation T for inverse
density in pole region.
It must be at most 0 and greater than -1.
A value of @code{-0.5} is treated separately and usually results in
faster marginal generation time (at the expense of smaller
acceptance probabilities.
If no @var{cp}-value is given it is estimated automatically.

Default: not set.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_itdr_set_ct}
@deftypefn Function {int} unur_itdr_set_ct (UNUR_PAR* @var{parameters}, double @var{ct})
Sets parameter @var{ct} for transformation T for
density in tail region.
It must be at most 0. For densities with unbounded domain
it must be greater than -1.
A value of @code{-0.5} is treated separately and usually results in
faster marginal generation time (at the expense of smaller
acceptance probabilities.
If no @var{ct}-value is given it is estimated automatically.

Default: not set.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_itdr_set_ct}
@deftypefn {} {int} unur_itdr_set_ct (UNUR_PAR* @var{parameters}, double @var{ct})
Sets parameter @var{ct} for transformation T for
density in tail region.
It must be at most 0. For densities with unbounded domain
it must be greater than -1.
A value of @code{-0.5} is treated separately and usually results in
faster marginal generation time (at the expense of smaller
acceptance probabilities.
If no @var{ct}-value is given it is estimated automatically.

Default: not set.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_itdr_get_xi}
@anchor{funct:unur_itdr_get_cp}
@anchor{funct:unur_itdr_get_ct}
@deftypefn Function {double} unur_itdr_get_xi (UNUR_GEN* @var{generator})
@deftypefnx Function {double} unur_itdr_get_cp (UNUR_GEN* @var{generator})
@deftypefnx Function {double} unur_itdr_get_ct (UNUR_GEN* @var{generator})
Get intersection point @var{xi}, and c-values @var{cp} and @var{ct},
respectively.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_itdr_get_xi}
@anchor{funct:unur_itdr_get_cp}
@anchor{funct:unur_itdr_get_ct}
@deftypefn {} {double} unur_itdr_get_xi (UNUR_GEN* @var{generator})
@deftypefnx {} {double} unur_itdr_get_cp (UNUR_GEN* @var{generator})
@deftypefnx {} {double} unur_itdr_get_ct (UNUR_GEN* @var{generator})
Get intersection point @var{xi}, and c-values @var{cp} and @var{ct},
respectively.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_itdr_get_area}
@deftypefn Function {double} unur_itdr_get_area (UNUR_GEN* @var{generator})
Get area below hat.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_itdr_get_area}
@deftypefn {} {double} unur_itdr_get_area (UNUR_GEN* @var{generator})
Get area below hat.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_itdr_set_verify}
@deftypefn Function {int} unur_itdr_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
Turn verifying of algorithm while sampling on/off.

If the condition
@math{PDF(x) <= hat(x)}
is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However, notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_itdr_set_verify}
@deftypefn {} {int} unur_itdr_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
Turn verifying of algorithm while sampling on/off.

If the condition
@iftex
@math{PDF(x) \leq hat(x)}
@end iftex
@ifhtml
@html
<I>PDF</I>(<I>x</I>) <= <I>hat</I>(<I>x</I>)
@end html
@end ifhtml
is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However, notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_itdr_chg_verify}
@deftypefn Function {int} unur_itdr_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Change the verifying of algorithm while sampling on/off.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_itdr_chg_verify}
@deftypefn {} {int} unur_itdr_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Change the verifying of algorithm while sampling on/off.
@end deftypefn
@end ifnotinfo




@c
@c end of itdr.h
@c -------------------------------------
@c -------------------------------------
@c ninv.h
@c

@page
@node NINV
@subsection   NINV  --  Numerical INVersion

@table @i
@item Required:
CDF
@item Optional:
PDF
@item Speed:
Set-up: optional, Sampling: (very) slow
@item Reinit:
supported
@end table


NINV implementations of some methods for numerical inversion:
Newton's method, regula falsi (combined with interval
bisectioning), and bisection method.
Regula falsi and bisection method require only the CDF while
Newton's method also requires the PDF.
To speed up marginal generation times a table with suitable
starting points can be created during the setup.
The performance of the algorithm can adjusted by the desired
accuracy of the method.
It is possible to use this method for generating from truncated
distributions. The truncated domain can be changed for an
existing generator object.


@subsubheading How To Use


Method NINV generates random variates by numerical
inversion and requires a continuous univariate distribution
objects with given CDF. Three variants are available:

@itemize @minus
@item Regula falsi  [default]
@item Newton's method
@item Interval bisectioning
@end itemize

Newton's method additionally requires the PDF of the
distribution and cannot be used otherwise (NINV automatically
switches to regula falsi then).
Default algorithm is regula falsi. It is slightly slower but
numerically much more stable than Newton's algorithm.
Interval bisectioning is the slowest method and should only be
considered as a last resort when the other methods fails.

It is possible to draw samples from truncated distributions.
The truncated domain can even be changed for an existing generator
object by an
@ifhtml
@ref{funct:unur_ninv_chg_truncated,@command{unur_ninv_chg_truncated}}
@end ifhtml
@ifnothtml
@command{unur_ninv_chg_truncated}
@end ifnothtml
call.

Marginal generation times can be sped up by means of a table
with suitable starting points which can be created during the
setup. Using such a table can be switched on by means of a
@ifhtml
@ref{funct:unur_ninv_set_table,@command{unur_ninv_set_table}}
@end ifhtml
@ifnothtml
@command{unur_ninv_set_table}
@end ifnothtml
call where the table size is given as a
parameter. The table is still useful when the (truncated) domain
is changed often, since it is computed for the
domain of the given distribution. (It is not possible to enlarge
this domain.) If it is necessary to recalculate the table during
sampling, the command
@ifhtml
@ref{funct:unur_ninv_chg_table,@command{unur_ninv_chg_table}}
@end ifhtml
@ifnothtml
@command{unur_ninv_chg_table}
@end ifnothtml
can be used.
As a rule of thumb using such a table is appropriate when the
number of generated points exceeds the table size by a factor of
100.

The default number of iterations of NINV should be enough for all
reasonable cases. Nevertheless, it is possible to adjust the maximal
number of iterations with the commands
@ifhtml
@ref{funct:unur_ninv_set_max_iter,@command{unur_ninv_set_max_iter}}
@end ifhtml
@ifnothtml
@command{unur_ninv_set_max_iter}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_ninv_chg_max_iter,@command{unur_ninv_chg_max_iter}.}
@end ifhtml
@ifnothtml
@command{unur_ninv_chg_max_iter}.
@end ifnothtml
In particular this might be necessary when the PDF has a pole or
the distribution has extremely heavy tails.

It is also possible to set/change the accuracy of the method
(which also heavily influencies the generation time).
We use two measures for the approximation error which can be
used independently: x-error and u-error
(@pxref{Inversion} for more details).
It is possible to set the maximal tolerated error using
with
@ifhtml
@ref{funct:unur_ninv_set_x_resolution,@command{unur_ninv_set_x_resolution}}
@end ifhtml
@ifnothtml
@command{unur_ninv_set_x_resolution}
@end ifnothtml
and
with
@ifhtml
@ref{funct:unur_ninv_set_u_resolution,@command{unur_ninv_set_u_resolution},}
@end ifhtml
@ifnothtml
@command{unur_ninv_set_u_resolution},
@end ifnothtml
resp., and change it with the
respective calls
@ifhtml
@ref{funct:unur_ninv_chg_x_resolution,@command{unur_ninv_chg_x_resolution}}
@end ifhtml
@ifnothtml
@command{unur_ninv_chg_x_resolution}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_ninv_chg_x_resolution,@command{unur_ninv_chg_x_resolution}.}
@end ifhtml
@ifnothtml
@command{unur_ninv_chg_x_resolution}.
@end ifnothtml
The algorithm tries to satisfy @emph{both} accuracy goals (and
raises an error flag it this fails).
One of these accuracy checks can be disabled by setting the
accuracy goal to a negative value.

NINV tries to use proper starting values for both the regula
falsi and bisection method, and for Newton's method. Of course
the user might have more knowledge about the properties of the
target distribution and is able to share his wisdom with NINV
using the respective commands
@ifhtml
@ref{funct:unur_ninv_set_start,@command{unur_ninv_set_start}}
@end ifhtml
@ifnothtml
@command{unur_ninv_set_start}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_ninv_chg_start,@command{unur_ninv_chg_start}.}
@end ifhtml
@ifnothtml
@command{unur_ninv_chg_start}.
@end ifnothtml
It is possible to change the parameters and the domain of the chosen
distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator object.
The values given by the last
@ifhtml
@ref{funct:unur_ninv_chg_truncated,@command{unur_ninv_chg_truncated}}
@end ifhtml
@ifnothtml
@command{unur_ninv_chg_truncated}
@end ifnothtml
call will be
then changed to the values of the domain of the underlying distribution
object. It is important to note that for a distribution from the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions})
the normalization constant has to be updated using the
@ifhtml
@ref{funct:unur_distr_cont_upd_pdfarea,@command{unur_distr_cont_upd_pdfarea}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_upd_pdfarea}
@end ifnothtml
call whenever its parameters have been
changed by means of a
@ifhtml
@ref{funct:unur_distr_cont_set_pdfparams,@command{unur_distr_cont_set_pdfparams}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_pdfparams}
@end ifnothtml
call.

It might happen that NINV aborts
@ifhtml
@ref{funct:unur_sample_cont,@command{unur_sample_cont}}
@end ifhtml
@ifnothtml
@command{unur_sample_cont}
@end ifnothtml
without
computing the correct value (because the maximal number
iterations has been exceeded). Then the last approximate value
for @i{x} is returned (with might be fairly false) and
@code{unur_error} is set to @code{UNUR_ERR_GEN_SAMPLING}.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_ninv_new,unur_ninv_new}
@item @ref{funct:unur_ninv_set_useregula,unur_ninv_set_useregula}
@item @ref{funct:unur_ninv_set_usenewton,unur_ninv_set_usenewton}
@item @ref{funct:unur_ninv_set_usebisect,unur_ninv_set_usebisect}
@item @ref{funct:unur_ninv_set_max_iter,unur_ninv_set_max_iter}
@item @ref{funct:unur_ninv_chg_max_iter,unur_ninv_chg_max_iter}
@item @ref{funct:unur_ninv_set_x_resolution,unur_ninv_set_x_resolution}
@item @ref{funct:unur_ninv_chg_x_resolution,unur_ninv_chg_x_resolution}
@item @ref{funct:unur_ninv_set_u_resolution,unur_ninv_set_u_resolution}
@item @ref{funct:unur_ninv_chg_u_resolution,unur_ninv_chg_u_resolution}
@item @ref{funct:unur_ninv_set_start,unur_ninv_set_start}
@item @ref{funct:unur_ninv_chg_start,unur_ninv_chg_start}
@item @ref{funct:unur_ninv_set_table,unur_ninv_set_table}
@item @ref{funct:unur_ninv_chg_table,unur_ninv_chg_table}
@item @ref{funct:unur_ninv_chg_truncated,unur_ninv_chg_truncated}
@item @ref{funct:unur_ninv_eval_approxinvcdf,unur_ninv_eval_approxinvcdf}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_ninv_new}
@deftypefn Function {UNUR_PAR*} unur_ninv_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ninv_new}
@deftypefn {} {UNUR_PAR*} unur_ninv_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ninv_set_useregula}
@deftypefn Function {int} unur_ninv_set_useregula (UNUR_PAR* @var{parameters})
Switch to regula falsi combined with interval bisectioning.
(This the default.)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ninv_set_useregula}
@deftypefn {} {int} unur_ninv_set_useregula (UNUR_PAR* @var{parameters})
Switch to regula falsi combined with interval bisectioning.
(This the default.)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ninv_set_usenewton}
@deftypefn Function {int} unur_ninv_set_usenewton (UNUR_PAR* @var{parameters})
Switch to Newton's method.
Notice that it is numerically less stable than regula falsi.
It it is not possible to invert the CDF for a particular uniform random
number @i{U} when calling
@ifhtml
@ref{funct:unur_sample_cont,@command{unur_sample_cont},}
@end ifhtml
@ifnothtml
@command{unur_sample_cont},
@end ifnothtml
@code{unur_error} is set
to @code{UNUR_ERR_GEN_SAMPLING}.
Thus it is recommended to check @code{unur_error} before
using the result of the sampling routine.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ninv_set_usenewton}
@deftypefn {} {int} unur_ninv_set_usenewton (UNUR_PAR* @var{parameters})
Switch to Newton's method.
Notice that it is numerically less stable than regula falsi.
It it is not possible to invert the CDF for a particular uniform random
number @i{U} when calling
@ifhtml
@ref{funct:unur_sample_cont,@command{unur_sample_cont},}
@end ifhtml
@ifnothtml
@command{unur_sample_cont},
@end ifnothtml
@code{unur_error} is set
to @code{UNUR_ERR_GEN_SAMPLING}.
Thus it is recommended to check @code{unur_error} before
using the result of the sampling routine.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ninv_set_usebisect}
@deftypefn Function {int} unur_ninv_set_usebisect (UNUR_PAR* @var{parameters})
Switch to bisection method. This is a slow algorithm and should
only be used as a last resort.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ninv_set_usebisect}
@deftypefn {} {int} unur_ninv_set_usebisect (UNUR_PAR* @var{parameters})
Switch to bisection method. This is a slow algorithm and should
only be used as a last resort.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ninv_set_max_iter}
@anchor{funct:unur_ninv_chg_max_iter}
@deftypefn Function {int} unur_ninv_set_max_iter (UNUR_PAR* @var{parameters}, int @var{max_iter})
@deftypefnx Function {int} unur_ninv_chg_max_iter (UNUR_GEN* @var{generator}, int @var{max_iter})
Set and change number of maximal iterations.
Default is @code{100}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ninv_set_max_iter}
@anchor{funct:unur_ninv_chg_max_iter}
@deftypefn {} {int} unur_ninv_set_max_iter (UNUR_PAR* @var{parameters}, int @var{max_iter})
@deftypefnx {} {int} unur_ninv_chg_max_iter (UNUR_GEN* @var{generator}, int @var{max_iter})
Set and change number of maximal iterations.
Default is @code{100}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ninv_set_x_resolution}
@anchor{funct:unur_ninv_chg_x_resolution}
@deftypefn Function {int} unur_ninv_set_x_resolution (UNUR_PAR* @var{parameters}, double @var{x_resolution})
@deftypefnx Function {int} unur_ninv_chg_x_resolution (UNUR_GEN* @var{generator}, double @var{x_resolution})
Set and change the maximal tolerated relative x-error.
If @var{x_resolution} is negative then checking of the x-error is
disabled.

Default is @code{1.e-8}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ninv_set_x_resolution}
@anchor{funct:unur_ninv_chg_x_resolution}
@deftypefn {} {int} unur_ninv_set_x_resolution (UNUR_PAR* @var{parameters}, double @var{x_resolution})
@deftypefnx {} {int} unur_ninv_chg_x_resolution (UNUR_GEN* @var{generator}, double @var{x_resolution})
Set and change the maximal tolerated relative x-error.
If @var{x_resolution} is negative then checking of the x-error is
disabled.

Default is @code{1.e-8}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ninv_set_u_resolution}
@anchor{funct:unur_ninv_chg_u_resolution}
@deftypefn Function {int} unur_ninv_set_u_resolution (UNUR_PAR* @var{parameters}, double @var{u_resolution})
@deftypefnx Function {int} unur_ninv_chg_u_resolution (UNUR_GEN* @var{generator}, double @var{u_resolution})
Set and change the maximal tolerated (abolute) u-error.
If @var{u_resolution} is negative then checking of the u-error is
disabled.

Default is @code{-1} (disabled).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ninv_set_u_resolution}
@anchor{funct:unur_ninv_chg_u_resolution}
@deftypefn {} {int} unur_ninv_set_u_resolution (UNUR_PAR* @var{parameters}, double @var{u_resolution})
@deftypefnx {} {int} unur_ninv_chg_u_resolution (UNUR_GEN* @var{generator}, double @var{u_resolution})
Set and change the maximal tolerated (abolute) u-error.
If @var{u_resolution} is negative then checking of the u-error is
disabled.

Default is @code{-1} (disabled).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ninv_set_start}
@deftypefn Function {int} unur_ninv_set_start (UNUR_PAR* @var{parameters}, double @var{left}, double @var{right})
Set starting points.
If not set, suitable values are chosen automatically.

@multitable @columnfractions 0.2 0.2 0.6
@item Newton:       @tab @var{left}:              @tab starting point
@item Regula falsi: @tab @var{left}, @var{right}: @tab boundary of starting interval
@end multitable

If the starting points are not set then the follwing points are used by
default:
@multitable @columnfractions 0.2 0.2 0.6
@item Newton:       @tab @var{left}:  @tab CDF(@var{left}) = 0.5
@item Regula falsi: @tab @var{left}:  @tab CDF(@var{left}) = 0.1
@item               @tab @var{right}: @tab CDF(@var{right}) = 0.9
@end multitable

If @var{left} == @var{right}, then  UNU.RAN always uses the default
starting points!
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ninv_set_start}
@deftypefn {} {int} unur_ninv_set_start (UNUR_PAR* @var{parameters}, double @var{left}, double @var{right})
Set starting points.
If not set, suitable values are chosen automatically.

@multitable @columnfractions 0.2 0.2 0.6
@item Newton:       @tab @var{left}:              @tab starting point
@item Regula falsi: @tab @var{left}, @var{right}: @tab boundary of starting interval
@end multitable

If the starting points are not set then the follwing points are used by
default:
@multitable @columnfractions 0.2 0.2 0.6
@item Newton:       @tab @var{left}:  @tab CDF(@var{left}) = 0.5
@item Regula falsi: @tab @var{left}:  @tab CDF(@var{left}) = 0.1
@item               @tab @var{right}: @tab CDF(@var{right}) = 0.9
@end multitable

If @var{left} == @var{right}, then  UNU.RAN always uses the default
starting points!
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ninv_chg_start}
@deftypefn Function {int} unur_ninv_chg_start (UNUR_GEN* @var{gen}, double @var{left}, double @var{right})
Change the starting points for numerical inversion.
If left==right, then UNU.RAN uses the default starting points
(see
@ifhtml
@ref{funct:unur_ninv_set_start,@command{unur_ninv_set_start}}
@end ifhtml
@ifnothtml
@command{unur_ninv_set_start}
@end ifnothtml
).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ninv_chg_start}
@deftypefn {} {int} unur_ninv_chg_start (UNUR_GEN* @var{gen}, double @var{left}, double @var{right})
Change the starting points for numerical inversion.
If left==right, then UNU.RAN uses the default starting points
(see
@ifhtml
@ref{funct:unur_ninv_set_start,@command{unur_ninv_set_start}}
@end ifhtml
@ifnothtml
@command{unur_ninv_set_start}
@end ifnothtml
).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ninv_set_table}
@deftypefn Function {int} unur_ninv_set_table (UNUR_PAR* @var{parameters}, int @var{no_of_points})
Generates a table with @var{no_of_points} points containing
suitable starting values for the iteration. The value of
@var{no_of_points} must be at least 10 (otherwise it will be set
to 10 automatically).

The table points are chosen such that the CDF at these points
form an equidistance sequence in the interval (0,1).

If a table is used, then the starting points given by
@ifhtml
@ref{funct:unur_ninv_set_start,@command{unur_ninv_set_start}}
@end ifhtml
@ifnothtml
@command{unur_ninv_set_start}
@end ifnothtml
are ignored.

No table is used by default.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ninv_set_table}
@deftypefn {} {int} unur_ninv_set_table (UNUR_PAR* @var{parameters}, int @var{no_of_points})
Generates a table with @var{no_of_points} points containing
suitable starting values for the iteration. The value of
@var{no_of_points} must be at least 10 (otherwise it will be set
to 10 automatically).

The table points are chosen such that the CDF at these points
form an equidistance sequence in the interval (0,1).

If a table is used, then the starting points given by
@ifhtml
@ref{funct:unur_ninv_set_start,@command{unur_ninv_set_start}}
@end ifhtml
@ifnothtml
@command{unur_ninv_set_start}
@end ifnothtml
are ignored.

No table is used by default.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ninv_chg_table}
@deftypefn Function {int} unur_ninv_chg_table (UNUR_GEN* @var{gen}, int @var{no_of_points})
Recomputes a table as described in
@ifhtml
@ref{funct:unur_ninv_set_table,@command{unur_ninv_set_table}.}
@end ifhtml
@ifnothtml
@command{unur_ninv_set_table}.
@end ifnothtml
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ninv_chg_table}
@deftypefn {} {int} unur_ninv_chg_table (UNUR_GEN* @var{gen}, int @var{no_of_points})
Recomputes a table as described in
@ifhtml
@ref{funct:unur_ninv_set_table,@command{unur_ninv_set_table}.}
@end ifhtml
@ifnothtml
@command{unur_ninv_set_table}.
@end ifnothtml
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ninv_chg_truncated}
@deftypefn Function {int} unur_ninv_chg_truncated (UNUR_GEN* @var{gen}, double @var{left}, double @var{right})
Changes the borders of the domain of the (truncated) distribution.

Notice that the given truncated domain must be a subset of the
domain of the given distribution. The generator always uses the
intersection of the domain of the distribution and the truncated
domain given by this call.
Moreover the starting point(s) will not be changed.

@emph{Important:} If the CDF is (almost) the same for @var{left} and
@var{right} and (almost) equal to @code{0} or @code{1}, then the truncated
domain is @emph{not} chanced and the call returns an error code.

@emph{Notice:} If the parameters of the distribution has been changed by a
@ifhtml
@ref{funct:unur_distr_cont_set_pdfparams,@command{unur_distr_cont_set_pdfparams}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_pdfparams}
@end ifnothtml
call it is recommended to set the
truncated domain again, since the former call might change the
domain of the distribution but not update the values for the
boundaries of the truncated distribution.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ninv_chg_truncated}
@deftypefn {} {int} unur_ninv_chg_truncated (UNUR_GEN* @var{gen}, double @var{left}, double @var{right})
Changes the borders of the domain of the (truncated) distribution.

Notice that the given truncated domain must be a subset of the
domain of the given distribution. The generator always uses the
intersection of the domain of the distribution and the truncated
domain given by this call.
Moreover the starting point(s) will not be changed.

@emph{Important:} If the CDF is (almost) the same for @var{left} and
@var{right} and (almost) equal to @code{0} or @code{1}, then the truncated
domain is @emph{not} chanced and the call returns an error code.

@emph{Notice:} If the parameters of the distribution has been changed by a
@ifhtml
@ref{funct:unur_distr_cont_set_pdfparams,@command{unur_distr_cont_set_pdfparams}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_pdfparams}
@end ifnothtml
call it is recommended to set the
truncated domain again, since the former call might change the
domain of the distribution but not update the values for the
boundaries of the truncated distribution.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ninv_eval_approxinvcdf}
@deftypefn Function {double} unur_ninv_eval_approxinvcdf (const @var{UNUR_GEN* generator}, double @var{u})
Get approximate approximate value of inverse CDF at @var{u}.
If @var{u} is out of the domain [0,1] then @code{unur_errno} is set
to @code{UNUR_ERR_DOMAIN} and the respective bound of
the domain of the distribution are returned (which is
@code{-UNUR_INFINITY} or @code{UNUR_INFINITY} in the case of
unbounded domains).

@emph{Notice}: This function always evaluates the inverse CDF of
the given distribution. A call to
@ifhtml
@ref{funct:unur_ninv_chg_truncated,@command{unur_ninv_chg_truncated}}
@end ifhtml
@ifnothtml
@command{unur_ninv_chg_truncated}
@end ifnothtml
call
has no effect.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ninv_eval_approxinvcdf}
@deftypefn {} {double} unur_ninv_eval_approxinvcdf (const @var{UNUR_GEN* generator}, double @var{u})
Get approximate approximate value of inverse CDF at @var{u}.
If @var{u} is out of the domain [0,1] then @code{unur_errno} is set
to @code{UNUR_ERR_DOMAIN} and the respective bound of
the domain of the distribution are returned (which is
@code{-UNUR_INFINITY} or @code{UNUR_INFINITY} in the case of
unbounded domains).

@emph{Notice}: This function always evaluates the inverse CDF of
the given distribution. A call to
@ifhtml
@ref{funct:unur_ninv_chg_truncated,@command{unur_ninv_chg_truncated}}
@end ifhtml
@ifnothtml
@command{unur_ninv_chg_truncated}
@end ifnothtml
call
has no effect.
@end deftypefn
@end ifnotinfo




@c
@c end of ninv.h
@c -------------------------------------
@c -------------------------------------
@c nrou.h
@c

@page
@node NROU
@subsection   NROU  --  Naive Ratio-Of-Uniforms method

@table @i
@item Required:
PDF
@item Optional:
mode, center, bounding rectangle for acceptance region
@item Speed:
Set-up: slow or fast, Sampling: moderate
@item Reinit:
supported
@item Reference:
@ifhtml
@ref{bib:HLD04,, [HLD04: Sect.2.4 and Sect.6.4]}
@end ifhtml
@ifnothtml
[HLD04: Sect.2.4 and Sect.6.4]
@end ifnothtml

@end table


NROU is an implementation of the (generalized) ratio-of-uniforms
method which uses (minimal) bounding rectangles, see
@ref{Ratio-of-Uniforms}. It uses a positive control parameter
@i{r} for adjusting the algorithm to the given distribution to
improve performance and/or to make this method applicable.
Larger values of @i{r} increase the class of distributions
for which the method works at the expense of a higher rejection
constant. For computational reasons @i{r=1} should be used if
possible (this is the default).
Moreover, this implementation uses the center
@iftex
@math{\mu}
@end iftex
@ifhtml
@html
mu
@end html
@end ifhtml
@ifinfo
@math{mu}
@end ifinfo
of
the distribution (see
@ifhtml
@ref{funct:unur_distr_cont_get_center,@command{unur_distr_cont_get_center}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_get_center}
@end ifnothtml
for
details of its default values).

For the special case with
@iftex
@math{r=1}
@end iftex
@ifhtml
@html
<I>r</I>=1
@end html
@end ifhtml
@ifinfo
@math{r=1}
@end ifinfo
the coordinates of the
minimal bounding rectangles are given by
@iftex

@quotation
@math{ v^+ = \sup\limits_{x} \sqrt{PDF(x)}, \hfil\break u^- = \inf\limits_{x} (x-\mu) \sqrt{PDF(x)}, \hfil\break u^+ = \sup\limits_{x} (x-\mu) \sqrt{PDF(x)}, }
@end quotation

@end iftex
@ifhtml
@quotation
@html
<I>v</I><SUP>+</SUP> = sup_<I>x</I> sqrt(<I>PDF</I>(<I>x</I>)), @*<I>u</I><SUP>-</SUP> = inf_<I>x</I> (<I>x</I>- mu) sqrt(<I>PDF</I>(<I>x</I>)), @*<I>u</I><SUP>+</SUP> = sup_<I>x</I> (<I>x</I>- mu) sqrt(<I>PDF</I>(<I>x</I>)),
@end html
@end quotation
@end ifhtml
@ifinfo
@quotation
@math{v^+ = sup_(x) sqrt(PDF(x)), @*u^- = inf_(x) (x- mu) sqrt(PDF(x)), @*u^+ = sup_(x) (x- mu) sqrt(PDF(x)),}
@end quotation
@end ifinfo

@noindent
where
@iftex
@math{\mu}
@end iftex
@ifhtml
@html
mu
@end html
@end ifhtml
@ifinfo
@math{mu}
@end ifinfo
is the center of the distribution.
For other values of @i{r} we have
@iftex

@quotation
@math{ v^+ = \sup\limits_{x} (PDF(x))^{1/(r+1)}, \hfil\break u^- = \inf\limits_{x} (x-\mu) (PDF(x))^{r/(r+1)}, \hfil\break u^+ = \sup\limits_{x} (x-\mu) (PDF(x))^{r/(r+1)}. }
@end quotation

@end iftex
@ifhtml
@quotation
@html
<I>v</I><SUP>+</SUP> = sup_<I>x</I> (<I>PDF</I>(<I>x</I>))<SUP>1/(<I>r</I>+1)</SUP>, @*<I>u</I><SUP>-</SUP> = inf_<I>x</I> (<I>x</I>- mu) (<I>PDF</I>(<I>x</I>))<SUP><I>r</I>/(<I>r</I>+1)</SUP>, @*<I>u</I><SUP>+</SUP> = sup_<I>x</I> (<I>x</I>- mu) (<I>PDF</I>(<I>x</I>))<SUP><I>r</I>/(<I>r</I>+1)</SUP>.
@end html
@end quotation
@end ifhtml
@ifinfo
@quotation
@math{v^+ = sup_(x) (PDF(x))^(1/(r+1)), @*u^- = inf_(x) (x- mu) (PDF(x))^(r/(r+1)), @*u^+ = sup_(x) (x- mu) (PDF(x))^(r/(r+1)).}
@end quotation
@end ifinfo

@noindent
These bounds can be given directly. Otherwise they are computed
automatically by means of a (slow) numerical routine.
Of course this routine can fail, especially when this rectangle
is not bounded.

It is important to note that the algorithm works with
@iftex
@math{PDF(x-\mu)}
@end iftex
@ifhtml
@html
<I>PDF</I>(<I>x</I>- mu)
@end html
@end ifhtml
@ifinfo
@math{PDF(x- mu)}
@end ifinfo
instead of
@iftex
@math{PDF(x).}
@end iftex
@ifhtml
@html
<I>PDF</I>(<I>x</I>).
@end html
@end ifhtml
@ifinfo
@math{PDF(x).}
@end ifinfo
This is important as otherwise the acceptance region can become
a very long and skinny ellipsoid along a diagonal of the (huge)
bounding rectangle.


@subsubheading How To Use


For using the NROU method UNU.RAN needs the PDF of the
distribution. Additionally, the parameter @i{r} can be set via
a
@ifhtml
@ref{funct:unur_vnrou_set_r,@command{unur_vnrou_set_r}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_r}
@end ifnothtml
call. Notice that the acceptance
probability decreases when @i{r} is increased. On the other
hand is is more unlikely that the bounding rectangle does not
exist if @i{r} is small.

A bounding rectangle can be given by the
@ifhtml
@ref{funct:unur_vnrou_set_u,@command{unur_vnrou_set_u}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_u}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_vnrou_set_v,@command{unur_vnrou_set_v}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_v}
@end ifnothtml
calls.

@emph{Important:} The bounding rectangle has to be
provided for the function
@iftex
@math{PDF(x-center)!}
@end iftex
@ifhtml
@html
<I>PDF</I>(<I>x</I>-<I>center</I>)!
@end html
@end ifhtml
@ifinfo
@math{PDF(x-center)!}
@end ifinfo
Notice that @code{center} is the center of the given
distribution, see
@ifhtml
@ref{funct:unur_distr_cont_set_center,@command{unur_distr_cont_set_center}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_center}.
@end ifnothtml
If in doubt or if this value is not optimal, it can be changed
(overridden) by a
@ifhtml
@ref{funct:unur_nrou_set_center,@command{unur_nrou_set_center}}
@end ifhtml
@ifnothtml
@command{unur_nrou_set_center}
@end ifnothtml
call.

If the coordinates of the bounding rectangle are not provided by
the user then the minimal bounding rectangle is computed
automatically.

By means of
@ifhtml
@ref{funct:unur_vnrou_set_verify,@command{unur_vnrou_set_verify}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_verify}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_vnrou_chg_verify,@command{unur_vnrou_chg_verify}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_chg_verify}
@end ifnothtml
one can run the sampling algorithm in a checking mode, i.e., in
every cycle of the rejection loop it is checked whether the used
rectangle indeed enclosed the acceptance region of the
distribution. When in doubt (e.g., when it is not clear whether
the numerical routine has worked correctly) this can be used to
run a small Monte Carlo study.

It is possible to change the parameters and the domain of the chosen
distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator object.
Notice, that derived parameters like the mode must also be (re-) set
if the parameters or the domain has be changed.
Notice, however, that then the values that has been set by
@ifhtml
@ref{funct:unur_vnrou_set_u,@command{unur_vnrou_set_u}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_u}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_vnrou_set_v,@command{unur_vnrou_set_v}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_v}
@end ifnothtml
calls are removed and
the coordinates of the bounding box are computed numerically.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_nrou_new,unur_nrou_new}
@item @ref{funct:unur_nrou_set_u,unur_nrou_set_u}
@item @ref{funct:unur_nrou_set_v,unur_nrou_set_v}
@item @ref{funct:unur_nrou_set_r,unur_nrou_set_r}
@item @ref{funct:unur_nrou_set_center,unur_nrou_set_center}
@item @ref{funct:unur_nrou_set_verify,unur_nrou_set_verify}
@item @ref{funct:unur_nrou_chg_verify,unur_nrou_chg_verify}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_nrou_new}
@deftypefn Function {UNUR_PAR*} unur_nrou_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_nrou_new}
@deftypefn {} {UNUR_PAR*} unur_nrou_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_nrou_set_u}
@deftypefn Function {int} unur_nrou_set_u (UNUR_PAR* @var{parameters}, double @var{umin}, double @var{umax})
Sets left and right boundary of bounding rectangle.
If no values are given, the boundary of the minimal bounding
rectangle is computed numerically.

@emph{Notice}: Computing the minimal bounding rectangle may fail
under some circumstances. Moreover, for multimodal distributions
the bounds might be too small as only local extrema are computed.
Nevertheless, for
@math{T_c}
-concave distributions with
@math{c=-1/2}
it should work.

@emph{Important:} The bounding rectangle that has to be
provided is for the function
@math{PDF(x-center)!}

Default: not set.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_nrou_set_u}
@deftypefn {} {int} unur_nrou_set_u (UNUR_PAR* @var{parameters}, double @var{umin}, double @var{umax})
Sets left and right boundary of bounding rectangle.
If no values are given, the boundary of the minimal bounding
rectangle is computed numerically.

@emph{Notice}: Computing the minimal bounding rectangle may fail
under some circumstances. Moreover, for multimodal distributions
the bounds might be too small as only local extrema are computed.
Nevertheless, for
@iftex
@math{T_c}
@end iftex
@ifhtml
@html
<I>T</I>_<I>c</I>
@end html
@end ifhtml
-concave distributions with
@iftex
@math{c=-1/2}
@end iftex
@ifhtml
@html
<I>c</I>=-1/2
@end html
@end ifhtml
it should work.

@emph{Important:} The bounding rectangle that has to be
provided is for the function
@iftex
@math{PDF(x-center)!}
@end iftex
@ifhtml
@html
<I>PDF</I>(<I>x</I>-<I>center</I>)!
@end html
@end ifhtml

Default: not set.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_nrou_set_v}
@deftypefn Function {int} unur_nrou_set_v (UNUR_PAR* @var{parameters}, double @var{vmax})
Set upper boundary for bounding rectangle. If this value is not
given then
@math{sqrt(PDF(mode))}
is used instead.

@emph{Notice}: When the mode is not given for the distribution
object, then it will be computed numerically.

Default: not set.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_nrou_set_v}
@deftypefn {} {int} unur_nrou_set_v (UNUR_PAR* @var{parameters}, double @var{vmax})
Set upper boundary for bounding rectangle. If this value is not
given then
@iftex
@math{\sqrt{PDF(mode)}}
@end iftex
@ifhtml
@html
sqrt(<I>PDF</I>(<I>mode</I>))
@end html
@end ifhtml
is used instead.

@emph{Notice}: When the mode is not given for the distribution
object, then it will be computed numerically.

Default: not set.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_nrou_set_r}
@deftypefn Function {int} unur_nrou_set_r (UNUR_PAR* @var{parameters}, double @var{r})
Sets the parameter @var{r} of the generalized ratio-of-uniforms
method.

@emph{Notice}: This parameter must satisfy @var{r}>0.

Default: @code{1}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_nrou_set_r}
@deftypefn {} {int} unur_nrou_set_r (UNUR_PAR* @var{parameters}, double @var{r})
Sets the parameter @var{r} of the generalized ratio-of-uniforms
method.

@emph{Notice}: This parameter must satisfy @var{r}>0.

Default: @code{1}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_nrou_set_center}
@deftypefn Function {int} unur_nrou_set_center (UNUR_PAR* @var{parameters}, double @var{center})
Set the center
@math{mu}
of the PDF.
If not set the center of the given distribution object is used.

Default: see
@ifhtml
@ref{funct:unur_distr_cont_set_center,@command{unur_distr_cont_set_center}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_center}.
@end ifnothtml
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_nrou_set_center}
@deftypefn {} {int} unur_nrou_set_center (UNUR_PAR* @var{parameters}, double @var{center})
Set the center
@iftex
@math{\mu}
@end iftex
@ifhtml
@html
mu
@end html
@end ifhtml
of the PDF.
If not set the center of the given distribution object is used.

Default: see
@ifhtml
@ref{funct:unur_distr_cont_set_center,@command{unur_distr_cont_set_center}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_center}.
@end ifnothtml
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_nrou_set_verify}
@deftypefn Function {int} unur_nrou_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
Turn verifying of algorithm while sampling on/off.

If the condition
@math{PDF(x) <= hat(x)}
is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However, notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_nrou_set_verify}
@deftypefn {} {int} unur_nrou_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
Turn verifying of algorithm while sampling on/off.

If the condition
@iftex
@math{PDF(x) \leq hat(x)}
@end iftex
@ifhtml
@html
<I>PDF</I>(<I>x</I>) <= <I>hat</I>(<I>x</I>)
@end html
@end ifhtml
is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However, notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_nrou_chg_verify}
@deftypefn Function {int} unur_nrou_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Change the verifying of algorithm while sampling on/off.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_nrou_chg_verify}
@deftypefn {} {int} unur_nrou_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Change the verifying of algorithm while sampling on/off.
@end deftypefn
@end ifnotinfo




@c
@c end of nrou.h
@c -------------------------------------
@c -------------------------------------
@c pinv.h
@c

@page
@node PINV
@subsection   PINV  --  Polynomial interpolation based INVersion of CDF

@table @i
@item Required:
PDF
@item Optional:
domain, center, CDF, derivative of PDF
@item Speed:
Set-up: (very) slow, Sampling: (very) fast
@item Reinit:
not implemented
@item Reference:
@ifhtml
@ref{bib:DHLa08,, [DHLa08]}
@end ifhtml
@ifnothtml
[DHLa08]
@end ifnothtml

@end table


PINV is a variant of numerical inversion, where the inverse CDF
is approximated using Newton's interpolating formula.
The interval [0,1] is split into several subintervals. In each
of these the inverse CDF is constructed at nodes
@iftex
@math{(CDF(x),x)}
@end iftex
@ifhtml
@html
(<I>CDF</I>(<I>x</I>),<I>x</I>)
@end html
@end ifhtml
@ifinfo
@math{(CDF(x),x)}
@end ifinfo
for some points @i{x} in this subinterval.
If the PDF is given, then the CDF is computed numerically
from the given PDF using adaptive Gauss-Lobatto
integration with 5 points. Subintervals are split until the
requested accuracy goal is reached.

The method is not exact, as it only produces random variates of
the approximated distribution. Nevertheless, the maximal
tolerated approximation error can be set to be the resolution
(but of course is bounded by the machine precision).
We use the u-error
@iftex
@math{|U-CDF(X)|}
@end iftex
@ifhtml
@html
|<I>U</I>-<I>CDF</I>(<I>X</I>)|
@end html
@end ifhtml
@ifinfo
@math{|U-CDF(X)|}
@end ifinfo
to measure the error
for @i{X} = "approximate inverse CDF"(@i{U}).
Notice that very small values of the u-resolution are possible
but increase the cost for the setup step.
We call the maximal tolerated u-error the @emph{u-resolution} of
the algorithm in the sequel.

Both the order of the interpolating polynomial and the
u-resolution can be selected.

The interpolating polynomials have to be computed in a setup
step. However, it only works for distributions with bounded
domain; for distributions with unbounded domain the tails are
cut off such that the probability for the tail regions is
small compared to the given u-resolution.

The construction of the interpolation polynomial only works when
the PDF is unimodal or when the PDF does not vanish between two
modes.

There are some restrictions for the given distribution:
@itemize
@item
The support of the distribution (i.e., the region where the PDF
is strictly positive) must be connected. In practice this means,
that the region where PDF is "not too small" must be connected.
Unimodal densities satisfy this condition.
If this condition is violated then the domain of the
distribution might be truncated.
@item
When the PDF is integrated numerically, then the given PDF must
be continuous and should be smooth.
@item
The PDF must be bounded.
@item
The algorithm has problems when the distribution has heavy tails
(as then the inverse CDF becomes very steep at 0 or 1)
and the requested u-resolution is very small.
E.g., the Cauchy distribution is likely to show this problem
when the requested u-resolution is less then @code{1.e-12}.
@end itemize
Regions with very small PDF values or heavy tails might lead to
an abortion of the set-up or (even worse) the approximation
error might become larger than requested, since the (computation of the)
interpolating polynomial becomes numerically unstable.

@emph{Remark:}
We also have implemented experimental variants.
However, we observed that these variants are more sensitive to
round-off errors, especially in the right hand tail and we
@emph{do not recommend} their usage unless there are severe
reasons.

@itemize @minus
@item
Use a function that implements the CDF instead of numerical
integration of the PDF.

@item
Use Hermite interpolation instead of Newton interpolation.
Thus the first (and second) derivative of the interpolating
polynomial coincides with that of the inverse CDF.
Consequently the interpolant is also (twice) differentiable even
at the interval boundaries.
This variant can be seen as limiting case of Newton
interpolation with double (or triple) points as nodes.

We have used a @emph{smoothness} parameter to control this
feature. However, besides numerical problems we observed that
this variant requires more intervals and thus larger setup times
and higher memory consumptions.
@end itemize



@subsubheading How To Use


PINV works for continuous univariate distribution objects with
given PDF. The corresponding distribution object should contain a
typical point of the distribution, i.e., a point where the PDF
is not too small, e.g., (a point near) the mode.
However, it is important that the center is @strong{not} the
pole of the distribution (or a point too close to the pole).
It can be set using a
@ifhtml
@ref{funct:unur_distr_cont_set_center,@command{unur_distr_cont_set_center}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_center}
@end ifnothtml
or
a
@ifhtml
@ref{funct:unur_distr_cont_set_mode,@command{unur_distr_cont_set_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_mode}
@end ifnothtml
call. If neither is set, or if the
given center cannot be used, then a simple search routine tries
to find an appropriate point for the center.

It is recommended that the domain of the distribution with
bounded domain is specified using a
@ifhtml
@ref{funct:unur_distr_cont_set_domain,@command{unur_distr_cont_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_domain}
@end ifnothtml
call. Otherwise, the boundary is searched numerically which
might be rather expensive, especially when this boundary point
is @code{0}.

The inverse CDF is interpolated using Newton polynomials.
The order of this polynomial can be set by means of a
@ifhtml
@ref{funct:unur_pinv_set_order,@command{unur_pinv_set_order}}
@end ifhtml
@ifnothtml
@command{unur_pinv_set_order}
@end ifnothtml
call.

The smoothness of the interpolant at interval boundaries can be
controlled using a
@ifhtml
@ref{funct:unur_pinv_set_smoothness,@command{unur_pinv_set_smoothness}}
@end ifhtml
@ifnothtml
@command{unur_pinv_set_smoothness}
@end ifnothtml
call.
Then Hermite interpolation instead of Newton interpolation is
used. (The former can be seen as a limiting case of Newton
interpolation with double (or triple) points.)
However, using higher smoothness is @emph{not recommended}
unless differentiability at the interval boundaries is
important.

For distributions with unbounded domains the tails are cut
off such that the probability for the tail regions is small
compared to the given u-resolution. For finding these cut points
the algorithm starts with the region @code{[-1.e100,1.e100]}. For
the exceptional case where this does not work these starting
points can be changed via a
@ifhtml
@ref{funct:unur_pinv_set_boundary,@command{unur_pinv_set_boundary}}
@end ifhtml
@ifnothtml
@command{unur_pinv_set_boundary}
@end ifnothtml
call.

This method is not exact, as it only produces random variates of
the approximated distribution. Nevertheless, the numerical error
in "u-direction" (i.e., |U-CDF(X)|, for
X = "approximate inverse CDF"(U) |U-CDF(X)|) can be controlled
by means of
@ifhtml
@ref{funct:unur_pinv_set_u_resolution,@command{unur_pinv_set_u_resolution}.}
@end ifhtml
@ifnothtml
@command{unur_pinv_set_u_resolution}.
@end ifnothtml
However, the maximal error of this approximation is only
estimated. For very small u-resolutions the actual approximation
error might be (slightly) larger than the requested u-resolution.
(Of course the size of this value depends on the given PDF.)
If this error is crucial for an application we recommend to
compute this error using
@ifhtml
@ref{funct:unur_pinv_estimate_error,@command{unur_pinv_estimate_error}}
@end ifhtml
@ifnothtml
@command{unur_pinv_estimate_error}
@end ifnothtml
which runs a
small Monte Carlo simulation.
It is also possible to improve the error estimate during setup
by means of
@ifhtml
@ref{funct:unur_pinv_set_extra_testpoints,@command{unur_pinv_set_extra_testpoints}.}
@end ifhtml
@ifnothtml
@command{unur_pinv_set_extra_testpoints}.
@end ifnothtml
See also the documentation for function
@ifhtml
@ref{funct:unur_pinv_set_u_resolution,@command{unur_pinv_set_u_resolution}}
@end ifhtml
@ifnothtml
@command{unur_pinv_set_u_resolution}
@end ifnothtml
and the remark given there.

The number of required subintervals heavily depends on the order
of the interpolating polynomial and the requested u-resolution:
it increases when order or u-resolution are decreased.
It can be checked using a
@ifhtml
@ref{funct:unur_pinv_get_n_intervals,@command{unur_pinv_get_n_intervals}}
@end ifhtml
@ifnothtml
@command{unur_pinv_get_n_intervals}
@end ifnothtml
call.
The maximum number of such subintervals is fixed but can be
increased using a
@ifhtml
@ref{funct:unur_pinv_set_max_intervals,@command{unur_pinv_set_max_intervals}}
@end ifhtml
@ifnothtml
@command{unur_pinv_set_max_intervals}
@end ifnothtml
call.
If this maximum number is too small then the set-up aborts with
a corresponding error message.

It is also possible to use the CDF of the distribution instead
of the PDF. Then the distribution object must contain a pointer
to the CDF. Moreover, this variant of the algorithm has to be
switched on using an
@ifhtml
@ref{funct:unur_pinv_set_usecdf,@command{unur_pinv_set_usecdf}}
@end ifhtml
@ifnothtml
@command{unur_pinv_set_usecdf}
@end ifnothtml
call.
Notice, however, that the setup for this variant is numerically
less stable than using integration of the PDF (the default
variant). Thus using the CDF is @emph{not recommended}.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_pinv_new,unur_pinv_new}
@item @ref{funct:unur_pinv_set_order,unur_pinv_set_order}
@item @ref{funct:unur_pinv_set_smoothness,unur_pinv_set_smoothness}
@item @ref{funct:unur_pinv_set_u_resolution,unur_pinv_set_u_resolution}
@item @ref{funct:unur_pinv_set_extra_testpoints,unur_pinv_set_extra_testpoints}
@item @ref{funct:unur_pinv_set_use_upoints,unur_pinv_set_use_upoints}
@item @ref{funct:unur_pinv_set_usepdf,unur_pinv_set_usepdf}
@item @ref{funct:unur_pinv_set_usecdf,unur_pinv_set_usecdf}
@item @ref{funct:unur_pinv_set_boundary,unur_pinv_set_boundary}
@item @ref{funct:unur_pinv_set_searchboundary,unur_pinv_set_searchboundary}
@item @ref{funct:unur_pinv_set_max_intervals,unur_pinv_set_max_intervals}
@item @ref{funct:unur_pinv_get_n_intervals,unur_pinv_get_n_intervals}
@item @ref{funct:unur_pinv_set_keepcdf,unur_pinv_set_keepcdf}
@item @ref{funct:unur_pinv_eval_approxinvcdf,unur_pinv_eval_approxinvcdf}
@item @ref{funct:unur_pinv_eval_approxcdf,unur_pinv_eval_approxcdf}
@item @ref{funct:unur_pinv_estimate_error,unur_pinv_estimate_error}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_pinv_new}
@deftypefn Function {UNUR_PAR*} unur_pinv_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_pinv_new}
@deftypefn {} {UNUR_PAR*} unur_pinv_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_pinv_set_order}
@deftypefn Function {int} unur_pinv_set_order (UNUR_PAR* @var{parameters}, int @var{order})
Set order of interpolation. Valid orders are between @code{3} and
@code{17}. Higher orders result in fewer intervals for the
approximations.

Default: @code{5}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_pinv_set_order}
@deftypefn {} {int} unur_pinv_set_order (UNUR_PAR* @var{parameters}, int @var{order})
Set order of interpolation. Valid orders are between @code{3} and
@code{17}. Higher orders result in fewer intervals for the
approximations.

Default: @code{5}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_pinv_set_smoothness}
@deftypefn Function {int} unur_pinv_set_smoothness (UNUR_PAR* @var{parameters}, int @var{smoothness})
Set smoothness of interpolant. By construction the interpolant is
piecewise polynomial and thus smooth on each of the intervals
where these polynomials are constructed. At the interval
boundaries, however, it usually not be differentiable.
Method PINV also implements variants of Newton interpolation where
the first (or second) derivative of the interpolating
polynomial coincides with the respective derivative of the inverse
CDF at the nodes. The the interpolant is (twice) differentiable
even at the interval boundaries.
These variants can be seen as limiting case of Newton interpolation
with double (or triple) points as nodes and are known as Hermite
interpolation.

Possible values for @var{smoothness}:

@multitable @columnfractions .1 .25 .60
@headitem Value @tab Effect @tab Requirements
@item @code{0}
@tab continuous
@tab requires PDF (or CDF)

@item @code{1}
@tab differentiable
@tab requires PDF (optional: CDF), @*
order of polynomial must be odd

@item @code{2}
@tab twice differentiable
@tab requires PDF and its derivative (optional: CDF), @*
order must be 5, 8, 11, 14 or 17
@end multitable

If the order of the polynomial does not satisfy the given
condition, then it is increased to the next larger possible value.

@emph{Remark:}
A higher smoothness parameter usually results in a higher number of
intervals and thus a higher setup time and memory consumption.
We also observed that higher smoothness parameters make the
algorithm more sensible for round-off error. Then the setup fails.

@emph{Remark:}
If the interpolating polynomial cannot be constructed for the
requested smoothness on a particular interval,
then the smoothness parameter is reduced for that interval.

@emph{Remark:}
For order @code{3} and smoothness @code{1} (cubic Hermite
interpolation) monotonicity is guaranteed by checking a simple
monotonicity condition for the coefficients of the polynomials.

@emph{Remark:}
Using @var{smoothness} larger than @code{0} is
@emph{not recommended} unless differentiability at the interval
boundaries is important for ones application.

Default: @code{0}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_pinv_set_smoothness}
@deftypefn {} {int} unur_pinv_set_smoothness (UNUR_PAR* @var{parameters}, int @var{smoothness})
Set smoothness of interpolant. By construction the interpolant is
piecewise polynomial and thus smooth on each of the intervals
where these polynomials are constructed. At the interval
boundaries, however, it usually not be differentiable.
Method PINV also implements variants of Newton interpolation where
the first (or second) derivative of the interpolating
polynomial coincides with the respective derivative of the inverse
CDF at the nodes. The the interpolant is (twice) differentiable
even at the interval boundaries.
These variants can be seen as limiting case of Newton interpolation
with double (or triple) points as nodes and are known as Hermite
interpolation.

Possible values for @var{smoothness}:

@multitable @columnfractions .1 .25 .60
@headitem Value @tab Effect @tab Requirements
@item @code{0}
@tab continuous
@tab requires PDF (or CDF)

@item @code{1}
@tab differentiable
@tab requires PDF (optional: CDF), @*
order of polynomial must be odd

@item @code{2}
@tab twice differentiable
@tab requires PDF and its derivative (optional: CDF), @*
order must be 5, 8, 11, 14 or 17
@end multitable

If the order of the polynomial does not satisfy the given
condition, then it is increased to the next larger possible value.

@emph{Remark:}
A higher smoothness parameter usually results in a higher number of
intervals and thus a higher setup time and memory consumption.
We also observed that higher smoothness parameters make the
algorithm more sensible for round-off error. Then the setup fails.

@emph{Remark:}
If the interpolating polynomial cannot be constructed for the
requested smoothness on a particular interval,
then the smoothness parameter is reduced for that interval.

@emph{Remark:}
For order @code{3} and smoothness @code{1} (cubic Hermite
interpolation) monotonicity is guaranteed by checking a simple
monotonicity condition for the coefficients of the polynomials.

@emph{Remark:}
Using @var{smoothness} larger than @code{0} is
@emph{not recommended} unless differentiability at the interval
boundaries is important for ones application.

Default: @code{0}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_pinv_set_u_resolution}
@deftypefn Function {int} unur_pinv_set_u_resolution (UNUR_PAR* @var{parameters}, double @var{u_resolution})
Set maximal tolerated u-error. Values of @var{u_resolution} must
at least @code{1.e-15} and @code{1.e-5} at most.
Notice that the resolution of most uniform random number sources is
@math{2^(-32)}
= @code{2.3e-10}. Thus a value of @code{1.e-10}
leads to an inversion algorithm that could be called exact. For most
simulations slightly bigger values for the maximal error are enough
as well.

Smaller values for @var{u_resolution} increase the number of
subinterval that are necessary for the approximation of the inverse
CDF. For very small values (less then @code{1.e-12}) this number
might exceed the maximum number of such intervals. However, this
number can be increased using a
@ifhtml
@ref{funct:unur_pinv_set_max_intervals,@command{unur_pinv_set_max_intervals}}
@end ifhtml
@ifnothtml
@command{unur_pinv_set_max_intervals}
@end ifnothtml
call.

@emph{Remark:}
We ran many experiments and found that the observed u-error was
always smaller than the given @var{u_resolution} whenever this
value was @code{1.e-12}. For values smaller than @code{1e-13} the
maximal observed u-error was slightly larger. One use @code{1.e-15}
if best approximation is required. However, then the actual u-error
can be as large as @code{1.e-14}.

Consider calling
@ifhtml
@ref{funct:unur_pinv_set_extra_testpoints,@command{unur_pinv_set_extra_testpoints}}
@end ifhtml
@ifnothtml
@command{unur_pinv_set_extra_testpoints}
@end ifnothtml
in order to
reduce the risk of larger approximation errors.

@strong{Warning!}
These figures are based on our experiments (with some tolerance
added to be on the safe side). There is no guarantee for these error
estimates for a particular distribution.

Default is @code{1.e-10}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_pinv_set_u_resolution}
@deftypefn {} {int} unur_pinv_set_u_resolution (UNUR_PAR* @var{parameters}, double @var{u_resolution})
Set maximal tolerated u-error. Values of @var{u_resolution} must
at least @code{1.e-15} and @code{1.e-5} at most.
Notice that the resolution of most uniform random number sources is
@iftex
@math{2^{-32}}
@end iftex
@ifhtml
@html
2<SUP>-32</SUP>
@end html
@end ifhtml
= @code{2.3e-10}. Thus a value of @code{1.e-10}
leads to an inversion algorithm that could be called exact. For most
simulations slightly bigger values for the maximal error are enough
as well.

Smaller values for @var{u_resolution} increase the number of
subinterval that are necessary for the approximation of the inverse
CDF. For very small values (less then @code{1.e-12}) this number
might exceed the maximum number of such intervals. However, this
number can be increased using a
@ifhtml
@ref{funct:unur_pinv_set_max_intervals,@command{unur_pinv_set_max_intervals}}
@end ifhtml
@ifnothtml
@command{unur_pinv_set_max_intervals}
@end ifnothtml
call.

@emph{Remark:}
We ran many experiments and found that the observed u-error was
always smaller than the given @var{u_resolution} whenever this
value was @code{1.e-12}. For values smaller than @code{1e-13} the
maximal observed u-error was slightly larger. One use @code{1.e-15}
if best approximation is required. However, then the actual u-error
can be as large as @code{1.e-14}.

Consider calling
@ifhtml
@ref{funct:unur_pinv_set_extra_testpoints,@command{unur_pinv_set_extra_testpoints}}
@end ifhtml
@ifnothtml
@command{unur_pinv_set_extra_testpoints}
@end ifnothtml
in order to
reduce the risk of larger approximation errors.

@strong{Warning!}
These figures are based on our experiments (with some tolerance
added to be on the safe side). There is no guarantee for these error
estimates for a particular distribution.

Default is @code{1.e-10}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_pinv_set_extra_testpoints}
@deftypefn Function {int} unur_pinv_set_extra_testpoints (UNUR_PAR* @var{parameters}, int @var{n_points})
During setup method PINV checks the current u-error by means of
carefully selected test points and improves the approximation where
necessary. However, it nevertheless may happen, that the
maximal approximation error is larger than estimated in some
interval (which usually is hit with a very small probability).
This estimate can be improved by using extra test points
which can be added by means of this call.
However, this increases the setup time considerably.
Note that these additional points are selected equidistributed
in each subinterval.

Default is @code{0} (i.e., no additional test points are used).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_pinv_set_extra_testpoints}
@deftypefn {} {int} unur_pinv_set_extra_testpoints (UNUR_PAR* @var{parameters}, int @var{n_points})
During setup method PINV checks the current u-error by means of
carefully selected test points and improves the approximation where
necessary. However, it nevertheless may happen, that the
maximal approximation error is larger than estimated in some
interval (which usually is hit with a very small probability).
This estimate can be improved by using extra test points
which can be added by means of this call.
However, this increases the setup time considerably.
Note that these additional points are selected equidistributed
in each subinterval.

Default is @code{0} (i.e., no additional test points are used).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_pinv_set_use_upoints}
@deftypefn Function {int} unur_pinv_set_use_upoints (UNUR_PAR* @var{parameters}, int @var{use_upoints})
If @var{use_upoints} is @code{TRUE}, then the nodes of the interpolating
polynomial are constructed by means of Chebyshev points in u-scale
not in x-scale. This results is a better approximation but almost
doubles the number of PDF or CDF evaluations during the setup.
(This is an experimental feature.)

Default: @code{FALSE}
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_pinv_set_use_upoints}
@deftypefn {} {int} unur_pinv_set_use_upoints (UNUR_PAR* @var{parameters}, int @var{use_upoints})
If @var{use_upoints} is @code{TRUE}, then the nodes of the interpolating
polynomial are constructed by means of Chebyshev points in u-scale
not in x-scale. This results is a better approximation but almost
doubles the number of PDF or CDF evaluations during the setup.
(This is an experimental feature.)

Default: @code{FALSE}
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_pinv_set_usepdf}
@deftypefn Function {int} unur_pinv_set_usepdf (UNUR_PAR* @var{parameters})
Use PDF (if available) to compute approximate inverse CDF.

This is the default.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_pinv_set_usepdf}
@deftypefn {} {int} unur_pinv_set_usepdf (UNUR_PAR* @var{parameters})
Use PDF (if available) to compute approximate inverse CDF.

This is the default.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_pinv_set_usecdf}
@deftypefn Function {int} unur_pinv_set_usecdf (UNUR_PAR* @var{parameters})
Use CDF (if available) to compute approximate inverse CDF.
This variant is intend for running experiments with method PINV.

@emph{Remark:}
We ran many experiments and found that for small values of the
given @var{u_resolution} (less than @code{1.e-12}) the setup fails
for distributions with heavy tails. We found that using the PDF
(instead of the CDF) is numerically more stable.
This is especially the case when the smoothness parameter is set
to @code{1} or @code{2}.

Using the CDF is @strong{not recommended}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_pinv_set_usecdf}
@deftypefn {} {int} unur_pinv_set_usecdf (UNUR_PAR* @var{parameters})
Use CDF (if available) to compute approximate inverse CDF.
This variant is intend for running experiments with method PINV.

@emph{Remark:}
We ran many experiments and found that for small values of the
given @var{u_resolution} (less than @code{1.e-12}) the setup fails
for distributions with heavy tails. We found that using the PDF
(instead of the CDF) is numerically more stable.
This is especially the case when the smoothness parameter is set
to @code{1} or @code{2}.

Using the CDF is @strong{not recommended}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_pinv_set_boundary}
@deftypefn Function {int} unur_pinv_set_boundary (UNUR_PAR* @var{parameters}, double @var{left}, double @var{right})
Set @var{left} and @var{right} point for finding the cut-off points
for the "computational domain", i.e., the domain that covers the
essential part of the distribution.
The cut-off points are computed such that the tail probabilities
are smaller than given by
@ifhtml
@ref{funct:unur_pinv_set_u_resolution,@command{unur_pinv_set_u_resolution}.}
@end ifhtml
@ifnothtml
@command{unur_pinv_set_u_resolution}.
@end ifnothtml
It is usually safe to use a large interval.
However, @code{+/- UNUR_INFINITY} is not allowed.

@emph{Important}: This call does not change the domain of the
given distribution itself. But it restricts the domain for the
resulting random variates.

Default: intersection of @code{[-1.e100,+1.e100]} and the given
domain of the distribution.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_pinv_set_boundary}
@deftypefn {} {int} unur_pinv_set_boundary (UNUR_PAR* @var{parameters}, double @var{left}, double @var{right})
Set @var{left} and @var{right} point for finding the cut-off points
for the "computational domain", i.e., the domain that covers the
essential part of the distribution.
The cut-off points are computed such that the tail probabilities
are smaller than given by
@ifhtml
@ref{funct:unur_pinv_set_u_resolution,@command{unur_pinv_set_u_resolution}.}
@end ifhtml
@ifnothtml
@command{unur_pinv_set_u_resolution}.
@end ifnothtml
It is usually safe to use a large interval.
However, @code{+/- UNUR_INFINITY} is not allowed.

@emph{Important}: This call does not change the domain of the
given distribution itself. But it restricts the domain for the
resulting random variates.

Default: intersection of @code{[-1.e100,+1.e100]} and the given
domain of the distribution.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_pinv_set_searchboundary}
@deftypefn Function {int} unur_pinv_set_searchboundary (UNUR_PAR* @var{parameters}, int @var{left}, int @var{right})
If @var{left} or @var{right} is set to @code{FALSE} then the respective
boundary as given by a
@ifhtml
@ref{funct:unur_pinv_set_boundary,@command{unur_pinv_set_boundary}}
@end ifhtml
@ifnothtml
@command{unur_pinv_set_boundary}
@end ifnothtml
call is used
without any further computations.
However, these boundary points might cause numerical problems
during the setup when PDF returns @code{0} ``almost everywhere''.
If set to @code{TRUE} (the default) then the computational interval is
shortened to a more sensible region by means of a search algorithm.
Switching off this search is useful, e.g., for the Gamma(2)
distribution where the left border @code{0} is fixed and finite.

@emph{Remark:}
The searching algorithm assumes that the support of the distribution
is connected.

@emph{Remark:}
Do not set this parameter to @code{FALSE} except when searching for
cut-off points fails and one wants to try with precomputed values.

Default: @code{TRUE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_pinv_set_searchboundary}
@deftypefn {} {int} unur_pinv_set_searchboundary (UNUR_PAR* @var{parameters}, int @var{left}, int @var{right})
If @var{left} or @var{right} is set to @code{FALSE} then the respective
boundary as given by a
@ifhtml
@ref{funct:unur_pinv_set_boundary,@command{unur_pinv_set_boundary}}
@end ifhtml
@ifnothtml
@command{unur_pinv_set_boundary}
@end ifnothtml
call is used
without any further computations.
However, these boundary points might cause numerical problems
during the setup when PDF returns @code{0} ``almost everywhere''.
If set to @code{TRUE} (the default) then the computational interval is
shortened to a more sensible region by means of a search algorithm.
Switching off this search is useful, e.g., for the Gamma(2)
distribution where the left border @code{0} is fixed and finite.

@emph{Remark:}
The searching algorithm assumes that the support of the distribution
is connected.

@emph{Remark:}
Do not set this parameter to @code{FALSE} except when searching for
cut-off points fails and one wants to try with precomputed values.

Default: @code{TRUE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_pinv_set_max_intervals}
@deftypefn Function {int} unur_pinv_set_max_intervals (UNUR_PAR* @var{parameters}, int @var{max_ivs})
Set maximum number of intervals. @var{max_ivs} must be at least
@code{100} and at most @code{1000000}.

Default is @code{10000}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_pinv_set_max_intervals}
@deftypefn {} {int} unur_pinv_set_max_intervals (UNUR_PAR* @var{parameters}, int @var{max_ivs})
Set maximum number of intervals. @var{max_ivs} must be at least
@code{100} and at most @code{1000000}.

Default is @code{10000}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_pinv_get_n_intervals}
@deftypefn Function {int} unur_pinv_get_n_intervals (const @var{UNUR_GEN* generator})
Get number of intervals used for interpolation in
the generator object.
It returns @code{0} in case of an error.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_pinv_get_n_intervals}
@deftypefn {} {int} unur_pinv_get_n_intervals (const @var{UNUR_GEN* generator})
Get number of intervals used for interpolation in
the generator object.
It returns @code{0} in case of an error.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_pinv_set_keepcdf}
@deftypefn Function {int} unur_pinv_set_keepcdf (UNUR_PAR* @var{parameters}, int @var{keepcdf})
If the PDF is given, then the CDF is computed numerically
from the given PDF using adaptive Gauss-Lobatto integration.
Thus a table of CDF points is stored to keep the number of
evaluations of the PDF minimal. Usually this table is discarded
when the setup is completed.
If @var{keepcdf} is @code{TRUE}, then this table is kept and can be used
to compute the CDF of the underlying distribution by means of
function
@ifhtml
@ref{funct:unur_pinv_eval_approxcdf,@command{unur_pinv_eval_approxcdf}.}
@end ifhtml
@ifnothtml
@command{unur_pinv_eval_approxcdf}.
@end ifnothtml
This option is ignored when
@ifhtml
@ref{funct:unur_pinv_set_usecdf,@command{unur_pinv_set_usecdf}}
@end ifhtml
@ifnothtml
@command{unur_pinv_set_usecdf}
@end ifnothtml
is called.

Default: @code{FALSE}
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_pinv_set_keepcdf}
@deftypefn {} {int} unur_pinv_set_keepcdf (UNUR_PAR* @var{parameters}, int @var{keepcdf})
If the PDF is given, then the CDF is computed numerically
from the given PDF using adaptive Gauss-Lobatto integration.
Thus a table of CDF points is stored to keep the number of
evaluations of the PDF minimal. Usually this table is discarded
when the setup is completed.
If @var{keepcdf} is @code{TRUE}, then this table is kept and can be used
to compute the CDF of the underlying distribution by means of
function
@ifhtml
@ref{funct:unur_pinv_eval_approxcdf,@command{unur_pinv_eval_approxcdf}.}
@end ifhtml
@ifnothtml
@command{unur_pinv_eval_approxcdf}.
@end ifnothtml
This option is ignored when
@ifhtml
@ref{funct:unur_pinv_set_usecdf,@command{unur_pinv_set_usecdf}}
@end ifhtml
@ifnothtml
@command{unur_pinv_set_usecdf}
@end ifnothtml
is called.

Default: @code{FALSE}
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_pinv_eval_approxinvcdf}
@deftypefn Function {double} unur_pinv_eval_approxinvcdf (const @var{UNUR_GEN* generator}, double @var{u})
Evaluate interpolation of inverse CDF at @var{u}.
If @var{u} is out of the domain (0,1) then @code{unur_errno} is set
to @code{UNUR_ERR_DOMAIN} and the respective bound of
the domain of the distribution are returned (which is
@code{-UNUR_INFINITY} or @code{UNUR_INFINITY} in the case of
unbounded domains).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_pinv_eval_approxinvcdf}
@deftypefn {} {double} unur_pinv_eval_approxinvcdf (const @var{UNUR_GEN* generator}, double @var{u})
Evaluate interpolation of inverse CDF at @var{u}.
If @var{u} is out of the domain (0,1) then @code{unur_errno} is set
to @code{UNUR_ERR_DOMAIN} and the respective bound of
the domain of the distribution are returned (which is
@code{-UNUR_INFINITY} or @code{UNUR_INFINITY} in the case of
unbounded domains).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_pinv_eval_approxcdf}
@deftypefn Function {double} unur_pinv_eval_approxcdf (const @var{UNUR_GEN* generator}, double @var{x})
Evaluate (approximate) CDF at @var{x}. If the PDF of the
distribution is given, then adaptive Gauss-Lobatto integration is
used to compute the CDF.
If the PDF is used to create the generator object, then the
table of integral values must not removed at the end of setup and thus
@ifhtml
@ref{funct:unur_pinv_set_keepcdf,@command{unur_pinv_set_keepcdf}}
@end ifhtml
@ifnothtml
@command{unur_pinv_set_keepcdf}
@end ifnothtml
must be called.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_pinv_eval_approxcdf}
@deftypefn {} {double} unur_pinv_eval_approxcdf (const @var{UNUR_GEN* generator}, double @var{x})
Evaluate (approximate) CDF at @var{x}. If the PDF of the
distribution is given, then adaptive Gauss-Lobatto integration is
used to compute the CDF.
If the PDF is used to create the generator object, then the
table of integral values must not removed at the end of setup and thus
@ifhtml
@ref{funct:unur_pinv_set_keepcdf,@command{unur_pinv_set_keepcdf}}
@end ifhtml
@ifnothtml
@command{unur_pinv_set_keepcdf}
@end ifnothtml
must be called.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_pinv_estimate_error}
@deftypefn Function {int} unur_pinv_estimate_error (const @var{UNUR_GEN* generator}, int @var{samplesize}, double* @var{max_error}, double* @var{MAE})
Estimate maximal u-error and mean absolute error (MAE) for @var{generator}
by means of Monte-Carlo simulation with sample size @var{samplesize}.
The results are stored in @var{max_error} and @var{MAE}, respectively.

It returns @code{UNUR_SUCCESS} if successful.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_pinv_estimate_error}
@deftypefn {} {int} unur_pinv_estimate_error (const @var{UNUR_GEN* generator}, int @var{samplesize}, double* @var{max_error}, double* @var{MAE})
Estimate maximal u-error and mean absolute error (MAE) for @var{generator}
by means of Monte-Carlo simulation with sample size @var{samplesize}.
The results are stored in @var{max_error} and @var{MAE}, respectively.

It returns @code{UNUR_SUCCESS} if successful.
@end deftypefn
@end ifnotinfo




@c
@c end of pinv.h
@c -------------------------------------
@c -------------------------------------
@c srou.h
@c

@page
@node SROU
@subsection   SROU  --  Simple Ratio-Of-Uniforms method

@table @i
@item Required:
T-concave PDF, mode, area
@item Speed:
Set-up: fast, Sampling: slow
@item Reinit:
supported
@item Reference:
@ifhtml
@ref{bib:LJa01,, [LJa01]}
@end ifhtml
@ifnothtml
[LJa01]
@end ifnothtml
@ifhtml
@ref{bib:LJa02,, [LJa02]}
@end ifhtml
@ifnothtml
[LJa02]
@end ifnothtml
@ifhtml
@ref{bib:HLD04,, [HLD04: Sect.6.3.1; Sect.6.3.2; Sect.6.4.1; Alg.6.4; Alg.6.5; Alg.6.7]}
@end ifhtml
@ifnothtml
[HLD04: Sect.6.3.1; Sect.6.3.2; Sect.6.4.1; Alg.6.4; Alg.6.5; Alg.6.7]
@end ifnothtml

@end table


SROU is based on the ratio-of-uniforms method
(@pxref{Ratio-of-Uniforms}) that uses universal inequalities for
constructing a (universal) bounding rectangle.
It works for all @i{T}-concave distributions, including
log-concave and @i{T}-concave distributions with
@iftex
@math{T(x) = -1/\sqrt{x}.}
@end iftex
@ifhtml
@html
<I>T</I>(<I>x</I>) = -1/sqrt(<I>x</I>).
@end html
@end ifhtml
@ifinfo
@math{T(x) = -1/sqrt(x).}
@end ifinfo

Moreover an (optional) parameter @code{r} can be given, to
adjust the generator to the given distribution. This parameter
is strongly related to the parameter @code{c} for transformed
density rejection (@pxref{TDR}) via the formula
@i{c = -r/(r+1)}. The rejection constant increases with higher
values for @code{r}. On the other hand, the given density must
be
@iftex
@math{T_c}
@end iftex
@ifhtml
@html
<I>T</I>_<I>c</I>
@end html
@end ifhtml
@ifinfo
@math{T_c}
@end ifinfo
-concave for the corresponding @i{c}.
The default setting for @code{r} is 1 which results in a very
simple code. (For other settings, sampling uniformly from the
acceptance region is more complicated.)

Optionally the CDF at the mode can be given to increase the
performance of the algorithm. Then the rejection constant is
reduced by 1/2 and (if @code{r=1}) even a universal squeeze can
(but need not be) used.
A way to increase the performance of the algorithm when the
CDF at the mode is not provided is the usage of the mirror
principle (only if @code{r=1}). However, using squeezes and using
the mirror principle is only recommended when the PDF is
expensive to compute.

The exact location of the mode and/or the area below the PDF can
be replace by appropriate bounds. Then the algorithm still works
but has larger rejection constants.


@subsubheading How To Use


SROU works for any continuous univariate distribution object with
given
@iftex
@math{T_c}
@end iftex
@ifhtml
@html
<I>T</I>_<I>c</I>
@end html
@end ifhtml
@ifinfo
@math{T_c}
@end ifinfo
-concave PDF with
@iftex
@math{c<1,}
@end iftex
@ifhtml
@html
<I>c</I><1,
@end html
@end ifhtml
@ifinfo
@math{c<1,}
@end ifinfo
)
mode and area below PDF. Optional the CDF at the mode
can be given to increase the performance of the algorithm by
means of the
@ifhtml
@ref{funct:unur_srou_set_cdfatmode,@command{unur_srou_set_cdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_srou_set_cdfatmode}
@end ifnothtml
call. Additionally
squeezes can be used and switched on via
@ifhtml
@ref{funct:unur_srou_set_usesqueeze,@command{unur_srou_set_usesqueeze}}
@end ifhtml
@ifnothtml
@command{unur_srou_set_usesqueeze}
@end ifnothtml
(only if @code{r=1}).
A way to increase the performance of the algorithm when the
CDF at the mode is not provided is the usage of the mirror
principle which can be swithced on by means of a
@ifhtml
@ref{funct:unur_srou_set_usemirror,@command{unur_srou_set_usemirror}}
@end ifhtml
@ifnothtml
@command{unur_srou_set_usemirror}
@end ifnothtml
call (only if @code{r=1}) .
However using squeezes and using
the mirror principle is only recommended when the PDF is
expensive to compute.

The parameter @code{r} can be given, to adjust the generator to
the given distribution. This parameter is strongly related
parameter @code{c} for transformed density rejection via the
formula @i{c = -r/(r+1)}.
The parameter @code{r} can be any value larger than or equal to
1. Values less then 1 are automatically set to 1.
The rejection constant depends on the chosen parameter
@code{r} but not on the particular distribution. It is 4 for
@code{r} equal to 1 and higher for higher values of @code{r}.
It is important to note that different algorithms for different
values of @code{r}: If @code{r} equal to 1 this is much faster
than the algorithm for @code{r} greater than 1.
The default setting for @code{r} is 1.

If the (exact) area below the PDF is not known, then an upper
bound can be used instead (which of course increases the rejection
constant).  But then the squeeze flag must not be set and
@ifhtml
@ref{funct:unur_srou_set_cdfatmode,@command{unur_srou_set_cdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_srou_set_cdfatmode}
@end ifnothtml
must not be used.

If the exact location of the mode is not known, then use the
approximate location and provide the (exact) value of the PDF at
the mode by means of the
@ifhtml
@ref{funct:unur_srou_set_pdfatmode,@command{unur_srou_set_pdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_srou_set_pdfatmode}
@end ifnothtml
call. But then
@ifhtml
@ref{funct:unur_srou_set_cdfatmode,@command{unur_srou_set_cdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_srou_set_cdfatmode}
@end ifnothtml
must not be used. Notice, that a (slow)
numerical mode finder will be used if no mode is given at all.
It is even possible to give an upper bound for the PDF only.
However, then the (upper bound for the) area below the PDF has to be
multiplied by the ratio between the upper bound and the lower bound of
the PDF at the mode.  Again setting the squeeze flag and using
@ifhtml
@ref{funct:unur_srou_set_cdfatmode,@command{unur_srou_set_cdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_srou_set_cdfatmode}
@end ifnothtml
is not allowed.

It is possible to change the parameters and the domain of the chosen
distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator object.
Notice, that derived parameters like the mode must also be (re-) set
if the parameters or the domain has be changed.
Moreover, if the PDF at the mode has been provided by a
@ifhtml
@ref{funct:unur_srou_set_pdfatmode,@command{unur_srou_set_pdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_srou_set_pdfatmode}
@end ifnothtml
call, additionally
@ifhtml
@ref{funct:unur_srou_chg_pdfatmode,@command{unur_srou_chg_pdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_srou_chg_pdfatmode}
@end ifnothtml
must be used (otherwise this call is
not necessary since then this figure is computed directly from
the PDF).

There exists a test mode that verifies whether the conditions
for the method are satisfied or not while sampling. It can be
switched on by calling
@ifhtml
@ref{funct:unur_srou_set_verify,@command{unur_srou_set_verify}}
@end ifhtml
@ifnothtml
@command{unur_srou_set_verify}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_srou_chg_verify,@command{unur_srou_chg_verify},}
@end ifhtml
@ifnothtml
@command{unur_srou_chg_verify},
@end ifnothtml
respectively. Notice however that
sampling is (a little bit) slower then.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_srou_new,unur_srou_new}
@item @ref{funct:unur_srou_set_r,unur_srou_set_r}
@item @ref{funct:unur_srou_set_cdfatmode,unur_srou_set_cdfatmode}
@item @ref{funct:unur_srou_set_pdfatmode,unur_srou_set_pdfatmode}
@item @ref{funct:unur_srou_set_usesqueeze,unur_srou_set_usesqueeze}
@item @ref{funct:unur_srou_set_usemirror,unur_srou_set_usemirror}
@item @ref{funct:unur_srou_set_verify,unur_srou_set_verify}
@item @ref{funct:unur_srou_chg_verify,unur_srou_chg_verify}
@item @ref{funct:unur_srou_chg_cdfatmode,unur_srou_chg_cdfatmode}
@item @ref{funct:unur_srou_chg_pdfatmode,unur_srou_chg_pdfatmode}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_srou_new}
@deftypefn Function {UNUR_PAR*} unur_srou_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_srou_new}
@deftypefn {} {UNUR_PAR*} unur_srou_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_srou_set_r}
@deftypefn Function {int} unur_srou_set_r (UNUR_PAR* @var{parameters}, double @var{r})
Set parameter @var{r} for transformation.
Only values greater than or equal to 1 are allowed.
The performance of the generator decreases when @var{r} is
increased. On the other hand @var{r} must not be set to small,
since the given density must be T_c-concave for
@i{c = -r/(r+1)}.

@emph{Notice:} If @var{r} is set to @code{1} a simpler and much
faster algorithm is used then for @var{r} greater than one.

For computational reasons values of @var{r} that are greater than
@code{1} but less than @code{1.01} are always set to @code{1.01}.

Default is @code{1}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_srou_set_r}
@deftypefn {} {int} unur_srou_set_r (UNUR_PAR* @var{parameters}, double @var{r})
Set parameter @var{r} for transformation.
Only values greater than or equal to 1 are allowed.
The performance of the generator decreases when @var{r} is
increased. On the other hand @var{r} must not be set to small,
since the given density must be T_c-concave for
@i{c = -r/(r+1)}.

@emph{Notice:} If @var{r} is set to @code{1} a simpler and much
faster algorithm is used then for @var{r} greater than one.

For computational reasons values of @var{r} that are greater than
@code{1} but less than @code{1.01} are always set to @code{1.01}.

Default is @code{1}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_srou_set_cdfatmode}
@deftypefn Function {int} unur_srou_set_cdfatmode (UNUR_PAR* @var{parameters}, double @var{Fmode})
Set CDF at mode.
When set, the performance of the algorithm is increased by factor 2.
However, when the parameters of the distribution are changed
@ifhtml
@ref{funct:unur_srou_chg_cdfatmode,@command{unur_srou_chg_cdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_srou_chg_cdfatmode}
@end ifnothtml
has to be used to update this value.

Default: not set.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_srou_set_cdfatmode}
@deftypefn {} {int} unur_srou_set_cdfatmode (UNUR_PAR* @var{parameters}, double @var{Fmode})
Set CDF at mode.
When set, the performance of the algorithm is increased by factor 2.
However, when the parameters of the distribution are changed
@ifhtml
@ref{funct:unur_srou_chg_cdfatmode,@command{unur_srou_chg_cdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_srou_chg_cdfatmode}
@end ifnothtml
has to be used to update this value.

Default: not set.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_srou_set_pdfatmode}
@deftypefn Function {int} unur_srou_set_pdfatmode (UNUR_PAR* @var{parameters}, double @var{fmode})
Set pdf at mode.
When set, the PDF at the mode is never changed.
This is to avoid additional computations, when the PDF does not
change when parameters of the distributions vary.
It is only useful when the PDF at the mode does not change with
changing parameters of the distribution.

@emph{IMPORTANT:}
This call has to be executed after a possible call of
@ifhtml
@ref{funct:unur_srou_set_r,@command{unur_srou_set_r}.}
@end ifhtml
@ifnothtml
@command{unur_srou_set_r}.
@end ifnothtml
Default: not set.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_srou_set_pdfatmode}
@deftypefn {} {int} unur_srou_set_pdfatmode (UNUR_PAR* @var{parameters}, double @var{fmode})
Set pdf at mode.
When set, the PDF at the mode is never changed.
This is to avoid additional computations, when the PDF does not
change when parameters of the distributions vary.
It is only useful when the PDF at the mode does not change with
changing parameters of the distribution.

@emph{IMPORTANT:}
This call has to be executed after a possible call of
@ifhtml
@ref{funct:unur_srou_set_r,@command{unur_srou_set_r}.}
@end ifhtml
@ifnothtml
@command{unur_srou_set_r}.
@end ifnothtml
Default: not set.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_srou_set_usesqueeze}
@deftypefn Function {int} unur_srou_set_usesqueeze (UNUR_PAR* @var{parameters}, int @var{usesqueeze})
Set flag for using universal squeeze (default: off).
Using squeezes is only useful when the evaluation of the PDF is
(extremely) expensive.
Using squeezes is automatically disabled when the CDF at the mode
is not given (then no universal squeezes exist).

Squeezes can only be used if @code{r=1}.

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_srou_set_usesqueeze}
@deftypefn {} {int} unur_srou_set_usesqueeze (UNUR_PAR* @var{parameters}, int @var{usesqueeze})
Set flag for using universal squeeze (default: off).
Using squeezes is only useful when the evaluation of the PDF is
(extremely) expensive.
Using squeezes is automatically disabled when the CDF at the mode
is not given (then no universal squeezes exist).

Squeezes can only be used if @code{r=1}.

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_srou_set_usemirror}
@deftypefn Function {int} unur_srou_set_usemirror (UNUR_PAR* @var{parameters}, int @var{usemirror})
Set flag for using mirror principle (default: off).
Using the mirror principle is only useful when the CDF at the
mode is not known and the evaluation of the PDF is rather cheap compared
to the marginal generation time of the underlying uniform random
number generator.
It is automatically disabled when the CDF at the mode is given.
(Then there is no necessity to use the mirror principle. However disabling
is only done during the initialization step but not at a re-initialization
step.)

The mirror principle can only be used if @code{r=1}.

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_srou_set_usemirror}
@deftypefn {} {int} unur_srou_set_usemirror (UNUR_PAR* @var{parameters}, int @var{usemirror})
Set flag for using mirror principle (default: off).
Using the mirror principle is only useful when the CDF at the
mode is not known and the evaluation of the PDF is rather cheap compared
to the marginal generation time of the underlying uniform random
number generator.
It is automatically disabled when the CDF at the mode is given.
(Then there is no necessity to use the mirror principle. However disabling
is only done during the initialization step but not at a re-initialization
step.)

The mirror principle can only be used if @code{r=1}.

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_srou_set_verify}
@anchor{funct:unur_srou_chg_verify}
@deftypefn Function {int} unur_srou_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx Function {int} unur_srou_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the condition squeeze(@i{x}) <= PDF(@i{x}) <= hat(@i{x}) is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_srou_set_verify}
@anchor{funct:unur_srou_chg_verify}
@deftypefn {} {int} unur_srou_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx {} {int} unur_srou_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the condition squeeze(@i{x}) <= PDF(@i{x}) <= hat(@i{x}) is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_srou_chg_cdfatmode}
@deftypefn Function {int} unur_srou_chg_cdfatmode (UNUR_GEN* @var{generator}, double @var{Fmode})
Change CDF at mode of distribution.
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
must be executed before sampling from the
generator again.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_srou_chg_cdfatmode}
@deftypefn {} {int} unur_srou_chg_cdfatmode (UNUR_GEN* @var{generator}, double @var{Fmode})
Change CDF at mode of distribution.
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
must be executed before sampling from the
generator again.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_srou_chg_pdfatmode}
@deftypefn Function {int} unur_srou_chg_pdfatmode (UNUR_GEN* @var{generator}, double @var{fmode})
Change PDF at mode of distribution.
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
must be executed before sampling from the
generator again.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_srou_chg_pdfatmode}
@deftypefn {} {int} unur_srou_chg_pdfatmode (UNUR_GEN* @var{generator}, double @var{fmode})
Change PDF at mode of distribution.
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
must be executed before sampling from the
generator again.
@end deftypefn
@end ifnotinfo




@c
@c end of srou.h
@c -------------------------------------
@c -------------------------------------
@c ssr.h
@c

@page
@node SSR
@subsection   SSR  --  Simple Setup Rejection

@table @i
@item Required:
T-concave PDF, mode, area
@item Speed:
Set-up: fast, Sampling: slow
@item Reinit:
supported
@item Reference:
@ifhtml
@ref{bib:LJa01,, [LJa01]}
@end ifhtml
@ifnothtml
[LJa01]
@end ifnothtml
@ifhtml
@ref{bib:HLD04,, [HLD04: Sect.6.3.3; Alg.6.6]}
@end ifhtml
@ifnothtml
[HLD04: Sect.6.3.3; Alg.6.6]
@end ifnothtml

@end table


SSR is an acceptance/rejection method that uses universal
inequalities for constructing (universal) hats and squeezes
(@pxref{Rejection}).
It works for all @i{T}-concave distributions with
@iftex
@math{T(x) = -1/\sqrt{x}.}
@end iftex
@ifhtml
@html
<I>T</I>(<I>x</I>) = -1/sqrt(<I>x</I>).
@end html
@end ifhtml
@ifinfo
@math{T(x) = -1/sqrt(x).}
@end ifinfo

It requires the PDF, the (exact) location of the mode and the
area below the given PDF. The rejection constant is 4 for all
@i{T}-concave distributions with unbounded domain and is less
than 4 when the domain is bounded. Optionally the CDF at the
mode can be given to increase the performance of the algorithm.
Then the rejection constant is at most 2 and a universal squeeze
can (but need not be) used. However, using squeezes is not
recommended unless the evaluation of the PDF is expensive.

The exact location of the mode and/or the area below the PDF can
be replace by appropriate bounds. Then the algorithm still works
but has larger rejection constants.


@subsubheading How To Use


SSR works for any continuous univariate distribution object with
given @i{T}-concave PDF (with
@iftex
@math{T(x) = -1/\sqrt{x},)}
@end iftex
@ifhtml
@html
<I>T</I>(<I>x</I>) = -1/sqrt(<I>x</I>),)
@end html
@end ifhtml
@ifinfo
@math{T(x) = -1/sqrt(x),)}
@end ifinfo
mode and area below PDF. Optional the CDF at the mode
can be given to increase the performance of the algorithm by
means of the
@ifhtml
@ref{funct:unur_ssr_set_cdfatmode,@command{unur_ssr_set_cdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_ssr_set_cdfatmode}
@end ifnothtml
call. Additionally
squeezes can be used and switched on via
@ifhtml
@ref{funct:unur_ssr_set_usesqueeze,@command{unur_ssr_set_usesqueeze}.}
@end ifhtml
@ifnothtml
@command{unur_ssr_set_usesqueeze}.
@end ifnothtml
If the (exact) area below the PDF is not known, then an upper
bound can be used instead (which of course increases the rejection
constant).  But then the squeeze flag must not be set and
@ifhtml
@ref{funct:unur_ssr_set_cdfatmode,@command{unur_ssr_set_cdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_ssr_set_cdfatmode}
@end ifnothtml
must not be used.

If the exact location of the mode is not known, then use the
approximate location and provide the (exact) value of the PDF at
the mode by means of the
@ifhtml
@ref{funct:unur_ssr_set_pdfatmode,@command{unur_ssr_set_pdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_ssr_set_pdfatmode}
@end ifnothtml
call. But then
@ifhtml
@ref{funct:unur_ssr_set_cdfatmode,@command{unur_ssr_set_cdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_ssr_set_cdfatmode}
@end ifnothtml
must not be used. Notice, that a (slow)
numerical mode finder will be used if no mode is given at all.
It is even possible to give an upper bound for the PDF only.
However, then the (upper bound for the) area below the PDF has to be
multiplied by the ratio between the upper bound and the lower bound of
the PDF at the mode.  Again setting the squeeze flag and using
@ifhtml
@ref{funct:unur_ssr_set_cdfatmode,@command{unur_ssr_set_cdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_ssr_set_cdfatmode}
@end ifnothtml
is not allowed.

It is possible to change the parameters and the domain of the chosen
distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator object.
Notice, that derived parameters like the mode must also be (re-) set
if the parameters or the domain has be changed.
Moreover, if the PDF at the mode has been provided by a
@ifhtml
@ref{funct:unur_ssr_set_pdfatmode,@command{unur_ssr_set_pdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_ssr_set_pdfatmode}
@end ifnothtml
call, additionally
@ifhtml
@ref{funct:unur_ssr_chg_pdfatmode,@command{unur_ssr_chg_pdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_ssr_chg_pdfatmode}
@end ifnothtml
must be used (otherwise this call is
not necessary since then this figure is computed directly from
the PDF).

@emph{Important:}
If any of mode, PDF or CDF at the mode, or the area below the mode
has been changed, then
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
must be executed.
(Otherwise the generator produces garbage).

There exists a test mode that verifies whether the conditions for
the method are satisfied or not while sampling. It can be
switched on/off by calling
@ifhtml
@ref{funct:unur_ssr_set_verify,@command{unur_ssr_set_verify}}
@end ifhtml
@ifnothtml
@command{unur_ssr_set_verify}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_ssr_chg_verify,@command{unur_ssr_chg_verify},}
@end ifhtml
@ifnothtml
@command{unur_ssr_chg_verify},
@end ifnothtml
respectively.
Notice, however, that sampling is (a little bit) slower then.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_ssr_new,unur_ssr_new}
@item @ref{funct:unur_ssr_set_cdfatmode,unur_ssr_set_cdfatmode}
@item @ref{funct:unur_ssr_set_pdfatmode,unur_ssr_set_pdfatmode}
@item @ref{funct:unur_ssr_set_usesqueeze,unur_ssr_set_usesqueeze}
@item @ref{funct:unur_ssr_set_verify,unur_ssr_set_verify}
@item @ref{funct:unur_ssr_chg_verify,unur_ssr_chg_verify}
@item @ref{funct:unur_ssr_chg_cdfatmode,unur_ssr_chg_cdfatmode}
@item @ref{funct:unur_ssr_chg_pdfatmode,unur_ssr_chg_pdfatmode}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_ssr_new}
@deftypefn Function {UNUR_PAR*} unur_ssr_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ssr_new}
@deftypefn {} {UNUR_PAR*} unur_ssr_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ssr_set_cdfatmode}
@deftypefn Function {int} unur_ssr_set_cdfatmode (UNUR_PAR* @var{parameters}, double @var{Fmode})
Set CDF at mode.
When set, the performance of the algorithm is increased by factor 2.
However, when the parameters of the distribution are changed
@ifhtml
@ref{funct:unur_ssr_chg_cdfatmode,@command{unur_ssr_chg_cdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_ssr_chg_cdfatmode}
@end ifnothtml
has to be used to update this value.

Default: not set.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ssr_set_cdfatmode}
@deftypefn {} {int} unur_ssr_set_cdfatmode (UNUR_PAR* @var{parameters}, double @var{Fmode})
Set CDF at mode.
When set, the performance of the algorithm is increased by factor 2.
However, when the parameters of the distribution are changed
@ifhtml
@ref{funct:unur_ssr_chg_cdfatmode,@command{unur_ssr_chg_cdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_ssr_chg_cdfatmode}
@end ifnothtml
has to be used to update this value.

Default: not set.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ssr_set_pdfatmode}
@deftypefn Function {int} unur_ssr_set_pdfatmode (UNUR_PAR* @var{parameters}, double @var{fmode})
Set pdf at mode.
When set, the PDF at the mode is never changed.
This is to avoid additional computations, when the PDF does not
change when parameters of the distributions vary.
It is only useful when the PDF at the mode does not change with
changing parameters for the distribution.

Default: not set.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ssr_set_pdfatmode}
@deftypefn {} {int} unur_ssr_set_pdfatmode (UNUR_PAR* @var{parameters}, double @var{fmode})
Set pdf at mode.
When set, the PDF at the mode is never changed.
This is to avoid additional computations, when the PDF does not
change when parameters of the distributions vary.
It is only useful when the PDF at the mode does not change with
changing parameters for the distribution.

Default: not set.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ssr_set_usesqueeze}
@deftypefn Function {int} unur_ssr_set_usesqueeze (UNUR_PAR* @var{parameters}, int @var{usesqueeze})
Set flag for using universal squeeze (default: off).
Using squeezes is only useful when the evaluation of the PDF is
(extremely) expensive.
Using squeezes is automatically disabled when the CDF at the mode
is not given (then no universal squeezes exist).

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ssr_set_usesqueeze}
@deftypefn {} {int} unur_ssr_set_usesqueeze (UNUR_PAR* @var{parameters}, int @var{usesqueeze})
Set flag for using universal squeeze (default: off).
Using squeezes is only useful when the evaluation of the PDF is
(extremely) expensive.
Using squeezes is automatically disabled when the CDF at the mode
is not given (then no universal squeezes exist).

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ssr_set_verify}
@anchor{funct:unur_ssr_chg_verify}
@deftypefn Function {int} unur_ssr_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx Function {int} unur_ssr_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the condition squeeze(@i{x}) <= PDF(@i{x}) <= hat(@i{x}) is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ssr_set_verify}
@anchor{funct:unur_ssr_chg_verify}
@deftypefn {} {int} unur_ssr_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx {} {int} unur_ssr_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the condition squeeze(@i{x}) <= PDF(@i{x}) <= hat(@i{x}) is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ssr_chg_cdfatmode}
@deftypefn Function {int} unur_ssr_chg_cdfatmode (UNUR_GEN* @var{generator}, double @var{Fmode})
Change CDF at mode of distribution.
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
must be executed before sampling from the
generator again.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ssr_chg_cdfatmode}
@deftypefn {} {int} unur_ssr_chg_cdfatmode (UNUR_GEN* @var{generator}, double @var{Fmode})
Change CDF at mode of distribution.
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
must be executed before sampling from the
generator again.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_ssr_chg_pdfatmode}
@deftypefn Function {int} unur_ssr_chg_pdfatmode (UNUR_GEN* @var{generator}, double @var{fmode})
Change PDF at mode of distribution.
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
must be executed before sampling from the
generator again.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_ssr_chg_pdfatmode}
@deftypefn {} {int} unur_ssr_chg_pdfatmode (UNUR_GEN* @var{generator}, double @var{fmode})
Change PDF at mode of distribution.
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
must be executed before sampling from the
generator again.
@end deftypefn
@end ifnotinfo




@c
@c end of ssr.h
@c -------------------------------------
@c -------------------------------------
@c tabl.h
@c

@page
@node TABL
@subsection   TABL  --  a TABLe method with piecewise constant hats

@table @i
@item Required:
PDF, all local extrema, cut-off values for the tails
@item Optional:
approximate area
@item Speed:
Set-up: (very) slow, Sampling: fast
@item Reinit:
not implemented
@item Reference:
@ifhtml
@ref{bib:AJa93,, [AJa93]}
@end ifhtml
@ifnothtml
[AJa93]
@end ifnothtml
@ifhtml
@ref{bib:AJa95,, [AJa95]}
@end ifhtml
@ifnothtml
[AJa95]
@end ifnothtml
@ifhtml
@ref{bib:HLD04,, [HLD04: Cha.5.1]}
@end ifhtml
@ifnothtml
[HLD04: Cha.5.1]
@end ifnothtml

@end table


TABL (called Ahrens method in
@ifhtml
@ref{bib:HLD04,, [HLD04]}
@end ifhtml
@ifnothtml
[HLD04]
@end ifnothtml
)
is an acceptance/rejection method (@pxref{Rejection}) that uses
a decomposition of the domain of the distribution into many
short subintervals. Inside of these subintervals constant hat
and squeeze functions are utilized. Thus it is easy to use the
idea of immediate acceptance for points below the squeeze. This
reduces the expected number of uniform random numbers per
generated random variate to less than two. Using a large number
of subintervals only little more than one random number is
necessary on average. Thus this method becomes very fast.

Due to the constant hat function this method only works for
distributions with bounded domains. Thus for unbounded domains
the left and right tails have to be cut off.  This is no problem
when the probability of falling into these tail regions is
beyond computational relevance (e.g. smaller than @code{1.e-12}).

For easy construction of hat and squeeze functions it is necessary
to know the regions of monotonicity (called @emph{slopes}) or
equivalently all local maxima and minima of the density.
The main problem for this method in the setup is the choice of the
subintervals. A simple and close to optimal approach is the
"equal area rule"
@ifhtml
@ref{bib:HLD04,, [HLD04: Cha.5.1]}
@end ifhtml
@ifnothtml
[HLD04: Cha.5.1]
@end ifnothtml
. There the subintervals are
selected such that the area below the hat is the same for
each subinterval which can be realized with a simple recursion.
If more subintervals are necessary it is possible to split
either randomly chosen intervals (adaptive rejection sampling, ARS)
or those intervals, where the ratio between squeeze and hat is
smallest. This version of the setup is called derandomized ARS
(DARS). With the default settings TABL is first calculating
approximately 30 subintervals with the equal area rule. Then
DARS is used till the desired fit of the hat is reached.

A convenient measure to control the quality of the fit of hat
and squeeze is the ratio (area below squeeze)/(area below hat)
called @code{sqhratio} which must be smaller or equal to one.
The expected number of iterations in the rejection algorithm
is known to be smaller than 1/sqhratio and the expected number
of evaluations of the density is bounded by @code{1/sqhratio - 1}.
So values of the sqhratio close to one (e.g. @code{0.95} or
@code{0.99}) lead to many subintervals. Thus a better fitting
hat is constructed and the sampling algorithm becomes fast; on
the other hand large tables are needed and the setup is very
slow. For moderate values of sqhratio (e.g. @code{0.9} or
@code{0.8}) the sampling is slower but the required tables are
smaller and the setup is not so slow.

It follows from the above explanations that TABL is always
requiring a slow setup and that it is not very well suited for
heavy-tailed distributions.


@subsubheading How To Use



For using the TABL method UNU.RAN needs a bounded interval to
which the generated variates can be restricted and information
about all local extrema of the distribution. For unimodal
densities it is sufficient to provide the mode of the
distribution. For the case of a built-in unimodal distribution
with bounded domain all these information is present in the
distribution object and thus no extra input is necessary (see
example_TABL1 below).

For a built-in unimodal distribution with unbounded domain we
should specify the cut-off values for the tails. This can be
done with the
@ifhtml
@ref{funct:unur_tabl_set_boundary,@command{unur_tabl_set_boundary}}
@end ifhtml
@ifnothtml
@command{unur_tabl_set_boundary}
@end ifnothtml
call (see example_TABL2
below). For the case that we do not set these boundaries the
default values of @code{+/- 1.e20} are used. We can see in
example_TABL1 that this still works fine for many standard
distributions.

For the case of a multimodal distribution we have to set the
regions of monotonicity (called slopes) explicitly using the
@ifhtml
@ref{funct:unur_tabl_set_slopes,@command{unur_tabl_set_slopes}}
@end ifhtml
@ifnothtml
@command{unur_tabl_set_slopes}
@end ifnothtml
command (see example_TABL3 below).

To controll the fit of the hat and the size of the tables and
thus the speed of the setup and the sampling it is most
convenient to use the
@ifhtml
@ref{funct:unur_tabl_set_max_sqhratio,@command{unur_tabl_set_max_sqhratio}}
@end ifhtml
@ifnothtml
@command{unur_tabl_set_max_sqhratio}
@end ifnothtml
call. The
default is @code{0.9} which is a sensible value for most
distributions and applications. If very large samples of a
distribution are required or the evaluation of a density is very
slow it may be useful to increase the sqhratio to
eg. @code{0.95} or even @code{0.99}. With the
@ifhtml
@ref{funct:unur_tabl_get_sqhratio,@command{unur_tabl_get_sqhratio}}
@end ifhtml
@ifnothtml
@command{unur_tabl_get_sqhratio}
@end ifnothtml
call we can check which sqhratio was
really reached. If that value is below the desired value it is
necessary to increase the maximal number of subintervals, which
defaults to @code{1000}, using the
@ifhtml
@ref{funct:unur_tabl_set_max_intervals,@command{unur_tabl_set_max_intervals}}
@end ifhtml
@ifnothtml
@command{unur_tabl_set_max_intervals}
@end ifnothtml
call.
The
@ifhtml
@ref{funct:unur_tabl_get_n_intervals,@command{unur_tabl_get_n_intervals}}
@end ifhtml
@ifnothtml
@command{unur_tabl_get_n_intervals}
@end ifnothtml
call can be used to find out the
number of subintervals the setup calculated.

It is also possible to set the number of intervals and their
respective boundaries by means of the
@ifhtml
@ref{funct:unur_tabl_set_cpoints,@command{unur_tabl_set_cpoints}}
@end ifhtml
@ifnothtml
@command{unur_tabl_set_cpoints}
@end ifnothtml
call.

It is also possible to use method TABL for correlation induction
(variance reduction) by setting of an auxiliary uniform random
number generator via the
@ifhtml
@ref{funct:unur_set_urng_aux,@command{unur_set_urng_aux}}
@end ifhtml
@ifnothtml
@command{unur_set_urng_aux}
@end ifnothtml
call. (Notice that
this must be done after a possible
@ifhtml
@ref{funct:unur_set_urng,@command{unur_set_urng}}
@end ifhtml
@ifnothtml
@command{unur_set_urng}
@end ifnothtml
call.)
However, this only works when immediate acceptance is switched
off by a
@ifhtml
@ref{funct:unur_tabl_set_variant_ia,@command{unur_tabl_set_variant_ia}}
@end ifhtml
@ifnothtml
@command{unur_tabl_set_variant_ia}
@end ifnothtml
call.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_tabl_new,unur_tabl_new}
@item @ref{funct:unur_tabl_set_variant_ia,unur_tabl_set_variant_ia}
@item @ref{funct:unur_tabl_set_cpoints,unur_tabl_set_cpoints}
@item @ref{funct:unur_tabl_set_nstp,unur_tabl_set_nstp}
@item @ref{funct:unur_tabl_set_useear,unur_tabl_set_useear}
@item @ref{funct:unur_tabl_set_areafraction,unur_tabl_set_areafraction}
@item @ref{funct:unur_tabl_set_usedars,unur_tabl_set_usedars}
@item @ref{funct:unur_tabl_set_darsfactor,unur_tabl_set_darsfactor}
@item @ref{funct:unur_tabl_set_variant_splitmode,unur_tabl_set_variant_splitmode}
@item @ref{funct:unur_tabl_set_max_sqhratio,unur_tabl_set_max_sqhratio}
@item @ref{funct:unur_tabl_get_sqhratio,unur_tabl_get_sqhratio}
@item @ref{funct:unur_tabl_get_hatarea,unur_tabl_get_hatarea}
@item @ref{funct:unur_tabl_get_squeezearea,unur_tabl_get_squeezearea}
@item @ref{funct:unur_tabl_set_max_intervals,unur_tabl_set_max_intervals}
@item @ref{funct:unur_tabl_get_n_intervals,unur_tabl_get_n_intervals}
@item @ref{funct:unur_tabl_set_slopes,unur_tabl_set_slopes}
@item @ref{funct:unur_tabl_set_guidefactor,unur_tabl_set_guidefactor}
@item @ref{funct:unur_tabl_set_boundary,unur_tabl_set_boundary}
@item @ref{funct:unur_tabl_chg_truncated,unur_tabl_chg_truncated}
@item @ref{funct:unur_tabl_set_verify,unur_tabl_set_verify}
@item @ref{funct:unur_tabl_chg_verify,unur_tabl_chg_verify}
@item @ref{funct:unur_tabl_set_pedantic,unur_tabl_set_pedantic}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_tabl_new}
@deftypefn Function {UNUR_PAR*} unur_tabl_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_new}
@deftypefn {} {UNUR_PAR*} unur_tabl_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tabl_set_variant_ia}
@deftypefn Function {int} unur_tabl_set_variant_ia (UNUR_PAR* @var{parameters}, int @var{use_ia})
Use immediate acceptance when @var{use_ia} is set to @code{TRUE}.
This technique requires less uniform. If it is set to @code{FALSE},
``classical'' acceptance/rejection from hat distribution
is used.

@emph{Notice:} Auxiliary uniform random number generators for
correlation induction (variance reduction) can only be used when
``classical'' acceptance/rejection is used.

Default: @code{TRUE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_set_variant_ia}
@deftypefn {} {int} unur_tabl_set_variant_ia (UNUR_PAR* @var{parameters}, int @var{use_ia})
Use immediate acceptance when @var{use_ia} is set to @code{TRUE}.
This technique requires less uniform. If it is set to @code{FALSE},
``classical'' acceptance/rejection from hat distribution
is used.

@emph{Notice:} Auxiliary uniform random number generators for
correlation induction (variance reduction) can only be used when
``classical'' acceptance/rejection is used.

Default: @code{TRUE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tabl_set_cpoints}
@deftypefn Function {int} unur_tabl_set_cpoints (UNUR_PAR* @var{parameters}, int @var{n_cpoints}, const @var{double* cpoints})
Set construction points for the hat function. If @var{stp} is @code{NULL}
than a heuristic rule of thumb is used to get @var{n_stp}
construction points. This is the default behavior.

The default number of construction points is @code{30}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_set_cpoints}
@deftypefn {} {int} unur_tabl_set_cpoints (UNUR_PAR* @var{parameters}, int @var{n_cpoints}, const @var{double* cpoints})
Set construction points for the hat function. If @var{stp} is @code{NULL}
than a heuristic rule of thumb is used to get @var{n_stp}
construction points. This is the default behavior.

The default number of construction points is @code{30}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tabl_set_nstp}
@deftypefn Function {int} unur_tabl_set_nstp (UNUR_PAR* @var{parameters}, int @var{n_stp})
Set number of construction points for the hat function. @var{n_stp}
must be greater than zero. After the setup there are about
@var{n_stp} construction points. However it might be larger when a
small fraction is given by the
@ifhtml
@ref{funct:unur_tabl_set_areafraction,@command{unur_tabl_set_areafraction}}
@end ifhtml
@ifnothtml
@command{unur_tabl_set_areafraction}
@end ifnothtml
call.
It also might be smaller for some variants.

Default is @code{30}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_set_nstp}
@deftypefn {} {int} unur_tabl_set_nstp (UNUR_PAR* @var{parameters}, int @var{n_stp})
Set number of construction points for the hat function. @var{n_stp}
must be greater than zero. After the setup there are about
@var{n_stp} construction points. However it might be larger when a
small fraction is given by the
@ifhtml
@ref{funct:unur_tabl_set_areafraction,@command{unur_tabl_set_areafraction}}
@end ifhtml
@ifnothtml
@command{unur_tabl_set_areafraction}
@end ifnothtml
call.
It also might be smaller for some variants.

Default is @code{30}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tabl_set_useear}
@deftypefn Function {int} unur_tabl_set_useear (UNUR_PAR* @var{parameters}, int @var{useear})
If @var{useear} is set to @code{TRUE}, the ``equal area rule'' is used,
the given slopes are partitioned in such a way that the area below
the hat function in each subinterval (``stripe'') has the same
area (except the last the last interval which can be smaller).
The area can be set by means of the
@ifhtml
@ref{funct:unur_tabl_set_areafraction,@command{unur_tabl_set_areafraction}}
@end ifhtml
@ifnothtml
@command{unur_tabl_set_areafraction}
@end ifnothtml
call.

Default is @code{TRUE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_set_useear}
@deftypefn {} {int} unur_tabl_set_useear (UNUR_PAR* @var{parameters}, int @var{useear})
If @var{useear} is set to @code{TRUE}, the ``equal area rule'' is used,
the given slopes are partitioned in such a way that the area below
the hat function in each subinterval (``stripe'') has the same
area (except the last the last interval which can be smaller).
The area can be set by means of the
@ifhtml
@ref{funct:unur_tabl_set_areafraction,@command{unur_tabl_set_areafraction}}
@end ifhtml
@ifnothtml
@command{unur_tabl_set_areafraction}
@end ifnothtml
call.

Default is @code{TRUE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tabl_set_areafraction}
@deftypefn Function {int} unur_tabl_set_areafraction (UNUR_PAR* @var{parameters}, double @var{fraction})
Set parameter for the equal area rule. During the setup a piecewise
constant hat is constructed, such that the area below each of these
pieces (strips) is the same and equal to the (given) area below the
PDF times @var{fraction} (which must be greater than
zero).

@emph{Important:} If the area below the PDF is not set in the
distribution object, then 1 is assumed.

Default is @code{0.1}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_set_areafraction}
@deftypefn {} {int} unur_tabl_set_areafraction (UNUR_PAR* @var{parameters}, double @var{fraction})
Set parameter for the equal area rule. During the setup a piecewise
constant hat is constructed, such that the area below each of these
pieces (strips) is the same and equal to the (given) area below the
PDF times @var{fraction} (which must be greater than
zero).

@emph{Important:} If the area below the PDF is not set in the
distribution object, then 1 is assumed.

Default is @code{0.1}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tabl_set_usedars}
@deftypefn Function {int} unur_tabl_set_usedars (UNUR_PAR* @var{parameters}, int @var{usedars})
If @var{usedars} is set to @code{TRUE}, ``derandomized adaptive rejection
sampling'' (DARS) is used in the setup.
Intervals, where the area between hat and squeeze is too
large compared to the average area between hat and squeeze
over all intervals, are split.
This procedure is repeated until the ratio between squeeze and hat
exceeds the bound given by
@ifhtml
@ref{funct:unur_tabl_set_max_sqhratio,@command{unur_tabl_set_max_sqhratio}}
@end ifhtml
@ifnothtml
@command{unur_tabl_set_max_sqhratio}
@end ifnothtml
call or the
maximum number of intervals is reached. Moreover, it also aborts
when no more intervals can be found for splitting.

For finding splitting points the arc-mean rule (a mixture of
arithmetic mean and harmonic mean) is used.

Default is @code{TRUE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_set_usedars}
@deftypefn {} {int} unur_tabl_set_usedars (UNUR_PAR* @var{parameters}, int @var{usedars})
If @var{usedars} is set to @code{TRUE}, ``derandomized adaptive rejection
sampling'' (DARS) is used in the setup.
Intervals, where the area between hat and squeeze is too
large compared to the average area between hat and squeeze
over all intervals, are split.
This procedure is repeated until the ratio between squeeze and hat
exceeds the bound given by
@ifhtml
@ref{funct:unur_tabl_set_max_sqhratio,@command{unur_tabl_set_max_sqhratio}}
@end ifhtml
@ifnothtml
@command{unur_tabl_set_max_sqhratio}
@end ifnothtml
call or the
maximum number of intervals is reached. Moreover, it also aborts
when no more intervals can be found for splitting.

For finding splitting points the arc-mean rule (a mixture of
arithmetic mean and harmonic mean) is used.

Default is @code{TRUE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tabl_set_darsfactor}
@deftypefn Function {int} unur_tabl_set_darsfactor (UNUR_PAR* @var{parameters}, double @var{factor})
Set factor for ``derandomized adaptive rejection sampling''.
This factor is used to determine the segments that are ``too
large'', that is, all segments where the area between squeeze and
hat is larger than @var{factor} times the average area over all
intervals between squeeze and hat.
Notice that all segments are split when @var{factor} is set to
@code{0.}, and that there is no splitting at all when @var{factor}
is set to @code{UNUR_INFINITY}.

Default is @code{0.99}. There is no need to change this parameter.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_set_darsfactor}
@deftypefn {} {int} unur_tabl_set_darsfactor (UNUR_PAR* @var{parameters}, double @var{factor})
Set factor for ``derandomized adaptive rejection sampling''.
This factor is used to determine the segments that are ``too
large'', that is, all segments where the area between squeeze and
hat is larger than @var{factor} times the average area over all
intervals between squeeze and hat.
Notice that all segments are split when @var{factor} is set to
@code{0.}, and that there is no splitting at all when @var{factor}
is set to @code{UNUR_INFINITY}.

Default is @code{0.99}. There is no need to change this parameter.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tabl_set_variant_splitmode}
@deftypefn Function {int} unur_tabl_set_variant_splitmode (UNUR_PAR* @var{parameters}, unsigned @var{splitmode})
There are three variants for adaptive rejection sampling. These
differ in the way how an interval is split:
@table @r
@item splitmode @code{1}
use the generated point to split the interval.
@item splitmode @code{2}
use the mean point of the interval.
@item splitmode @code{3}
use the arcmean point;
suggested for distributions with heavy tails.

@end table
Default is splitmode @code{2}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_set_variant_splitmode}
@deftypefn {} {int} unur_tabl_set_variant_splitmode (UNUR_PAR* @var{parameters}, unsigned @var{splitmode})
There are three variants for adaptive rejection sampling. These
differ in the way how an interval is split:
@table @r
@item splitmode @code{1}
use the generated point to split the interval.
@item splitmode @code{2}
use the mean point of the interval.
@item splitmode @code{3}
use the arcmean point;
suggested for distributions with heavy tails.

@end table
Default is splitmode @code{2}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tabl_set_max_sqhratio}
@deftypefn Function {int} unur_tabl_set_max_sqhratio (UNUR_PAR* @var{parameters}, double @var{max_ratio})
Set upper bound for the
ratio (area below squeeze) / (area below hat).
It must be a number between 0 and 1.
When the ratio exceeds the given number no further construction
points are inserted via DARS in the setup.

For the case of ARS (unur_tabl_set_usedars() must be set to @code{FALSE}):
Use @code{0} if no construction points should be added after the setup.
Use @code{1} if added new construction points should not be stopped
until the maximum number of construction points is reached.
If @var{max_ratio} is close to one, many construction points are used.

Default is @code{0.9}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_set_max_sqhratio}
@deftypefn {} {int} unur_tabl_set_max_sqhratio (UNUR_PAR* @var{parameters}, double @var{max_ratio})
Set upper bound for the
ratio (area below squeeze) / (area below hat).
It must be a number between 0 and 1.
When the ratio exceeds the given number no further construction
points are inserted via DARS in the setup.

For the case of ARS (unur_tabl_set_usedars() must be set to @code{FALSE}):
Use @code{0} if no construction points should be added after the setup.
Use @code{1} if added new construction points should not be stopped
until the maximum number of construction points is reached.
If @var{max_ratio} is close to one, many construction points are used.

Default is @code{0.9}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tabl_get_sqhratio}
@deftypefn Function {double} unur_tabl_get_sqhratio (const @var{UNUR_GEN* generator})
Get the current ratio (area below squeeze) / (area below hat)
for the generator.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_get_sqhratio}
@deftypefn {} {double} unur_tabl_get_sqhratio (const @var{UNUR_GEN* generator})
Get the current ratio (area below squeeze) / (area below hat)
for the generator.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tabl_get_hatarea}
@deftypefn Function {double} unur_tabl_get_hatarea (const @var{UNUR_GEN* generator})
Get the area below the hat for the generator.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_get_hatarea}
@deftypefn {} {double} unur_tabl_get_hatarea (const @var{UNUR_GEN* generator})
Get the area below the hat for the generator.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tabl_get_squeezearea}
@deftypefn Function {double} unur_tabl_get_squeezearea (const @var{UNUR_GEN* generator})
Get the area below the squeeze for the generator.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_get_squeezearea}
@deftypefn {} {double} unur_tabl_get_squeezearea (const @var{UNUR_GEN* generator})
Get the area below the squeeze for the generator.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tabl_set_max_intervals}
@deftypefn Function {int} unur_tabl_set_max_intervals (UNUR_PAR* @var{parameters}, int @var{max_ivs})
Set maximum number of intervals.
No construction points are added in or after the setup when the
number of intervals suceeds @var{max_ivs}.

Default is @code{1000}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_set_max_intervals}
@deftypefn {} {int} unur_tabl_set_max_intervals (UNUR_PAR* @var{parameters}, int @var{max_ivs})
Set maximum number of intervals.
No construction points are added in or after the setup when the
number of intervals suceeds @var{max_ivs}.

Default is @code{1000}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tabl_get_n_intervals}
@deftypefn Function {int} unur_tabl_get_n_intervals (const @var{UNUR_GEN* generator})
Get the current number of intervals.
(In case of an error 0 is returned.)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_get_n_intervals}
@deftypefn {} {int} unur_tabl_get_n_intervals (const @var{UNUR_GEN* generator})
Get the current number of intervals.
(In case of an error 0 is returned.)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tabl_set_slopes}
@deftypefn Function {int} unur_tabl_set_slopes (UNUR_PAR* @var{parameters}, const @var{double* slopes}, int @var{n_slopes})
Set slopes for the PDF.
A slope <a,b> is an interval [a,b] or [b,a] where the PDF is
monotone and PDF(a) >= PDF(b).
The list of slopes is given by an array @var{slopes} where each
consecutive tuple (i.e. @code{(slopes[0], slopes[1])},
@code{(slopes[2], slopes[3])}, etc.) defines one slope.
Slopes must be sorted (i.e. both @code{slopes[0]} and
@code{slopes[1]} must not be greater than any entry of the slope
@code{(slopes[2], slopes[3])}, etc.)
and must not be overlapping. Otherwise no slopes are set and
@var{unur_errno} is set to @code{UNUR_ERR_PAR_SET}.

@emph{Notice:} @var{n_slopes} is the number of slopes (and not the
length of the array @var{slopes}).

@emph{Notice} that setting slopes resets the given domain for the
distribution. However, in case of a standard distribution the area
below the PDF is not updated.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_set_slopes}
@deftypefn {} {int} unur_tabl_set_slopes (UNUR_PAR* @var{parameters}, const @var{double* slopes}, int @var{n_slopes})
Set slopes for the PDF.
A slope <a,b> is an interval [a,b] or [b,a] where the PDF is
monotone and PDF(a) >= PDF(b).
The list of slopes is given by an array @var{slopes} where each
consecutive tuple (i.e. @code{(slopes[0], slopes[1])},
@code{(slopes[2], slopes[3])}, etc.) defines one slope.
Slopes must be sorted (i.e. both @code{slopes[0]} and
@code{slopes[1]} must not be greater than any entry of the slope
@code{(slopes[2], slopes[3])}, etc.)
and must not be overlapping. Otherwise no slopes are set and
@var{unur_errno} is set to @code{UNUR_ERR_PAR_SET}.

@emph{Notice:} @var{n_slopes} is the number of slopes (and not the
length of the array @var{slopes}).

@emph{Notice} that setting slopes resets the given domain for the
distribution. However, in case of a standard distribution the area
below the PDF is not updated.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tabl_set_guidefactor}
@deftypefn Function {int} unur_tabl_set_guidefactor (UNUR_PAR* @var{parameters}, double @var{factor})
Set factor for relative size of the guide table for indexed search
(see also method DGT @ref{DGT}). It must be greater than or equal
to @code{0}.
When set to @code{0}, then sequential search is used.

Default is @code{1}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_set_guidefactor}
@deftypefn {} {int} unur_tabl_set_guidefactor (UNUR_PAR* @var{parameters}, double @var{factor})
Set factor for relative size of the guide table for indexed search
(see also method DGT @ref{DGT}). It must be greater than or equal
to @code{0}.
When set to @code{0}, then sequential search is used.

Default is @code{1}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tabl_set_boundary}
@deftypefn Function {int} unur_tabl_set_boundary (UNUR_PAR* @var{parameters}, double @var{left}, double @var{right})
Set the left and right boundary of the computation interval.
The piecewise hat is only constructed inside this interval. The
probability outside of this region must not be of
computational relevance.
Of course @code{+/- UNUR_INFINITY} is not allowed.

Default is @code{-1.e20,1.e20}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_set_boundary}
@deftypefn {} {int} unur_tabl_set_boundary (UNUR_PAR* @var{parameters}, double @var{left}, double @var{right})
Set the left and right boundary of the computation interval.
The piecewise hat is only constructed inside this interval. The
probability outside of this region must not be of
computational relevance.
Of course @code{+/- UNUR_INFINITY} is not allowed.

Default is @code{-1.e20,1.e20}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tabl_chg_truncated}
@deftypefn Function {int} unur_tabl_chg_truncated (UNUR_GEN* @var{gen}, double @var{left}, double @var{right})
Change the borders of the domain of the (truncated) distribution.

Notice that the given truncated domain must be a subset of the
domain of the given distribution. The generator always uses the
intersection of the domain of the distribution and the truncated
domain given by this call. The hat function will not be changed.

@emph{Important:}
The ratio between the area below the hat and the area below the
squeeze changes when the sampling region is restricted. In particalur
it becomes (very) large when sampling from the (far) tail of the
distribution. Then it is better to create a generator object for the
tail of distribution only.

@emph{Important:}
This call does not work for variant @code{IA} (immediate
acceptance). In this case UNU.RAN switches @emph{automatically} to
variant @code{RH} (use ``classical'' acceptance/rejection from hat
distribution) and does revert to the variant originally set by the
user.

@emph{Important:}
It is not a good idea to use adaptave rejection sampling while
sampling from a domain that is a strict subset of the domain that
has been used to construct the hat.
For that reason adaptive adding of construction points is
@emph{automatically disabled} by this call.

@emph{Important:} If the CDF of the hat is (almost) the same
for @var{left} and @var{right} and (almost) equal to @code{0} or
@code{1}, then the truncated domain is not changed and the call
returns an error code.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_chg_truncated}
@deftypefn {} {int} unur_tabl_chg_truncated (UNUR_GEN* @var{gen}, double @var{left}, double @var{right})
Change the borders of the domain of the (truncated) distribution.

Notice that the given truncated domain must be a subset of the
domain of the given distribution. The generator always uses the
intersection of the domain of the distribution and the truncated
domain given by this call. The hat function will not be changed.

@emph{Important:}
The ratio between the area below the hat and the area below the
squeeze changes when the sampling region is restricted. In particalur
it becomes (very) large when sampling from the (far) tail of the
distribution. Then it is better to create a generator object for the
tail of distribution only.

@emph{Important:}
This call does not work for variant @code{IA} (immediate
acceptance). In this case UNU.RAN switches @emph{automatically} to
variant @code{RH} (use ``classical'' acceptance/rejection from hat
distribution) and does revert to the variant originally set by the
user.

@emph{Important:}
It is not a good idea to use adaptave rejection sampling while
sampling from a domain that is a strict subset of the domain that
has been used to construct the hat.
For that reason adaptive adding of construction points is
@emph{automatically disabled} by this call.

@emph{Important:} If the CDF of the hat is (almost) the same
for @var{left} and @var{right} and (almost) equal to @code{0} or
@code{1}, then the truncated domain is not changed and the call
returns an error code.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tabl_set_verify}
@anchor{funct:unur_tabl_chg_verify}
@deftypefn Function {int} unur_tabl_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx Function {int} unur_tabl_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the condition squeeze(@i{x}) <= PDF(@i{x}) <= hat(@i{x}) is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_set_verify}
@anchor{funct:unur_tabl_chg_verify}
@deftypefn {} {int} unur_tabl_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx {} {int} unur_tabl_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the condition squeeze(@i{x}) <= PDF(@i{x}) <= hat(@i{x}) is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tabl_set_pedantic}
@deftypefn Function {int} unur_tabl_set_pedantic (UNUR_PAR* @var{parameters}, int @var{pedantic})
Sometimes it might happen that
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
has been executed
successfully. But when additional construction points are added by
adaptive rejection sampling, the algorithm detects that the
PDF is not monotone in the given slopes.

With @var{pedantic} being @code{TRUE}, the sampling routine is exchanged
by a routine that simply returns @code{UNUR_INFINITY} indicating an
error.

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tabl_set_pedantic}
@deftypefn {} {int} unur_tabl_set_pedantic (UNUR_PAR* @var{parameters}, int @var{pedantic})
Sometimes it might happen that
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
has been executed
successfully. But when additional construction points are added by
adaptive rejection sampling, the algorithm detects that the
PDF is not monotone in the given slopes.

With @var{pedantic} being @code{TRUE}, the sampling routine is exchanged
by a routine that simply returns @code{UNUR_INFINITY} indicating an
error.

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo




@c
@c end of tabl.h
@c -------------------------------------
@c -------------------------------------
@c tdr.h
@c

@page
@node TDR
@subsection   TDR  --  Transformed Density Rejection

@table @i
@item Required:
T-concave PDF, dPDF
@item Optional:
mode
@item Speed:
Set-up: slow, Sampling: fast
@item Reinit:
supported
@item Reference:
@ifhtml
@ref{bib:GWa92,, [GWa92]}
@end ifhtml
@ifnothtml
[GWa92]
@end ifnothtml
@ifhtml
@ref{bib:HWa95,, [HWa95]}
@end ifhtml
@ifnothtml
[HWa95]
@end ifnothtml
@ifhtml
@ref{bib:HLD04,, [HLD04: Cha.4]}
@end ifhtml
@ifnothtml
[HLD04: Cha.4]
@end ifnothtml

@end table


TDR is an acceptance/rejection method that uses the concavity of a
transformed density to construct hat function and squeezes
automatically. Such PDFs are called T-concave. Currently the
following transformations are implemented and can be selected by
setting their @code{c}-values by a
@ifhtml
@ref{funct:unur_tdr_set_c,@command{unur_tdr_set_c}}
@end ifhtml
@ifnothtml
@command{unur_tdr_set_c}
@end ifnothtml
call:

@table @code
@item c = 0
T(x) = log(x)
@item c = -0.5
T(x) = -1/sqrt(x) @ @ @ @ @ (Default)
@end table

In future releases the transformations T(x) = -(x)^c will be
available for any c with 0 > c > -1.
Notice that if a PDF is T-concave for a c then it also T-concave
for every c'<c. However the performance decreases when c' is
smaller than c. For computational reasons we suggest the usage of
c = -0.5 (this is the default).
For c <= -1 the hat is not bounded any more if the domain of the
PDF is unbounded. But in the case of a bounded domain using
method TABL is preferred to a TDR with c < -1 (except in a few
special cases).

We offer three variants of the algorithm.

@table @code
@item GW
squeezes between construction points
@item PS
squeezes proportional to hat function  @ @ @ @ @ (Default)
@item IA
same as variant PS but uses a compositon method with
``immediate acceptance'' in the region below the squeeze.
@end table

@code{GW} has a slightly faster setup but higher marginal generation
times.
@code{PS} is faster than @code{GW}. @code{IA} uses less uniform
random numbers and is therefore faster than @code{PS}.

It is also possible to evaluate the inverse of the CDF of the hat distribution
directly using the
@ifhtml
@ref{funct:unur_tdr_eval_invcdfhat,@command{unur_tdr_eval_invcdfhat}}
@end ifhtml
@ifnothtml
@command{unur_tdr_eval_invcdfhat}
@end ifnothtml
call.

There are lots of parameters for these methods, see below.

It is possible to use this method for correlation induction by
setting an auxiliary uniform random number generator via the
@ifhtml
@ref{funct:unur_set_urng_aux,@command{unur_set_urng_aux}}
@end ifhtml
@ifnothtml
@command{unur_set_urng_aux}
@end ifnothtml
call. (Notice that this must be done after a
possible
@ifhtml
@ref{funct:unur_set_urng,@command{unur_set_urng}}
@end ifhtml
@ifnothtml
@command{unur_set_urng}
@end ifnothtml
call.)
When an auxiliary generator is used then the number of
uniform random numbers from the first URNG that are used for one
generated random variate is constant and given in the following table:

@table @code
@item GW ... 2
@item PS ... 2
@item IA ... 1
@end table

There exists a test mode that verifies whether the conditions for
the method are satisfied or not. It can be switched on by calling
@ifhtml
@ref{funct:unur_tdr_set_verify,@command{unur_tdr_set_verify}}
@end ifhtml
@ifnothtml
@command{unur_tdr_set_verify}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_tdr_chg_verify,@command{unur_tdr_chg_verify},}
@end ifhtml
@ifnothtml
@command{unur_tdr_chg_verify},
@end ifnothtml
respectively.
Notice however that sampling is (much) slower then.

For densities with modes not close to 0 it is suggested to set
either the mode or the center of the distribution by the
@ifhtml
@ref{funct:unur_distr_cont_set_mode,@command{unur_distr_cont_set_mode}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_mode}
@end ifnothtml
or
@ifhtml
@ref{funct:unur_distr_cont_set_center,@command{unur_distr_cont_set_center}}
@end ifhtml
@ifnothtml
@command{unur_distr_cont_set_center}
@end ifnothtml
call.
The latter is the approximate location of the mode or the mean
of the distribution. This location provides some information
about the main part of the PDF and is used to avoid numerical
problems.

It is possible to use this method for generating from truncated
distributions. It even can be changed for an existing generator
object by an
@ifhtml
@ref{funct:unur_tdr_chg_truncated,@command{unur_tdr_chg_truncated}}
@end ifhtml
@ifnothtml
@command{unur_tdr_chg_truncated}
@end ifnothtml
call.

It is possible to change the parameters and the domain of the chosen
distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator object.

@emph{Important:} The ratio between the area below the hat and
the area below the squeeze changes when the sampling region is
restricted. Especially it becomes (very) small when sampling
from the (far) tail of the distribution. Then it is better to
create a new generator object for the tail of the distribution
only.


@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_tdr_new,unur_tdr_new}
@item @ref{funct:unur_tdr_set_c,unur_tdr_set_c}
@item @ref{funct:unur_tdr_set_variant_gw,unur_tdr_set_variant_gw}
@item @ref{funct:unur_tdr_set_variant_ps,unur_tdr_set_variant_ps}
@item @ref{funct:unur_tdr_set_variant_ia,unur_tdr_set_variant_ia}
@item @ref{funct:unur_tdr_set_usedars,unur_tdr_set_usedars}
@item @ref{funct:unur_tdr_set_darsfactor,unur_tdr_set_darsfactor}
@item @ref{funct:unur_tdr_set_cpoints,unur_tdr_set_cpoints}
@item @ref{funct:unur_tdr_set_reinit_percentiles,unur_tdr_set_reinit_percentiles}
@item @ref{funct:unur_tdr_chg_reinit_percentiles,unur_tdr_chg_reinit_percentiles}
@item @ref{funct:unur_tdr_set_reinit_ncpoints,unur_tdr_set_reinit_ncpoints}
@item @ref{funct:unur_tdr_chg_reinit_ncpoints,unur_tdr_chg_reinit_ncpoints}
@item @ref{funct:unur_tdr_chg_truncated,unur_tdr_chg_truncated}
@item @ref{funct:unur_tdr_set_max_sqhratio,unur_tdr_set_max_sqhratio}
@item @ref{funct:unur_tdr_get_sqhratio,unur_tdr_get_sqhratio}
@item @ref{funct:unur_tdr_get_hatarea,unur_tdr_get_hatarea}
@item @ref{funct:unur_tdr_get_squeezearea,unur_tdr_get_squeezearea}
@item @ref{funct:unur_tdr_set_max_intervals,unur_tdr_set_max_intervals}
@item @ref{funct:unur_tdr_set_usecenter,unur_tdr_set_usecenter}
@item @ref{funct:unur_tdr_set_usemode,unur_tdr_set_usemode}
@item @ref{funct:unur_tdr_set_guidefactor,unur_tdr_set_guidefactor}
@item @ref{funct:unur_tdr_set_verify,unur_tdr_set_verify}
@item @ref{funct:unur_tdr_chg_verify,unur_tdr_chg_verify}
@item @ref{funct:unur_tdr_set_pedantic,unur_tdr_set_pedantic}
@item @ref{funct:unur_tdr_eval_invcdfhat,unur_tdr_eval_invcdfhat}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_tdr_new}
@deftypefn Function {UNUR_PAR*} unur_tdr_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_new}
@deftypefn {} {UNUR_PAR*} unur_tdr_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_set_c}
@deftypefn Function {int} unur_tdr_set_c (UNUR_PAR* @var{parameters}, double @var{c})
Set parameter @var{c} for transformation T.
Currently only values between 0 and -0.5 are allowed.
If @code{c} is between 0 and -0.5 it is set to -0.5.

Default is @code{-0.5}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_set_c}
@deftypefn {} {int} unur_tdr_set_c (UNUR_PAR* @var{parameters}, double @var{c})
Set parameter @var{c} for transformation T.
Currently only values between 0 and -0.5 are allowed.
If @code{c} is between 0 and -0.5 it is set to -0.5.

Default is @code{-0.5}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_set_variant_gw}
@deftypefn Function {int} unur_tdr_set_variant_gw (UNUR_PAR* @var{parameters})
Use original version with squeezes between construction points as
proposed by Gilks & Wild  (1992).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_set_variant_gw}
@deftypefn {} {int} unur_tdr_set_variant_gw (UNUR_PAR* @var{parameters})
Use original version with squeezes between construction points as
proposed by Gilks & Wild  (1992).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_set_variant_ps}
@deftypefn Function {int} unur_tdr_set_variant_ps (UNUR_PAR* @var{parameters})
Use squeezes proportional to the hat function. This is faster than
the original version.
This is the default.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_set_variant_ps}
@deftypefn {} {int} unur_tdr_set_variant_ps (UNUR_PAR* @var{parameters})
Use squeezes proportional to the hat function. This is faster than
the original version.
This is the default.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_set_variant_ia}
@deftypefn Function {int} unur_tdr_set_variant_ia (UNUR_PAR* @var{parameters})
Use squeezes proportional to the hat function together with a
composition method that required less uniform random numbers.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_set_variant_ia}
@deftypefn {} {int} unur_tdr_set_variant_ia (UNUR_PAR* @var{parameters})
Use squeezes proportional to the hat function together with a
composition method that required less uniform random numbers.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_set_usedars}
@deftypefn Function {int} unur_tdr_set_usedars (UNUR_PAR* @var{parameters}, int @var{usedars})
If @var{usedars} is set to @code{TRUE}, ``derandomized adaptive rejection
sampling'' (DARS) is used in setup.
Intervals where the area between hat and squeeze is too
large compared to the average area between hat and squeeze
over all intervals are split.
This procedure is repeated until the ratio between area below squeeze
and area below hat exceeds the bound given by
@ifhtml
@ref{funct:unur_tdr_set_max_sqhratio,@command{unur_tdr_set_max_sqhratio}}
@end ifhtml
@ifnothtml
@command{unur_tdr_set_max_sqhratio}
@end ifnothtml
call or the maximum number of intervals is
reached. Moreover, it also aborts when no more intervals can be
found for splitting.

For finding splitting points the following rules are used (in
this order, i.e., is if the first rule cannot be applied, the next
one is used):
@enumerate
@item
Use the expected value of adaptive rejection sampling.
@item
Use the arc-mean rule (a mixture of arithmetic mean and harmonic
mean).
@item
Use the arithmetic mean of the interval boundaries.
@end enumerate
Notice, however, that for unbounded intervals neither rule 1 nor rule
3 can be used.

As an additional feature, it is possible to choose amoung these
rules.
If @var{usedars} is set to @code{1} or @code{TRUE} the expected point
(rule 1) is used (it switches to rule 2 for a particular
interval if rule 1 cannot be applied).
If it is set to @code{2} the arc-mean rule is used.
If it is set to @code{3} the mean is used.
Notice that rule 3 can only be used if the domain of the
distribution is bounded. It is faster than the other two methods
but for heavy-tailed distribution and large domain the hat
converges extremely slowly.

The default depends on the given construction points.
If the user has provided such points via a
@ifhtml
@ref{funct:unur_tdr_set_cpoints,@command{unur_tdr_set_cpoints}}
@end ifhtml
@ifnothtml
@command{unur_tdr_set_cpoints}
@end ifnothtml
call, then @var{usedars} is set to @code{FALSE} by default, i.e.,
there is no further splitting.
If the user has only given the number of construction points (or
only uses the default number), then @var{usedars} is set to @code{TRUE}
(i.e., use rule 1).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_set_usedars}
@deftypefn {} {int} unur_tdr_set_usedars (UNUR_PAR* @var{parameters}, int @var{usedars})
If @var{usedars} is set to @code{TRUE}, ``derandomized adaptive rejection
sampling'' (DARS) is used in setup.
Intervals where the area between hat and squeeze is too
large compared to the average area between hat and squeeze
over all intervals are split.
This procedure is repeated until the ratio between area below squeeze
and area below hat exceeds the bound given by
@ifhtml
@ref{funct:unur_tdr_set_max_sqhratio,@command{unur_tdr_set_max_sqhratio}}
@end ifhtml
@ifnothtml
@command{unur_tdr_set_max_sqhratio}
@end ifnothtml
call or the maximum number of intervals is
reached. Moreover, it also aborts when no more intervals can be
found for splitting.

For finding splitting points the following rules are used (in
this order, i.e., is if the first rule cannot be applied, the next
one is used):
@enumerate
@item
Use the expected value of adaptive rejection sampling.
@item
Use the arc-mean rule (a mixture of arithmetic mean and harmonic
mean).
@item
Use the arithmetic mean of the interval boundaries.
@end enumerate
Notice, however, that for unbounded intervals neither rule 1 nor rule
3 can be used.

As an additional feature, it is possible to choose amoung these
rules.
If @var{usedars} is set to @code{1} or @code{TRUE} the expected point
(rule 1) is used (it switches to rule 2 for a particular
interval if rule 1 cannot be applied).
If it is set to @code{2} the arc-mean rule is used.
If it is set to @code{3} the mean is used.
Notice that rule 3 can only be used if the domain of the
distribution is bounded. It is faster than the other two methods
but for heavy-tailed distribution and large domain the hat
converges extremely slowly.

The default depends on the given construction points.
If the user has provided such points via a
@ifhtml
@ref{funct:unur_tdr_set_cpoints,@command{unur_tdr_set_cpoints}}
@end ifhtml
@ifnothtml
@command{unur_tdr_set_cpoints}
@end ifnothtml
call, then @var{usedars} is set to @code{FALSE} by default, i.e.,
there is no further splitting.
If the user has only given the number of construction points (or
only uses the default number), then @var{usedars} is set to @code{TRUE}
(i.e., use rule 1).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_set_darsfactor}
@deftypefn Function {int} unur_tdr_set_darsfactor (UNUR_PAR* @var{parameters}, double @var{factor})
Set factor for ``derandomized adaptive rejection sampling''.
This factor is used to determine the intervals that are ``too
large'', that is, all intervals where the area between squeeze and
hat is larger than @var{factor} times the average area over all
intervals between squeeze and hat.
Notice that all intervals are split when @var{factor} is set to
@code{0.}, and that there is no splitting at all when @var{factor}
is set to @code{UNUR_INFINITY}.

Default is @code{0.99}. There is no need to change this parameter.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_set_darsfactor}
@deftypefn {} {int} unur_tdr_set_darsfactor (UNUR_PAR* @var{parameters}, double @var{factor})
Set factor for ``derandomized adaptive rejection sampling''.
This factor is used to determine the intervals that are ``too
large'', that is, all intervals where the area between squeeze and
hat is larger than @var{factor} times the average area over all
intervals between squeeze and hat.
Notice that all intervals are split when @var{factor} is set to
@code{0.}, and that there is no splitting at all when @var{factor}
is set to @code{UNUR_INFINITY}.

Default is @code{0.99}. There is no need to change this parameter.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_set_cpoints}
@deftypefn Function {int} unur_tdr_set_cpoints (UNUR_PAR* @var{parameters}, int @var{n_stp}, const @var{double* stp})
Set construction points for the hat function. If @var{stp} is @code{NULL}
than a heuristic rule of thumb is used to get @var{n_stp}
construction points. This is the default behavior.

The default number of construction points is 30.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_set_cpoints}
@deftypefn {} {int} unur_tdr_set_cpoints (UNUR_PAR* @var{parameters}, int @var{n_stp}, const @var{double* stp})
Set construction points for the hat function. If @var{stp} is @code{NULL}
than a heuristic rule of thumb is used to get @var{n_stp}
construction points. This is the default behavior.

The default number of construction points is 30.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_set_reinit_percentiles}
@anchor{funct:unur_tdr_chg_reinit_percentiles}
@deftypefn Function {int} unur_tdr_set_reinit_percentiles (UNUR_PAR* @var{parameters}, int @var{n_percentiles}, const @var{double* percentiles})
@deftypefnx Function {int} unur_tdr_chg_reinit_percentiles (UNUR_GEN* @var{generator}, int @var{n_percentiles}, const @var{double* percentiles})
By default, when the @var{generator} object is reinitialized, it
used the same construction points as for the initialization
procedure.
Often the underlying distribution object has been changed only
moderately. For example, the full conditional distribution of a
multivariate distribution.
In this case it might be more appropriate to use
percentilesm of the hat function for the last (unchanged)
distribution. @var{percentiles} must then be a pointer to an
ordered array of numbers between @code{0.01} and @code{0.99}.
If @var{percentiles} is @code{NULL}, then a heuristic rule of thumb is
used to get @var{n_percentiles} values for these percentiles.
Notice that @var{n_percentiles} must be at least @code{2},
otherwise defaults are used.
(Then the first and third quartiles are used by default.)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_set_reinit_percentiles}
@anchor{funct:unur_tdr_chg_reinit_percentiles}
@deftypefn {} {int} unur_tdr_set_reinit_percentiles (UNUR_PAR* @var{parameters}, int @var{n_percentiles}, const @var{double* percentiles})
@deftypefnx {} {int} unur_tdr_chg_reinit_percentiles (UNUR_GEN* @var{generator}, int @var{n_percentiles}, const @var{double* percentiles})
By default, when the @var{generator} object is reinitialized, it
used the same construction points as for the initialization
procedure.
Often the underlying distribution object has been changed only
moderately. For example, the full conditional distribution of a
multivariate distribution.
In this case it might be more appropriate to use
percentilesm of the hat function for the last (unchanged)
distribution. @var{percentiles} must then be a pointer to an
ordered array of numbers between @code{0.01} and @code{0.99}.
If @var{percentiles} is @code{NULL}, then a heuristic rule of thumb is
used to get @var{n_percentiles} values for these percentiles.
Notice that @var{n_percentiles} must be at least @code{2},
otherwise defaults are used.
(Then the first and third quartiles are used by default.)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_set_reinit_ncpoints}
@anchor{funct:unur_tdr_chg_reinit_ncpoints}
@deftypefn Function {int} unur_tdr_set_reinit_ncpoints (UNUR_PAR* @var{parameters}, int @var{ncpoints})
@deftypefnx Function {int} unur_tdr_chg_reinit_ncpoints (UNUR_GEN* @var{generator}, int @var{ncpoints})
When reinit fails with the given construction points or the percentiles
of the old hat function, another trial is undertaken with @var{ncpoints}
construction points. @var{ncpoints} must be at least @code{10}.

Default: @code{50}
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_set_reinit_ncpoints}
@anchor{funct:unur_tdr_chg_reinit_ncpoints}
@deftypefn {} {int} unur_tdr_set_reinit_ncpoints (UNUR_PAR* @var{parameters}, int @var{ncpoints})
@deftypefnx {} {int} unur_tdr_chg_reinit_ncpoints (UNUR_GEN* @var{generator}, int @var{ncpoints})
When reinit fails with the given construction points or the percentiles
of the old hat function, another trial is undertaken with @var{ncpoints}
construction points. @var{ncpoints} must be at least @code{10}.

Default: @code{50}
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_chg_truncated}
@deftypefn Function {int} unur_tdr_chg_truncated (UNUR_GEN* @var{gen}, double @var{left}, double @var{right})
Change the borders of the domain of the (truncated) distribution.

Notice that the given truncated domain must be a subset of the
domain of the given distribution. The generator always uses the
intersection of the domain of the distribution and the truncated
domain given by this call. The hat function will not be changed and
there is no need to run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}.}
@end ifhtml
@ifnothtml
@command{unur_reinit}.
@end ifnothtml
@emph{Important:}
The ratio between the area below the hat and the area below the
squeeze changes when the sampling region is restricted. In particular
it becomes (very) large when sampling from the (far) tail of the
distribution. Then it is better to create a generator object for the
tail of distribution only.

@emph{Important:}
This call does not work for variant @code{IA} (immediate
acceptance). In this case UNU.RAN switches @emph{automatically} to
variant @code{PS}.

@emph{Important:}
It is not a good idea to use adaptave rejection sampling while
sampling from a domain that is a strict subset of the domain that
has been used to construct the hat.
For that reason adaptive adding of construction points is
@emph{automatically disabled} by this call.

@emph{Important:} If the CDF of the hat is (almost) the same
for @var{left} and @var{right} and (almost) equal to @code{0} or
@code{1}, then the truncated domain is not changed and the call
returns an error code.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_chg_truncated}
@deftypefn {} {int} unur_tdr_chg_truncated (UNUR_GEN* @var{gen}, double @var{left}, double @var{right})
Change the borders of the domain of the (truncated) distribution.

Notice that the given truncated domain must be a subset of the
domain of the given distribution. The generator always uses the
intersection of the domain of the distribution and the truncated
domain given by this call. The hat function will not be changed and
there is no need to run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}.}
@end ifhtml
@ifnothtml
@command{unur_reinit}.
@end ifnothtml
@emph{Important:}
The ratio between the area below the hat and the area below the
squeeze changes when the sampling region is restricted. In particular
it becomes (very) large when sampling from the (far) tail of the
distribution. Then it is better to create a generator object for the
tail of distribution only.

@emph{Important:}
This call does not work for variant @code{IA} (immediate
acceptance). In this case UNU.RAN switches @emph{automatically} to
variant @code{PS}.

@emph{Important:}
It is not a good idea to use adaptave rejection sampling while
sampling from a domain that is a strict subset of the domain that
has been used to construct the hat.
For that reason adaptive adding of construction points is
@emph{automatically disabled} by this call.

@emph{Important:} If the CDF of the hat is (almost) the same
for @var{left} and @var{right} and (almost) equal to @code{0} or
@code{1}, then the truncated domain is not changed and the call
returns an error code.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_set_max_sqhratio}
@deftypefn Function {int} unur_tdr_set_max_sqhratio (UNUR_PAR* @var{parameters}, double @var{max_ratio})
Set upper bound for the
ratio (area below squeeze) / (area below hat).
It must be a number between 0 and 1.
When the ratio exceeds the given number no further construction
points are inserted via adaptive rejection sampling.
Use 0 if no construction points should be added after the setup.
Use 1 if added new construction points should not be stopped until
the maximum number of construction points is reached.

Default is @code{0.99}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_set_max_sqhratio}
@deftypefn {} {int} unur_tdr_set_max_sqhratio (UNUR_PAR* @var{parameters}, double @var{max_ratio})
Set upper bound for the
ratio (area below squeeze) / (area below hat).
It must be a number between 0 and 1.
When the ratio exceeds the given number no further construction
points are inserted via adaptive rejection sampling.
Use 0 if no construction points should be added after the setup.
Use 1 if added new construction points should not be stopped until
the maximum number of construction points is reached.

Default is @code{0.99}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_get_sqhratio}
@deftypefn Function {double} unur_tdr_get_sqhratio (const @var{UNUR_GEN* generator})
Get the current ratio (area below squeeze) / (area below hat)
for the generator.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_get_sqhratio}
@deftypefn {} {double} unur_tdr_get_sqhratio (const @var{UNUR_GEN* generator})
Get the current ratio (area below squeeze) / (area below hat)
for the generator.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_get_hatarea}
@deftypefn Function {double} unur_tdr_get_hatarea (const @var{UNUR_GEN* generator})
Get the area below the hat for the generator.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_get_hatarea}
@deftypefn {} {double} unur_tdr_get_hatarea (const @var{UNUR_GEN* generator})
Get the area below the hat for the generator.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_get_squeezearea}
@deftypefn Function {double} unur_tdr_get_squeezearea (const @var{UNUR_GEN* generator})
Get the area below the squeeze for the generator.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_get_squeezearea}
@deftypefn {} {double} unur_tdr_get_squeezearea (const @var{UNUR_GEN* generator})
Get the area below the squeeze for the generator.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_set_max_intervals}
@deftypefn Function {int} unur_tdr_set_max_intervals (UNUR_PAR* @var{parameters}, int @var{max_ivs})
Set maximum number of intervals.
No construction points are added after the setup when the number of
intervals suceeds @var{max_ivs}.
It is increased automatically to twice the number of construction
points if this is larger.

Default is @code{100}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_set_max_intervals}
@deftypefn {} {int} unur_tdr_set_max_intervals (UNUR_PAR* @var{parameters}, int @var{max_ivs})
Set maximum number of intervals.
No construction points are added after the setup when the number of
intervals suceeds @var{max_ivs}.
It is increased automatically to twice the number of construction
points if this is larger.

Default is @code{100}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_set_usecenter}
@deftypefn Function {int} unur_tdr_set_usecenter (UNUR_PAR* @var{parameters}, int @var{usecenter})
Use the center as construction point. Default is @code{TRUE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_set_usecenter}
@deftypefn {} {int} unur_tdr_set_usecenter (UNUR_PAR* @var{parameters}, int @var{usecenter})
Use the center as construction point. Default is @code{TRUE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_set_usemode}
@deftypefn Function {int} unur_tdr_set_usemode (UNUR_PAR* @var{parameters}, int @var{usemode})
Use the (exact!) mode as construction point.
Notice that the behavior of the algorithm is different to simply
adding the mode in the list of construction points via a
@ifhtml
@ref{funct:unur_tdr_set_cpoints,@command{unur_tdr_set_cpoints}}
@end ifhtml
@ifnothtml
@command{unur_tdr_set_cpoints}
@end ifnothtml
call. In the latter case the mode is treated
just like any other point. However, when @code{usemode} is @code{TRUE}, the
tangent in the mode is always set to 0. Then the hat of the
transformed density can never cut the x-axis which must never
happen if c < 0, since otherwise the hat would not be bounded.

Default is @code{TRUE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_set_usemode}
@deftypefn {} {int} unur_tdr_set_usemode (UNUR_PAR* @var{parameters}, int @var{usemode})
Use the (exact!) mode as construction point.
Notice that the behavior of the algorithm is different to simply
adding the mode in the list of construction points via a
@ifhtml
@ref{funct:unur_tdr_set_cpoints,@command{unur_tdr_set_cpoints}}
@end ifhtml
@ifnothtml
@command{unur_tdr_set_cpoints}
@end ifnothtml
call. In the latter case the mode is treated
just like any other point. However, when @code{usemode} is @code{TRUE}, the
tangent in the mode is always set to 0. Then the hat of the
transformed density can never cut the x-axis which must never
happen if c < 0, since otherwise the hat would not be bounded.

Default is @code{TRUE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_set_guidefactor}
@deftypefn Function {int} unur_tdr_set_guidefactor (UNUR_PAR* @var{parameters}, double @var{factor})
Set factor for relative size of the guide table for indexed search
(see also method DGT @ref{DGT}). It must be greater than or equal
to @code{0}.
When set to @code{0}, then sequential search is used.

Default is 2.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_set_guidefactor}
@deftypefn {} {int} unur_tdr_set_guidefactor (UNUR_PAR* @var{parameters}, double @var{factor})
Set factor for relative size of the guide table for indexed search
(see also method DGT @ref{DGT}). It must be greater than or equal
to @code{0}.
When set to @code{0}, then sequential search is used.

Default is 2.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_set_verify}
@anchor{funct:unur_tdr_chg_verify}
@deftypefn Function {int} unur_tdr_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx Function {int} unur_tdr_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the condition squeeze(@i{x}) <= PDF(@i{x}) <= hat(@i{x}) is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_set_verify}
@anchor{funct:unur_tdr_chg_verify}
@deftypefn {} {int} unur_tdr_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx {} {int} unur_tdr_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the condition squeeze(@i{x}) <= PDF(@i{x}) <= hat(@i{x}) is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_set_pedantic}
@deftypefn Function {int} unur_tdr_set_pedantic (UNUR_PAR* @var{parameters}, int @var{pedantic})
Sometimes it might happen that
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
has been executed
successfully. But when additional construction points are added by
adaptive rejection sampling, the algorithm detects that the
PDF is not T-concave.

With @var{pedantic} being @code{TRUE}, the
sampling routine is exchanged by a routine that simply returns
@code{UNUR_INFINITY}. Otherwise the new point is not added to the
list of construction points. At least the hat function remains
T-concave.

Setting @var{pedantic} to @code{FALSE} allows sampling from a
distribution which is ``almost'' T-concave and small errors are
tolerated. However it might happen that the hat function cannot be
improved significantly. When the hat functions that has been
constructed by the
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
call is extremely large then it
might happen that the generation times are extremely high
(even hours are possible in extremely rare cases).

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_set_pedantic}
@deftypefn {} {int} unur_tdr_set_pedantic (UNUR_PAR* @var{parameters}, int @var{pedantic})
Sometimes it might happen that
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
has been executed
successfully. But when additional construction points are added by
adaptive rejection sampling, the algorithm detects that the
PDF is not T-concave.

With @var{pedantic} being @code{TRUE}, the
sampling routine is exchanged by a routine that simply returns
@code{UNUR_INFINITY}. Otherwise the new point is not added to the
list of construction points. At least the hat function remains
T-concave.

Setting @var{pedantic} to @code{FALSE} allows sampling from a
distribution which is ``almost'' T-concave and small errors are
tolerated. However it might happen that the hat function cannot be
improved significantly. When the hat functions that has been
constructed by the
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
call is extremely large then it
might happen that the generation times are extremely high
(even hours are possible in extremely rare cases).

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_tdr_eval_invcdfhat}
@deftypefn Function {double} unur_tdr_eval_invcdfhat (const @var{UNUR_GEN* generator}, double @var{u}, double* @var{hx}, double* @var{fx}, double* @var{sqx})
Evaluate the inverse of the CDF of the hat distribution at @var{u}.
As a side effect the values of the hat, the density, and the squeeze
at the computed point @i{x} are stored in @var{hx}, @var{fx}, and
@var{sqx}, respectively. However, these computations are suppressed
if the corresponding variable is set to @code{NULL}.

If @var{u} is out of the domain [0,1] then @code{unur_errno} is set
to @code{UNUR_ERR_DOMAIN} and the respective bound of
the domain of the distribution are returned (which is
@code{-UNUR_INFINITY} or @code{UNUR_INFINITY} in the case of
unbounded domains).

@emph{Important:}
This call does not work for variant @code{IA} (immediate
acceptance). In this case the hat CDF is evaluated as if
variant @code{PS} is used.

@emph{Notice}: This function always evaluates the inverse CDF of
the hat distribution. A call to
@ifhtml
@ref{funct:unur_tdr_chg_truncated,@command{unur_tdr_chg_truncated}}
@end ifhtml
@ifnothtml
@command{unur_tdr_chg_truncated}
@end ifnothtml
call
has no effect.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_tdr_eval_invcdfhat}
@deftypefn {} {double} unur_tdr_eval_invcdfhat (const @var{UNUR_GEN* generator}, double @var{u}, double* @var{hx}, double* @var{fx}, double* @var{sqx})
Evaluate the inverse of the CDF of the hat distribution at @var{u}.
As a side effect the values of the hat, the density, and the squeeze
at the computed point @i{x} are stored in @var{hx}, @var{fx}, and
@var{sqx}, respectively. However, these computations are suppressed
if the corresponding variable is set to @code{NULL}.

If @var{u} is out of the domain [0,1] then @code{unur_errno} is set
to @code{UNUR_ERR_DOMAIN} and the respective bound of
the domain of the distribution are returned (which is
@code{-UNUR_INFINITY} or @code{UNUR_INFINITY} in the case of
unbounded domains).

@emph{Important:}
This call does not work for variant @code{IA} (immediate
acceptance). In this case the hat CDF is evaluated as if
variant @code{PS} is used.

@emph{Notice}: This function always evaluates the inverse CDF of
the hat distribution. A call to
@ifhtml
@ref{funct:unur_tdr_chg_truncated,@command{unur_tdr_chg_truncated}}
@end ifhtml
@ifnothtml
@command{unur_tdr_chg_truncated}
@end ifnothtml
call
has no effect.
@end deftypefn
@end ifnotinfo




@c
@c end of tdr.h
@c -------------------------------------
@c -------------------------------------
@c utdr.h
@c

@page
@node UTDR
@subsection   UTDR  --  Universal Transformed Density Rejection

@table @i
@item Required:
T-concave PDF, mode, approximate area
@item Speed:
Set-up: moderate, Sampling: Moderate
@item Reinit:
supported
@item Reference:
@ifhtml
@ref{bib:HWa95,, [HWa95]}
@end ifhtml
@ifnothtml
[HWa95]
@end ifnothtml
@ifhtml
@ref{bib:HLD04,, [HLD04: Sect.4.5.4; Alg.4.4]}
@end ifhtml
@ifnothtml
[HLD04: Sect.4.5.4; Alg.4.4]
@end ifnothtml

@end table


UTDR is based on the transformed density rejection and uses
three almost optimal points for constructing hat and squeezes.
It works for all @i{T}-concave distributions with
@iftex
@math{T(x) = -1/\sqrt(x).}
@end iftex
@ifhtml
@html
<I>T</I>(<I>x</I>) = -1/sqrt(()<I>x</I>).
@end html
@end ifhtml
@ifinfo
@math{T(x) = -1/sqrt(x).}
@end ifinfo

It requires the PDF and the (exact) location of the mode.
Notice that if no mode is given at all, a (slow) numerical mode
finder will be used.
Moreover the approximate area below the given PDF is used.
(If no area is given for the distribution the algorithm assumes that it
is approximately 1.)
The rejection constant is bounded from above by 4
for all @i{T}-concave distributions.


@subsubheading How To Use


UTDR works for any continuous univariate distribution object with
given @i{T}-concave PDF (with
@iftex
@math{T(x) = -1/\sqrt{x},)}
@end iftex
@ifhtml
@html
<I>T</I>(<I>x</I>) = -1/sqrt(<I>x</I>),)
@end html
@end ifhtml
@ifinfo
@math{T(x) = -1/sqrt(x),)}
@end ifinfo
mode and approximate area below PDF.

When the PDF does not change at the mode for varying parameters, then
this value can be set with
@ifhtml
@ref{funct:unur_utdr_set_pdfatmode,@command{unur_utdr_set_pdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_utdr_set_pdfatmode}
@end ifnothtml
to avoid some
computations. Since this value will not be updated any more when the
parameters of the distribution are changed,
the
@ifhtml
@ref{funct:unur_utdr_chg_pdfatmode,@command{unur_utdr_chg_pdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_utdr_chg_pdfatmode}
@end ifnothtml
call is necessary to do this manually.

It is possible to change the parameters and the domain of the chosen
distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator object.
Notice, that derived parameters like the mode must also be (re-) set
if the parameters or the domain has be changed.
Moreover, if the PDF at the mode has been provided by a
@ifhtml
@ref{funct:unur_utdr_set_pdfatmode,@command{unur_utdr_set_pdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_utdr_set_pdfatmode}
@end ifnothtml
call, additionally
@ifhtml
@ref{funct:unur_utdr_chg_pdfatmode,@command{unur_utdr_chg_pdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_utdr_chg_pdfatmode}
@end ifnothtml
must be used (otherwise this call is
not necessary since then this figure is computed directly from
the PDF).

There exists a test mode that verifies whether the conditions for
the method are satisfied or not. It can be switched on by calling
@ifhtml
@ref{funct:unur_utdr_set_verify,@command{unur_utdr_set_verify}}
@end ifhtml
@ifnothtml
@command{unur_utdr_set_verify}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_utdr_chg_verify,@command{unur_utdr_chg_verify},}
@end ifhtml
@ifnothtml
@command{unur_utdr_chg_verify},
@end ifnothtml
respectively.
Notice however that sampling is slower then.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_utdr_new,unur_utdr_new}
@item @ref{funct:unur_utdr_set_pdfatmode,unur_utdr_set_pdfatmode}
@item @ref{funct:unur_utdr_set_cpfactor,unur_utdr_set_cpfactor}
@item @ref{funct:unur_utdr_set_deltafactor,unur_utdr_set_deltafactor}
@item @ref{funct:unur_utdr_set_verify,unur_utdr_set_verify}
@item @ref{funct:unur_utdr_chg_verify,unur_utdr_chg_verify}
@item @ref{funct:unur_utdr_chg_pdfatmode,unur_utdr_chg_pdfatmode}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_utdr_new}
@deftypefn Function {UNUR_PAR*} unur_utdr_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_utdr_new}
@deftypefn {} {UNUR_PAR*} unur_utdr_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_utdr_set_pdfatmode}
@deftypefn Function {int} unur_utdr_set_pdfatmode (UNUR_PAR* @var{parameters}, double @var{fmode})
Set pdf at mode.
When set, the PDF at the mode is never changed.
This is to avoid additional computations, when the PDF does not
change when parameters of the distributions vary.
It is only useful when the PDF at the mode does not change with
changing parameters for the distribution.

Default: not set.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_utdr_set_pdfatmode}
@deftypefn {} {int} unur_utdr_set_pdfatmode (UNUR_PAR* @var{parameters}, double @var{fmode})
Set pdf at mode.
When set, the PDF at the mode is never changed.
This is to avoid additional computations, when the PDF does not
change when parameters of the distributions vary.
It is only useful when the PDF at the mode does not change with
changing parameters for the distribution.

Default: not set.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_utdr_set_cpfactor}
@deftypefn Function {int} unur_utdr_set_cpfactor (UNUR_PAR* @var{parameters}, double @var{cp_factor})
Set factor for position of left and right construction point.
The @var{cp_factor} is used to find almost optimal construction
points for the hat function.
There is no need to change this factor in almost all situations.

Default is @code{0.664}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_utdr_set_cpfactor}
@deftypefn {} {int} unur_utdr_set_cpfactor (UNUR_PAR* @var{parameters}, double @var{cp_factor})
Set factor for position of left and right construction point.
The @var{cp_factor} is used to find almost optimal construction
points for the hat function.
There is no need to change this factor in almost all situations.

Default is @code{0.664}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_utdr_set_deltafactor}
@deftypefn Function {int} unur_utdr_set_deltafactor (UNUR_PAR* @var{parameters}, double @var{delta})
Set factor for replacing tangents by secants.
higher factors increase the rejection constant but reduces the risk of
serious round-off errors.
There is no need to change this factor it almost all situations.

Default is @code{1.e-5}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_utdr_set_deltafactor}
@deftypefn {} {int} unur_utdr_set_deltafactor (UNUR_PAR* @var{parameters}, double @var{delta})
Set factor for replacing tangents by secants.
higher factors increase the rejection constant but reduces the risk of
serious round-off errors.
There is no need to change this factor it almost all situations.

Default is @code{1.e-5}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_utdr_set_verify}
@anchor{funct:unur_utdr_chg_verify}
@deftypefn Function {int} unur_utdr_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx Function {int} unur_utdr_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the condition squeeze(@i{x}) <= PDF(@i{x}) <= hat(@i{x}) is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_utdr_set_verify}
@anchor{funct:unur_utdr_chg_verify}
@deftypefn {} {int} unur_utdr_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx {} {int} unur_utdr_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the condition squeeze(@i{x}) <= PDF(@i{x}) <= hat(@i{x}) is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_utdr_chg_pdfatmode}
@deftypefn Function {int} unur_utdr_chg_pdfatmode (UNUR_GEN* @var{generator}, double @var{fmode})
Change PDF at mode of distribution.
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
must be executed before sampling from the
generator again.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_utdr_chg_pdfatmode}
@deftypefn {} {int} unur_utdr_chg_pdfatmode (UNUR_GEN* @var{generator}, double @var{fmode})
Change PDF at mode of distribution.
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
must be executed before sampling from the
generator again.
@end deftypefn
@end ifnotinfo




@c
@c end of utdr.h
@c -------------------------------------
@c -------------------------------------
@c methods.dh
@c

@page
@node Methods_for_CEMP
@section   Methods for continuous empirical univariate distributions

@menu
* EMPK:: EMPirical distribution with Kernel smoothing
* EMPL:: EMPirical distribution with Linear interpolation
* HIST:: HISTogramm of empirical distribution
@end menu



@subheading Overview of methods

@include methods_cemp.texi

@subheading Example

@smallexample
@include ref_example_emp.texi
@end smallexample

@subheading Example (String API)

@smallexample
@include ref_example_emp_str.texi
@end smallexample



@c
@c end of methods.dh
@c -------------------------------------
@c -------------------------------------
@c empk.h
@c

@page
@node EMPK
@subsection   EMPK  --  EMPirical distribution with Kernel smoothing

@table @i
@item Required:
observed sample
@item Speed:
Set-up: slow (as sample is sorted), Sampling: fast (depends on kernel)
@item Reinit:
not implemented
@item Reference:
@ifhtml
@ref{bib:HLa00,, [HLa00]}
@end ifhtml
@ifnothtml
[HLa00]
@end ifnothtml
@ifhtml
@ref{bib:HLD04,, [HLD04: Sect.12.1.2]}
@end ifhtml
@ifnothtml
[HLD04: Sect.12.1.2]
@end ifnothtml

@end table


EMPK generates random variates from an empirical distribution that is
given by an observed sample. The idea is that simply choosing a random
point from the sample and to return it with some added noise results
in a method that has very nice properties, as it can be seen as sampling
from a kernel density estimate. If the underlying distribution is
continuous, especially the fine structur of the resulting empirical
distribution is much better than using only resampling without noise.

Clearly we have to decide about the density of the noise (called kernel)
and about the standard deviation of the noise.
The mathematical theory of kernel density estimation shows us that we
are comparatively free in choosing the kernel. It also supplies us with
a simple formula to compute the optimal standarddeviation of the noise,
called bandwidth (or window width) of the kernel.

The variance of the estimated density is slightly larger than
that of the observed sample. However, this can be easily
corrected if required.

There is also a correction (mirroring technique) for
distributions with non-negative support.

A simple robust reference method is implemented to find a good
standard deviation of the noise (i.e. the bandwidth of
kernel density estimation). For some cases
(e.g. densities with two or more sharp distinct peaks) there
kernel density estimation can be adjusted by changing the
smoothness factor and the so called beta factor.


@subsubheading How To Use


EMPK uses empirical distributions. The main parameter is the
choice if of kernel density. The most important kernels can be
set by
@ifhtml
@ref{funct:unur_empk_set_kernel,@command{unur_empk_set_kernel}.}
@end ifhtml
@ifnothtml
@command{unur_empk_set_kernel}.
@end ifnothtml
Additionally generators for other
kernels can be used by using
@ifhtml
@ref{funct:unur_empk_set_kernelgen,@command{unur_empk_set_kernelgen}}
@end ifhtml
@ifnothtml
@command{unur_empk_set_kernelgen}
@end ifnothtml
instead.
Additionally variance correction and a correction for
non-negative variates can be switched on.

The two other parameters (smoothing factor and beta factor) are
only useful for people knowing the theory of kernel density
estimation. It is not necessary to change them if
the true underlying distribution is somehow comparable with a
bell-shaped curve, even skewed or with some not too sharp extra peaks.
In all these cases the simple robust reference method implemented to
find a good standard deviation of the noise (i.e. the bandwidth of
kernel density estimation) should give sensible results.
However, it might be necessary to overwrite this automatic method
to find the bandwidth eg. when resampling from data with
two or more sharp distinct peaks. Then the distribution has nearly
discrete components as well and our automatic method may
easily choose too large a bandwidth which results in an
empirical distribution which is oversmoothed (i.e. it has
lower peaks than the original distribution). Then it
is recommended to decrease the bandwidth using the
@ifhtml
@ref{funct:unur_empk_set_smoothing,@command{unur_empk_set_smoothing}}
@end ifhtml
@ifnothtml
@command{unur_empk_set_smoothing}
@end ifnothtml
call. A smoothing factor of @code{1}
is the default. A smoothing factor of @code{0} leads to naive
resampling of the data. Thus an appropriate value between these
extremes should be choosen. We recommend to consult a reference
on kernel smoothing when doing so; but it is not a simple problem
to determine an optimal bandwidth for distributions with sharp peaks.

In general, for most applications it is perfectly ok to use the
default values offered. Unless you have some knowledge on
density estimation we do not recommend to change anything.
There are two exceptions:

@enumerate A
@item
In the case that the unknown underlying distribution is not continuous
but discrete you should "turn off" the adding of the noise by setting:

@example
unur_empk_set_smoothing(par, 0.)
@end example

@item
In the case that you are especially
interested in a fast sampling algorithm use the call
@example
unur_empk_set_kernel(par, UNUR_DISTR_BOXCAR);
@end example
to change the used noise distribution from the default Gaussian
distribution to the uniform distribution.
@end enumerate




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_empk_new,unur_empk_new}
@item @ref{funct:unur_empk_set_kernel,unur_empk_set_kernel}
@item @ref{funct:unur_empk_set_kernelgen,unur_empk_set_kernelgen}
@item @ref{funct:unur_empk_set_beta,unur_empk_set_beta}
@item @ref{funct:unur_empk_set_smoothing,unur_empk_set_smoothing}
@item @ref{funct:unur_empk_chg_smoothing,unur_empk_chg_smoothing}
@item @ref{funct:unur_empk_set_varcor,unur_empk_set_varcor}
@item @ref{funct:unur_empk_chg_varcor,unur_empk_chg_varcor}
@item @ref{funct:unur_empk_set_positive,unur_empk_set_positive}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_empk_new}
@deftypefn Function {UNUR_PAR*} unur_empk_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_empk_new}
@deftypefn {} {UNUR_PAR*} unur_empk_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_empk_set_kernel}
@deftypefn Function {int} unur_empk_set_kernel (UNUR_PAR* @var{parameters}, unsigned @var{kernel})
Select one of the supported kernel distributions. Currently the following
kernels are supported:

@table @code
@item UNUR_DISTR_GAUSSIAN
Gaussian (normal) kernel
@item UNUR_DISTR_EPANECHNIKOV
Epanechnikov kernel
@item UNUR_DISTR_BOXCAR
Boxcar (uniform, rectangular) kernel
@item UNUR_DISTR_STUDENT
t3 kernel (Student's distribution with 3 degrees of freedom)
@item UNUR_DISTR_LOGISTIC
logistic kernel
@end table

For other kernels (including kernels with Student's distribution
with other than 3 degrees of freedom) use the
@ifhtml
@ref{funct:unur_empk_set_kernelgen,@command{unur_empk_set_kernelgen}}
@end ifhtml
@ifnothtml
@command{unur_empk_set_kernelgen}
@end ifnothtml
call.

It is not possible to call
@ifhtml
@ref{funct:unur_empk_set_kernel,@command{unur_empk_set_kernel}}
@end ifhtml
@ifnothtml
@command{unur_empk_set_kernel}
@end ifnothtml
twice.

Default is the Gaussian kernel.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_empk_set_kernel}
@deftypefn {} {int} unur_empk_set_kernel (UNUR_PAR* @var{parameters}, unsigned @var{kernel})
Select one of the supported kernel distributions. Currently the following
kernels are supported:

@table @code
@item UNUR_DISTR_GAUSSIAN
Gaussian (normal) kernel
@item UNUR_DISTR_EPANECHNIKOV
Epanechnikov kernel
@item UNUR_DISTR_BOXCAR
Boxcar (uniform, rectangular) kernel
@item UNUR_DISTR_STUDENT
t3 kernel (Student's distribution with 3 degrees of freedom)
@item UNUR_DISTR_LOGISTIC
logistic kernel
@end table

For other kernels (including kernels with Student's distribution
with other than 3 degrees of freedom) use the
@ifhtml
@ref{funct:unur_empk_set_kernelgen,@command{unur_empk_set_kernelgen}}
@end ifhtml
@ifnothtml
@command{unur_empk_set_kernelgen}
@end ifnothtml
call.

It is not possible to call
@ifhtml
@ref{funct:unur_empk_set_kernel,@command{unur_empk_set_kernel}}
@end ifhtml
@ifnothtml
@command{unur_empk_set_kernel}
@end ifnothtml
twice.

Default is the Gaussian kernel.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_empk_set_kernelgen}
@deftypefn Function {int} unur_empk_set_kernelgen (UNUR_PAR* @var{parameters}, const @var{UNUR_GEN* kernelgen}, double @var{alpha}, double @var{kernelvar})
Set generator for the kernel used for density estimation.

@var{alpha} is used to compute the optimal bandwidth from the point of
view of minimizing the mean integrated square error (MISE).
It depends on the kernel K and is given by
@example
alpha(K) = Var(K)^(-2/5)@{ \int K(t)^2 dt@}^(1/5)
@end example
For standard kernels (see above) alpha is computed by the algorithm.

@var{kernvar} is the variance of the used kernel. It is only required
for the variance corrected version of density estimation (which is
used by default); otherwise it is ignored.
If @var{kernelvar} is nonpositive, variance correction is disabled.
For standard kernels (see above) @var{kernvar} is computed by the
algorithm.

It is not possible to call
@ifhtml
@ref{funct:unur_empk_set_kernelgen,@command{unur_empk_set_kernelgen}}
@end ifhtml
@ifnothtml
@command{unur_empk_set_kernelgen}
@end ifnothtml
after a standard kernel
has been selected by a
@ifhtml
@ref{funct:unur_empk_set_kernel,@command{unur_empk_set_kernel}}
@end ifhtml
@ifnothtml
@command{unur_empk_set_kernel}
@end ifnothtml
call.

Notice that the uniform random number generator of the kernel
generator is overwritten during the
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
call and at each
@ifhtml
@ref{funct:unur_chg_urng,@command{unur_chg_urng}}
@end ifhtml
@ifnothtml
@command{unur_chg_urng}
@end ifnothtml
call with the uniform generator used for the empirical
distribution.

Default is the Gaussian kernel.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_empk_set_kernelgen}
@deftypefn {} {int} unur_empk_set_kernelgen (UNUR_PAR* @var{parameters}, const @var{UNUR_GEN* kernelgen}, double @var{alpha}, double @var{kernelvar})
Set generator for the kernel used for density estimation.

@var{alpha} is used to compute the optimal bandwidth from the point of
view of minimizing the mean integrated square error (MISE).
It depends on the kernel K and is given by
@example
alpha(K) = Var(K)^(-2/5)@{ \int K(t)^2 dt@}^(1/5)
@end example
For standard kernels (see above) alpha is computed by the algorithm.

@var{kernvar} is the variance of the used kernel. It is only required
for the variance corrected version of density estimation (which is
used by default); otherwise it is ignored.
If @var{kernelvar} is nonpositive, variance correction is disabled.
For standard kernels (see above) @var{kernvar} is computed by the
algorithm.

It is not possible to call
@ifhtml
@ref{funct:unur_empk_set_kernelgen,@command{unur_empk_set_kernelgen}}
@end ifhtml
@ifnothtml
@command{unur_empk_set_kernelgen}
@end ifnothtml
after a standard kernel
has been selected by a
@ifhtml
@ref{funct:unur_empk_set_kernel,@command{unur_empk_set_kernel}}
@end ifhtml
@ifnothtml
@command{unur_empk_set_kernel}
@end ifnothtml
call.

Notice that the uniform random number generator of the kernel
generator is overwritten during the
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
call and at each
@ifhtml
@ref{funct:unur_chg_urng,@command{unur_chg_urng}}
@end ifhtml
@ifnothtml
@command{unur_chg_urng}
@end ifnothtml
call with the uniform generator used for the empirical
distribution.

Default is the Gaussian kernel.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_empk_set_beta}
@deftypefn Function {int} unur_empk_set_beta (UNUR_PAR* @var{parameters}, double @var{beta})
@var{beta} is used to compute the optimal bandwidth from the point
of view of minimizing the mean integrated square error (MISE).
@var{beta} depends on the (unknown) distribution of the sampled data
points.
By default Gaussian distribution is assumed for the sample
(@var{beta} = 1.3637439). There is no requirement to change
@var{beta}.

Default: @code{1.3637439}
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_empk_set_beta}
@deftypefn {} {int} unur_empk_set_beta (UNUR_PAR* @var{parameters}, double @var{beta})
@var{beta} is used to compute the optimal bandwidth from the point
of view of minimizing the mean integrated square error (MISE).
@var{beta} depends on the (unknown) distribution of the sampled data
points.
By default Gaussian distribution is assumed for the sample
(@var{beta} = 1.3637439). There is no requirement to change
@var{beta}.

Default: @code{1.3637439}
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_empk_set_smoothing}
@anchor{funct:unur_empk_chg_smoothing}
@deftypefn Function {int} unur_empk_set_smoothing (UNUR_PAR* @var{parameters}, double @var{smoothing})
@deftypefnx Function {int} unur_empk_chg_smoothing (UNUR_GEN* @var{generator}, double @var{smoothing})
Set and change the smoothing factor.
The smoothing factor controlles how ``smooth'' the resulting density
estimation will be. A smoothing factor equal to @code{0} results in naive
resampling. A very large smoothing factor (together with the
variance correction) results in a density which is approximately
equal to the kernel.
Default is 1 which results in a smoothing parameter minimising
the MISE (mean integrated squared error) if the data are not too
far away from normal. If a large smoothing factor is used, then
variance correction must be switched on.

Default: @code{1}
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_empk_set_smoothing}
@anchor{funct:unur_empk_chg_smoothing}
@deftypefn {} {int} unur_empk_set_smoothing (UNUR_PAR* @var{parameters}, double @var{smoothing})
@deftypefnx {} {int} unur_empk_chg_smoothing (UNUR_GEN* @var{generator}, double @var{smoothing})
Set and change the smoothing factor.
The smoothing factor controlles how ``smooth'' the resulting density
estimation will be. A smoothing factor equal to @code{0} results in naive
resampling. A very large smoothing factor (together with the
variance correction) results in a density which is approximately
equal to the kernel.
Default is 1 which results in a smoothing parameter minimising
the MISE (mean integrated squared error) if the data are not too
far away from normal. If a large smoothing factor is used, then
variance correction must be switched on.

Default: @code{1}
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_empk_set_varcor}
@anchor{funct:unur_empk_chg_varcor}
@deftypefn Function {int} unur_empk_set_varcor (UNUR_PAR* @var{parameters}, int @var{varcor})
@deftypefnx Function {int} unur_empk_chg_varcor (UNUR_GEN* @var{generator}, int @var{varcor})
Switch variance correction in generator on/off.
If @var{varcor} is @code{TRUE} then the variance of the used
density estimation is the same as the sample variance. However this
increases the MISE of the estimation a little bit.

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_empk_set_varcor}
@anchor{funct:unur_empk_chg_varcor}
@deftypefn {} {int} unur_empk_set_varcor (UNUR_PAR* @var{parameters}, int @var{varcor})
@deftypefnx {} {int} unur_empk_chg_varcor (UNUR_GEN* @var{generator}, int @var{varcor})
Switch variance correction in generator on/off.
If @var{varcor} is @code{TRUE} then the variance of the used
density estimation is the same as the sample variance. However this
increases the MISE of the estimation a little bit.

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_empk_set_positive}
@deftypefn Function {int} unur_empk_set_positive (UNUR_PAR* @var{parameters}, int @var{positive})
If @var{positive} is @code{TRUE} then only nonnegative random variates are
generated. This is done by means of a mirroring technique.

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_empk_set_positive}
@deftypefn {} {int} unur_empk_set_positive (UNUR_PAR* @var{parameters}, int @var{positive})
If @var{positive} is @code{TRUE} then only nonnegative random variates are
generated. This is done by means of a mirroring technique.

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo




@c
@c end of empk.h
@c -------------------------------------
@c -------------------------------------
@c empl.h
@c

@page
@node EMPL
@subsection   EMPL  --  EMPirical distribution with Linear interpolation

@table @i
@item Required:
observed sample
@item Speed:
Set-up: slow (as sample is sorted), Sampling: very fast (inversion)
@item Reinit:
not implemented
@item Reference:
@ifhtml
@ref{bib:HLa00,, [HLa00]}
@end ifhtml
@ifnothtml
[HLa00]
@end ifnothtml
@ifhtml
@ref{bib:HLD04,, [HLD04: Sect.12.1.3]}
@end ifhtml
@ifnothtml
[HLD04: Sect.12.1.3]
@end ifnothtml

@end table


EMPL generates random variates from an empirical distribution
that is given by an observed sample. This is done by linear
interpolation of the empirical CDF. Although this
method is suggested in the books of Law and Kelton (2000) and
Bratly, Fox, and Schrage (1987) we do not recommend this method at
all since it has many theoretical drawbacks:
The variance of empirical distribution function does not
coincide with the variance of the given sample. Moreover,
when the sample increases the empirical density function
does not converge to the density of the underlying random
variate. Notice that the range of the generated point set is
always given by the range of the given sample.

This method is provided in UNU.RAN for the sake of
completeness. We always recommend to use method EMPK
(@pxref{EMPK,,EMPirical distribution with Kernel smoothing}).

If the data seem to be far away from having a bell shaped
histogram, then we think that naive resampling is still better
than linear interpolation.


@subsubheading How To Use


EMPL creates and samples from an empiral distribution by linear
interpolation of the empirical CDF. There are no parameters to
set.

@noindent
@emph{Important}: We do not recommend to use this method! Use
method EMPK
(@pxref{EMPK,,EMPirical distribution with Kernel smoothing})
instead.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_empl_new,unur_empl_new}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_empl_new}
@deftypefn Function {UNUR_PAR*} unur_empl_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_empl_new}
@deftypefn {} {UNUR_PAR*} unur_empl_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo




@c
@c end of empl.h
@c -------------------------------------
@c -------------------------------------
@c hist.h
@c

@page
@node HIST
@subsection   HIST  --  HISTogramm of empirical distribution

@table @i
@item Required:
histogram
@item Speed:
Set-up: moderate, Sampling: fast
@item Reinit:
not implemented
@end table


Method HIST generates random variates from an empirical distribution
that is given as histogram. Sampling is done using the inversion
method.

If observed (raw) data are provided we recommend method EMPK
(@pxref{EMPK,,EMPirical distribution with Kernel smoothing})
instead of compting a histogram as this reduces information.


@subsubheading How To Use


Method HIST uses empirical distributions that are given as a
histgram. There are no optional parameters.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_hist_new,unur_hist_new}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_hist_new}
@deftypefn Function {UNUR_PAR*} unur_hist_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hist_new}
@deftypefn {} {UNUR_PAR*} unur_hist_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo




@c
@c end of hist.h
@c -------------------------------------
@c -------------------------------------
@c methods.dh
@c

@page
@node Methods_for_CVEC
@section   Methods for continuous multivariate distributions

@menu
* MVSTD:: MultiVariate continuous STandarD distributions
* MVTDR:: Multi-Variate Transformed Density Rejection
* NORTA:: NORmal To Anything
* VNROU:: Multivariate Naive Ratio-Of-Uniforms method
@end menu



@subheading Overview of methods

@include methods_cvec.texi



@c
@c end of methods.dh
@c -------------------------------------
@c -------------------------------------
@c mvstd.h
@c

@page
@node MVSTD
@subsection   MVSTD  --  MultiVariate continuous STandarD distributions

@table @i
@item Required:
standard distribution from UNU.RAN library (@pxref{Stddist,,Standard distributions}).
@item Speed:
depends on distribution and generator
@item Reinit:
supported
@end table


MVSTD is a wrapper for special generators for multivariate
continuous standard distributions. It only works for
distributions in the UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions}).
If a distribution object is provided that is build from scratch,
or if no special generator for the given standard distribution is
provided, the @code{NULL} pointer is returned.


@subsubheading How To Use


Create a distribution object for a standard distribution
from the UNU.RAN library (@pxref{Stddist,,Standard distributions}).

Sampling from truncated distributions (which can be constructed by
changing the default domain of a distribution by means of
@ifhtml
@ref{funct:unur_distr_cvec_set_domain_rect,@command{unur_distr_cvec_set_domain_rect}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_domain_rect}
@end ifnothtml
call) is not possible.

It is possible to change the parameters and the domain of the chosen
distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator object.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_mvstd_new,unur_mvstd_new}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_mvstd_new}
@deftypefn Function {UNUR_PAR*} unur_mvstd_new (const @var{UNUR_DISTR* distribution})
Get default parameters for new generator. It requires a distribution object
for a multivariate continuous distribution from the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions}).
Using a truncated distribution is not possible.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_mvstd_new}
@deftypefn {} {UNUR_PAR*} unur_mvstd_new (const @var{UNUR_DISTR* distribution})
Get default parameters for new generator. It requires a distribution object
for a multivariate continuous distribution from the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions}).
Using a truncated distribution is not possible.
@end deftypefn
@end ifnotinfo




@c
@c end of mvstd.h
@c -------------------------------------
@c -------------------------------------
@c mvtdr.h
@c

@page
@node MVTDR
@subsection   MVTDR  --  Multi-Variate Transformed Density Rejection

@table @i
@item Required:
log-concave (log)PDF, gradient of (log)PDF
@item Optional:
mode
@item Speed:
Set-up: slow, Sampling: depends on dimension
@item Reinit:
not implemented
@item Reference:
@ifhtml
@ref{bib:HLD04,, [HLD04: Sect.11.3.4; Alg.11.15.]}
@end ifhtml
@ifnothtml
[HLD04: Sect.11.3.4; Alg.11.15.]
@end ifnothtml
@ifhtml
@ref{bib:LJa98,, [LJa98]}
@end ifhtml
@ifnothtml
[LJa98]
@end ifnothtml

@end table


MVTDR a multivariate version of the Transformed Density Rection
(@pxref{TDR}) that works for log-concave densities.
For this method the domain of the distribution is partitioned
into cones with the mode (or the center) of the distribution as
their (common) vertex. The hat function is then constructed as
tangent planes of the transformed density in each of these
cones. The respective construction points lie on the central
lines in the cones through the vertex. The point is chosen such
that the hat is minimal among all such points (see the given
references for more details).

The cones are created by starting with the orthants of the reals
space. These are then iteratively split when the volume below
the hat in such cones is too large. Thus an increasing number of
cones results in a better fitting hat function.
Notice however, that the required number of cones increases
exponentially with the number of dimension.
Moreover, due to the construction the rejection does not
converge to 1 and remains strictly larger than 1.

For distributions with bounded domains the cones are cut to
pyramids that cover the domain.


@subsubheading How To Use


Create a multivariate generator object that contains the PDF and
its gradient. This object also should contain the mode of the
distribution (or a point nearby should be provided as center of
the distribution).

The method has three parameter to adjust the method for the given
distribution:

@table @code
@item stepsmin
Minimal number of iterations for splitting cones.
Notice that we start with 2^dim initial cones and that we arrive
at 2^(dim+stepsmin) cones after these splits. So this number
must be set with care. It can be set by a
@ifhtml
@ref{funct:unur_mvtdr_set_stepsmin,@command{unur_mvtdr_set_stepsmin}}
@end ifhtml
@ifnothtml
@command{unur_mvtdr_set_stepsmin}
@end ifnothtml
call.

@item boundsplitting
Cones where the volume below the hat is relatively large
(i.e. larger than the average volume over all cones times
@code{boundsplitting} are further split.
This parameter can set via a
@ifhtml
@ref{funct:unur_mvtdr_set_boundsplitting,@command{unur_mvtdr_set_boundsplitting}}
@end ifhtml
@ifnothtml
@command{unur_mvtdr_set_boundsplitting}
@end ifnothtml
call.

@item maxcones
The maximum number of generated cones. When this number is
reached, the initialization routine is stopped. Notice that the
rejection constant can be still prohibitive large.
This parameter can set via a
@ifhtml
@ref{funct:unur_mvtdr_set_maxcones,@command{unur_mvtdr_set_maxcones}}
@end ifhtml
@ifnothtml
@command{unur_mvtdr_set_maxcones}
@end ifnothtml
call.

@end table

Setting of these parameter can be quite tricky. The default
settings lead to hat functions where the volume below the hat is
similar in each cone. However, there might be some problems with
distributions with higher correlations, since then too few cones
are created. Then it might be necessary to increase the values
for @code{stepsmin} and @code{maxcones} and to set
@code{boundsplitting} to @code{0}.

The number of cones and the total volume below the hat can be
controlled using the respective calls
@ifhtml
@ref{funct:unur_mvtdr_get_ncones,@command{unur_mvtdr_get_ncones}}
@end ifhtml
@ifnothtml
@command{unur_mvtdr_get_ncones}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_mvtdr_get_hatvol,@command{unur_mvtdr_get_hatvol}.}
@end ifhtml
@ifnothtml
@command{unur_mvtdr_get_hatvol}.
@end ifnothtml
Notice, that the rejection constant is
bounded from below by some figure (larger than 1) that depends
on the dimension.

Unfortunately, the algorithm cannot detect the quality of the
constructed hat.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_mvtdr_new,unur_mvtdr_new}
@item @ref{funct:unur_mvtdr_set_stepsmin,unur_mvtdr_set_stepsmin}
@item @ref{funct:unur_mvtdr_set_boundsplitting,unur_mvtdr_set_boundsplitting}
@item @ref{funct:unur_mvtdr_set_maxcones,unur_mvtdr_set_maxcones}
@item @ref{funct:unur_mvtdr_get_ncones,unur_mvtdr_get_ncones}
@item @ref{funct:unur_mvtdr_get_hatvol,unur_mvtdr_get_hatvol}
@item @ref{funct:unur_mvtdr_set_verify,unur_mvtdr_set_verify}
@item @ref{funct:unur_mvtdr_chg_verify,unur_mvtdr_chg_verify}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_mvtdr_new}
@deftypefn Function {UNUR_PAR*} unur_mvtdr_new (const @var{UNUR_DISTR* distribution})
Get parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_mvtdr_new}
@deftypefn {} {UNUR_PAR*} unur_mvtdr_new (const @var{UNUR_DISTR* distribution})
Get parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_mvtdr_set_stepsmin}
@deftypefn Function {int} unur_mvtdr_set_stepsmin (UNUR_PAR* @var{parameters}, int @var{stepsmin})
Set minimum number of triangulation step for each starting cone.
@var{stepsmin} must be nonnegative.

Default: @code{5}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_mvtdr_set_stepsmin}
@deftypefn {} {int} unur_mvtdr_set_stepsmin (UNUR_PAR* @var{parameters}, int @var{stepsmin})
Set minimum number of triangulation step for each starting cone.
@var{stepsmin} must be nonnegative.

Default: @code{5}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_mvtdr_set_boundsplitting}
@deftypefn Function {int} unur_mvtdr_set_boundsplitting (UNUR_PAR* @var{parameters}, double @var{boundsplitting})
Set bound for splitting cones. All cones are split which have a
volume below the hat that is greater than @var{bound_splitting} times
the average over all volumes. However, the number given by the
@ifhtml
@ref{funct:unur_mvtdr_set_maxcones,@command{unur_mvtdr_set_maxcones}}
@end ifhtml
@ifnothtml
@command{unur_mvtdr_set_maxcones}
@end ifnothtml
is not exceeded.
Notice that the later number is always reached
if @var{bound_splitting} is less than 1.

Default: @code{1.5}
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_mvtdr_set_boundsplitting}
@deftypefn {} {int} unur_mvtdr_set_boundsplitting (UNUR_PAR* @var{parameters}, double @var{boundsplitting})
Set bound for splitting cones. All cones are split which have a
volume below the hat that is greater than @var{bound_splitting} times
the average over all volumes. However, the number given by the
@ifhtml
@ref{funct:unur_mvtdr_set_maxcones,@command{unur_mvtdr_set_maxcones}}
@end ifhtml
@ifnothtml
@command{unur_mvtdr_set_maxcones}
@end ifnothtml
is not exceeded.
Notice that the later number is always reached
if @var{bound_splitting} is less than 1.

Default: @code{1.5}
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_mvtdr_set_maxcones}
@deftypefn Function {int} unur_mvtdr_set_maxcones (UNUR_PAR* @var{parameters}, int @var{maxcones})
Set maximum number of cones.

Notice that this number is always increased to
@math{2^(dim+stepsmin)}
where @i{dim} is the dimension of the
distribution object and @i{stepsmin} the given mimimum number of
triangulation steps.

Notice: For higher dimensions and/or higher correlations between the
coordinates of the random vector the required number of cones can
be very high. A too small maximum number of cones can lead to
a very high rejection constant.

Default: @code{10000}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_mvtdr_set_maxcones}
@deftypefn {} {int} unur_mvtdr_set_maxcones (UNUR_PAR* @var{parameters}, int @var{maxcones})
Set maximum number of cones.

Notice that this number is always increased to
@iftex
@math{2^{dim+stepsmin}}
@end iftex
@ifhtml
@html
2<SUP><I>dim</I>+<I>stepsmin</I></SUP>
@end html
@end ifhtml
where @i{dim} is the dimension of the
distribution object and @i{stepsmin} the given mimimum number of
triangulation steps.

Notice: For higher dimensions and/or higher correlations between the
coordinates of the random vector the required number of cones can
be very high. A too small maximum number of cones can lead to
a very high rejection constant.

Default: @code{10000}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_mvtdr_get_ncones}
@deftypefn Function {int} unur_mvtdr_get_ncones (const @var{UNUR_GEN* generator})
Get the number of cones used for the hat function of the
@var{generator}.
(In case of an error @code{0} is returned.)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_mvtdr_get_ncones}
@deftypefn {} {int} unur_mvtdr_get_ncones (const @var{UNUR_GEN* generator})
Get the number of cones used for the hat function of the
@var{generator}.
(In case of an error @code{0} is returned.)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_mvtdr_get_hatvol}
@deftypefn Function {double} unur_mvtdr_get_hatvol (const @var{UNUR_GEN* generator})
Get the volume below the hat for the @var{generator}.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_mvtdr_get_hatvol}
@deftypefn {} {double} unur_mvtdr_get_hatvol (const @var{UNUR_GEN* generator})
Get the volume below the hat for the @var{generator}.
(In case of an error @code{UNUR_INFINITY} is returned.)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_mvtdr_set_verify}
@anchor{funct:unur_mvtdr_chg_verify}
@deftypefn Function {int} unur_mvtdr_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx Function {int} unur_mvtdr_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the condition squeeze(@i{x}) <= PDF(@i{x}) <= hat(@i{x}) is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_mvtdr_set_verify}
@anchor{funct:unur_mvtdr_chg_verify}
@deftypefn {} {int} unur_mvtdr_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx {} {int} unur_mvtdr_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the condition squeeze(@i{x}) <= PDF(@i{x}) <= hat(@i{x}) is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo




@c
@c end of mvtdr.h
@c -------------------------------------
@c -------------------------------------
@c norta.h
@c

@page
@node NORTA
@subsection   NORTA  --  NORmal To Anything

@table @i
@item Required:
rank correlation matrix, marginal distributions
@item Speed:
Set-up: slow, Sampling: depends on dimension
@item Reinit:
not implemented
@item Reference:
@ifhtml
@ref{bib:HLD04,, [HLD04: Sect.12.5.2; Alg.12.11.]}
@end ifhtml
@ifnothtml
[HLD04: Sect.12.5.2; Alg.12.11.]
@end ifnothtml

@end table


NORTA (NORmal to anything) is a model to get random vectors with
given marginal distributions and rank correlation.

@strong{Important:} Notice that marginal distribution and (rank)
correlation structure do not uniquely define a multivariate
distribution. Thus there are many other (more or less sensible)
models.

In the NORTA model multinormal random variates with the given
(Spearman's) rank correlations are generated.
In a second step the (standard normal distributed) marginal variates
are transformed by means of the CDF of the normal distribution to get
uniform marginals. The resulting random vectors have uniform
marginals and the desired rank correlation between its components.
Such a random vector is called 'copula'.

By means of the inverse CDF the uniform marginals are then
transformed into the target marginal distributions. This
transformation does not change the rank correlation.

For the generation of the multinormal distribution the
(Spearman's) rank correlation matrix is transformed into the
corresponding (Pearson) correlation matrix. Samples from the
resulting multinormal distribution are generated by means of the
Cholesky decomposition of the covariance matrix.

It can happen that the desired rank correlation matrix is not
feasible, i.e., it cannot occur as rank correlation matrix of a
multinormal distribution. The resulting "covariance" matrix is
not positive definite. In this case an eigenvector correction
method is used. Then all non-positive eigenvalues are set to a
small positive value and hence the rank correlation matrix of the
generated random vectors is "close" to the desired matrix.


@subsubheading How To Use


Create a multivariate generator object and set marginal
distributions using
@ifhtml
@ref{funct:unur_distr_cvec_set_marginals,@command{unur_distr_cvec_set_marginals},}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_marginals},
@end ifnothtml
@ifhtml
@ref{funct:unur_distr_cvec_set_marginal_array,@command{unur_distr_cvec_set_marginal_array}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_marginal_array}
@end ifnothtml
, or
@ifhtml
@ref{funct:unur_distr_cvec_set_marginal_list,@command{unur_distr_cvec_set_marginal_list}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_marginal_list}.
@end ifnothtml
(Do not use the corresponding calls for the standard
marginal distributions).

When the domain of the multivariate distribution is set by of a
@ifhtml
@ref{funct:unur_distr_cvec_set_domain_rect,@command{unur_distr_cvec_set_domain_rect}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_domain_rect}
@end ifnothtml
call then the domain of each
of the marginal distributions is truncated by the respective
coordinates of the given rectangle.

If copulae are required (i.e. multivariate distributions with
uniform marginals) such a generator object can be created by
means of
@ifhtml
@ref{funct:unur_distr_copula,@command{unur_distr_copula}}
@end ifhtml
@ifnothtml
@command{unur_distr_copula}
@end ifnothtml
.

There are no optional parameters for this method.



@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_norta_new,unur_norta_new}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_norta_new}
@deftypefn Function {UNUR_PAR*} unur_norta_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_norta_new}
@deftypefn {} {UNUR_PAR*} unur_norta_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo




@c
@c end of norta.h
@c -------------------------------------
@c -------------------------------------
@c vnrou.h
@c

@page
@node VNROU
@subsection   VNROU  --  Multivariate Naive Ratio-Of-Uniforms method

@table @i
@item Required:
PDF
@item Optional:
mode, center, bounding rectangle for acceptance region
@item Speed:
Set-up: fast or slow, Sampling: slow
@item Reinit:
supported
@item Reference:
@ifhtml
@ref{bib:WGS91,, [WGS91]}
@end ifhtml
@ifnothtml
[WGS91]
@end ifnothtml

@end table


VNROU is an implementation of the multivariate
ratio-of-uniforms method which uses a (minimal) bounding
hyper-rectangle, see also @ref{Ratio-of-Uniforms}.  It uses an
additional parameter @i{r} that can be used for adjusting the
algorithm to the given distribution to improve performance
and/or to make this method applicable.  Larger values of
@i{r} increase the class of distributions for which the
method works at the expense of higher rejection
constants. Moreover, this implementation uses the center
@iftex
@math{\mu}
@end iftex
@ifhtml
@html
mu
@end html
@end ifhtml
@ifinfo
@math{mu}
@end ifinfo
of the distribution (which is set to the mode or
mean by default, see
@ifhtml
@ref{funct:unur_distr_cvec_get_center,@command{unur_distr_cvec_get_center}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_get_center}
@end ifnothtml
for details of
its default values).

The minimal bounding has then the coordinates
@iftex

@quotation
@math{ v^+ = \sup\limits_{x} (f(x))^{1/r\,d+1}, \hfil\break u^-_i = \inf\limits_{x_i} (x_i-\mu_i) (f(x))^{r/r\,d+1}, \hfil\break u^+_i = \sup\limits_{x_i} (x_i-\mu_i) (f(x))^{r/r\,d+1}, }
@end quotation

@end iftex
@ifhtml
@quotation
@html
<I>v</I><SUP>+</SUP> = sup_<I>x</I> (<I>f</I>(<I>x</I>))<SUP>1/<I>r</I> <I>d</I>+1</SUP>, @*<I>u</I><SUP>-</SUP>_<I>i</I> = inf_<I>x</I>_<I>i</I> (<I>x</I>_<I>i</I>- mu_<I>i</I>) (<I>f</I>(<I>x</I>))<SUP><I>r</I>/<I>r</I> <I>d</I>+1</SUP>, @*<I>u</I><SUP>+</SUP>_<I>i</I> = sup_<I>x</I>_<I>i</I> (<I>x</I>_<I>i</I>- mu_<I>i</I>) (<I>f</I>(<I>x</I>))<SUP><I>r</I>/<I>r</I> <I>d</I>+1</SUP>,
@end html
@end quotation
@end ifhtml
@ifinfo
@quotation
@math{v^+ = sup_(x) (f(x))^(1/r d+1), @*u^-_i = inf_(x_i) (x_i- mu_i) (f(x))^(r/r d+1), @*u^+_i = sup_(x_i) (x_i- mu_i) (f(x))^(r/r d+1),}
@end quotation
@end ifinfo

@noindent
where
@iftex
@math{x_i}
@end iftex
@ifhtml
@html
<I>x</I>_<I>i</I>
@end html
@end ifhtml
@ifinfo
@math{x_i}
@end ifinfo
is the @i{i}-th coordinate of point @i{x};
@iftex
@math{\mu_i}
@end iftex
@ifhtml
@html
mu_<I>i</I>
@end html
@end ifhtml
@ifinfo
@math{mu_i}
@end ifinfo
is the @i{i}-th coordinate of the center
@iftex
@math{\mu.}
@end iftex
@ifhtml
@html
mu.
@end html
@end ifhtml
@ifinfo
@math{mu.}
@end ifinfo
@iftex
@math{d}
@end iftex
@ifhtml
@html
<I>d</I>
@end html
@end ifhtml
@ifinfo
@math{d}
@end ifinfo
denotes the dimension of the distribution.
These bounds can either be given directly, or are computed
automatically by means of an numerical routine
by Hooke and Jeeves
@ifhtml
@ref{bib:HJa61,, [HJa61]}
@end ifhtml
@ifnothtml
[HJa61]
@end ifnothtml
called direct search
(see @file{src/utils/hooke.c} for further references and
details). Of course this algorithm can fail, especially when
this rectangle is not bounded.

It is important to note that the algorithm works with
@iftex
@math{PDF(x-center)}
@end iftex
@ifhtml
@html
<I>PDF</I>(<I>x</I>-<I>center</I>)
@end html
@end ifhtml
@ifinfo
@math{PDF(x-center)}
@end ifinfo
instead of
@iftex
@math{PDF(x),}
@end iftex
@ifhtml
@html
<I>PDF</I>(<I>x</I>),
@end html
@end ifhtml
@ifinfo
@math{PDF(x),}
@end ifinfo
i.e. the bounding rectangle has to be
provided for
@iftex
@math{PDF(x-center).}
@end iftex
@ifhtml
@html
<I>PDF</I>(<I>x</I>-<I>center</I>).
@end html
@end ifhtml
@ifinfo
@math{PDF(x-center).}
@end ifinfo
This is important as otherwise the acceptance region can become
a very long and skinny ellipsoid along a diagonal of the (huge)
bounding rectangle.

VNROU is based on the rejection method (@pxref{Rejection}),
and it is important to note that the acceptance probability
decreases exponentially with dimension. Thus even for moderately
many dimensions (e.g. 5) the number of repetitions to get one
random vector can be prohibitively large and the algorithm seems
to stay in an infinite loop.


@subsubheading How To Use


For using the VNROU method UNU.RAN needs the PDF of the
distribution. Additionally, the parameter @i{r} can be set via
a
@ifhtml
@ref{funct:unur_vnrou_set_r,@command{unur_vnrou_set_r}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_r}
@end ifnothtml
call. Notice that the acceptance
probability decreases when @i{r} is increased. On the other
hand is is more unlikely that the bounding rectangle does not
exist if @i{r} is small.

A bounding rectangle can be given by the
@ifhtml
@ref{funct:unur_vnrou_set_u,@command{unur_vnrou_set_u}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_u}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_vnrou_set_v,@command{unur_vnrou_set_v}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_v}
@end ifnothtml
calls.

@emph{Important:} The bounding rectangle has to be
provided for the function
@iftex
@math{PDF(x-center)!}
@end iftex
@ifhtml
@html
<I>PDF</I>(<I>x</I>-<I>center</I>)!
@end html
@end ifhtml
@ifinfo
@math{PDF(x-center)!}
@end ifinfo
Notice that @code{center} is the center of the given
distribution, see
@ifhtml
@ref{funct:unur_distr_cvec_set_center,@command{unur_distr_cvec_set_center}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_center}.
@end ifnothtml
If in doubt or if this value is not optimal, it can be changed
(overridden) by a
@ifhtml
@ref{funct:unur_distr_cvec_set_center,@command{unur_distr_cvec_set_center}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_center}
@end ifnothtml
call.

If the coordinates of the bounding rectangle are not provided by
the user then the minimal bounding rectangle is computed
automatically.

By means of
@ifhtml
@ref{funct:unur_vnrou_set_verify,@command{unur_vnrou_set_verify}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_verify}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_vnrou_chg_verify,@command{unur_vnrou_chg_verify}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_chg_verify}
@end ifnothtml
one can run the sampling algorithm in a checking mode, i.e., in
every cycle of the rejection loop it is checked whether the used
rectangle indeed enclosed the acceptance region of the
distribution. When in doubt (e.g., when it is not clear whether
the numerical routine has worked correctly) this can be used to
run a small Monte Carlo study.

@strong{Important:}
The rejection constant (i.e. the expected number of iterations
for generationg one random vector) can be extremely high, in
particular when the dimension is 4 or higher.
Then the algorithm will perform almost infinite loops.
Thus it is recommended to read the volume below the hat function
by means of the
@ifhtml
@ref{funct:unur_vnrou_get_volumehat,@command{unur_vnrou_get_volumehat}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_get_volumehat}
@end ifnothtml
call. The returned
number divided by the volume below the PDF (which is 1 in case
of a normalized PDF) gives the rejection constant.

It is possible to change the parameters and the domain of the chosen
distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator object.
Notice, that the coordinates of a bounding rectangle given by
@ifhtml
@ref{funct:unur_vnrou_set_u,@command{unur_vnrou_set_u}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_u}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_vnrou_set_v,@command{unur_vnrou_set_v}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_v}
@end ifnothtml
calls are used also
when the generator is reused. These can be changed by means of
@ifhtml
@ref{funct:unur_vnrou_chg_u,@command{unur_vnrou_chg_u}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_chg_u}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_vnrou_chg_v,@command{unur_vnrou_chg_v}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_chg_v}
@end ifnothtml
calls.
(If no such coordinates have been given, then they are computed
numerically during the reinitialization proceedure.)




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_vnrou_new,unur_vnrou_new}
@item @ref{funct:unur_vnrou_set_u,unur_vnrou_set_u}
@item @ref{funct:unur_vnrou_chg_u,unur_vnrou_chg_u}
@item @ref{funct:unur_vnrou_set_v,unur_vnrou_set_v}
@item @ref{funct:unur_vnrou_chg_v,unur_vnrou_chg_v}
@item @ref{funct:unur_vnrou_set_r,unur_vnrou_set_r}
@item @ref{funct:unur_vnrou_set_verify,unur_vnrou_set_verify}
@item @ref{funct:unur_vnrou_chg_verify,unur_vnrou_chg_verify}
@item @ref{funct:unur_vnrou_get_volumehat,unur_vnrou_get_volumehat}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_vnrou_new}
@deftypefn Function {UNUR_PAR*} unur_vnrou_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_vnrou_new}
@deftypefn {} {UNUR_PAR*} unur_vnrou_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_vnrou_set_u}
@deftypefn Function {int} unur_vnrou_set_u (UNUR_PAR* @var{parameters}, double* @var{umin}, double* @var{umax})
Sets left and right boundaries of bounding hyper-rectangle.
If no values are given, the boundary of the minimal bounding
hyper-rectangle is computed numerically.

@strong{Important}: The boundaries are those of the density shifted
by the center of the distribution, i.e., for the
function
@math{PDF(x-center)!}

@emph{Notice}: Computing the minimal bounding rectangle may fail
under some circumstances. Moreover, for multimodal distributions
the bounds might be too small as only local extrema are computed.
Nevertheless, for log-concave distributions it should work.

Default: not set (i.e. computed automatically)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_vnrou_set_u}
@deftypefn {} {int} unur_vnrou_set_u (UNUR_PAR* @var{parameters}, double* @var{umin}, double* @var{umax})
Sets left and right boundaries of bounding hyper-rectangle.
If no values are given, the boundary of the minimal bounding
hyper-rectangle is computed numerically.

@strong{Important}: The boundaries are those of the density shifted
by the center of the distribution, i.e., for the
function
@iftex
@math{PDF(x-center)!}
@end iftex
@ifhtml
@html
<I>PDF</I>(<I>x</I>-<I>center</I>)!
@end html
@end ifhtml

@emph{Notice}: Computing the minimal bounding rectangle may fail
under some circumstances. Moreover, for multimodal distributions
the bounds might be too small as only local extrema are computed.
Nevertheless, for log-concave distributions it should work.

Default: not set (i.e. computed automatically)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_vnrou_chg_u}
@deftypefn Function {int} unur_vnrou_chg_u (UNUR_GEN* @var{generator}, double* @var{umin}, double* @var{umax})
Change left and right boundaries of bounding hyper-rectangle.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_vnrou_chg_u}
@deftypefn {} {int} unur_vnrou_chg_u (UNUR_GEN* @var{generator}, double* @var{umin}, double* @var{umax})
Change left and right boundaries of bounding hyper-rectangle.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_vnrou_set_v}
@deftypefn Function {int} unur_vnrou_set_v (UNUR_PAR* @var{parameters}, double @var{vmax})
Set upper boundary for bounding hyper-rectangle.
If no values are given, the density at the mode is evaluated.
If no mode is given for the distribution it is computed
numerically (and might fail).

Default: not set (i.e. computed automatically)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_vnrou_set_v}
@deftypefn {} {int} unur_vnrou_set_v (UNUR_PAR* @var{parameters}, double @var{vmax})
Set upper boundary for bounding hyper-rectangle.
If no values are given, the density at the mode is evaluated.
If no mode is given for the distribution it is computed
numerically (and might fail).

Default: not set (i.e. computed automatically)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_vnrou_chg_v}
@deftypefn Function {int} unur_vnrou_chg_v (UNUR_GEN* @var{generator}, double @var{vmax})
Change upper boundary for bounding hyper-rectangle.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_vnrou_chg_v}
@deftypefn {} {int} unur_vnrou_chg_v (UNUR_GEN* @var{generator}, double @var{vmax})
Change upper boundary for bounding hyper-rectangle.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_vnrou_set_r}
@deftypefn Function {int} unur_vnrou_set_r (UNUR_PAR* @var{parameters}, double @var{r})
Sets the parameter @var{r} of the generalized multivariate
ratio-of-uniforms method.

@emph{Notice}: This parameter must satisfy @var{r}>0.

Default: @code{1}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_vnrou_set_r}
@deftypefn {} {int} unur_vnrou_set_r (UNUR_PAR* @var{parameters}, double @var{r})
Sets the parameter @var{r} of the generalized multivariate
ratio-of-uniforms method.

@emph{Notice}: This parameter must satisfy @var{r}>0.

Default: @code{1}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_vnrou_set_verify}
@deftypefn Function {int} unur_vnrou_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
Turn verifying of algorithm while sampling on/off.

If the condition PDF(@i{x}) <= hat(@i{x}) is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_vnrou_set_verify}
@deftypefn {} {int} unur_vnrou_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
Turn verifying of algorithm while sampling on/off.

If the condition PDF(@i{x}) <= hat(@i{x}) is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_vnrou_chg_verify}
@deftypefn Function {int} unur_vnrou_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Change the verifying of algorithm while sampling on/off.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_vnrou_chg_verify}
@deftypefn {} {int} unur_vnrou_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Change the verifying of algorithm while sampling on/off.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_vnrou_get_volumehat}
@deftypefn Function {double} unur_vnrou_get_volumehat (const @var{UNUR_GEN* generator})
Get the volume of below the hat.
For normalized densities, i.e. when the volume below PDF is 1,
this value equals the rejection constant for the vnrou method.

In case of an error UNUR_INFINITY is returned.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_vnrou_get_volumehat}
@deftypefn {} {double} unur_vnrou_get_volumehat (const @var{UNUR_GEN* generator})
Get the volume of below the hat.
For normalized densities, i.e. when the volume below PDF is 1,
this value equals the rejection constant for the vnrou method.

In case of an error UNUR_INFINITY is returned.
@end deftypefn
@end ifnotinfo




@c
@c end of vnrou.h
@c -------------------------------------
@c -------------------------------------
@c methods.dh
@c

@page
@node MCMC_Methods_for_CVEC
@section   Markov chain samplers for continuous multivariate distributions

@menu
* GIBBS:: Markov Chain - GIBBS sampler
* HITRO:: Markov Chain - HIT-and-run sampler with Ratio-Of-uniforms
@end menu



Markov chain samplers generate sequences of random vectors which have
the target distribution as stationary distribution.
There generated vectors are (more or less) correlated and it might take a long
time until the sequence has converged to the given target distribution.

@strong{Beware: MCMC sampling can be dangerous!}

@subheading Overview of methods

@include methods_mcmc.texi



@c
@c end of methods.dh
@c -------------------------------------
@c -------------------------------------
@c gibbs.h
@c

@page
@node GIBBS
@subsection   GIBBS  --  Markov Chain - GIBBS sampler

@table @i
@item Required:
T-concave logPDF, derivatives of logPDF
@item Speed:
Set-up: fast, Sampling: moderate
@item Reinit:
not implemented
@item Reference:
@ifhtml
@ref{bib:HLD04,, [HLD04: Sect.14.1.2]}
@end ifhtml
@ifnothtml
[HLD04: Sect.14.1.2]
@end ifnothtml

@end table


Method GIBBS implements a Gibbs sampler for a multivariate
distribution with given joint density and its gradient.
When running such a Markov chain all coordinates are updated
cyclically using full conditional distributions. After each step
the state of the chain is returned (i.e., a random point is
returned whenever a single coordinate has been updated).
It is also possible to return only points after all coordinates
have been updated by "thinning" the chain.
Moreover, to reduce autocorrelation this thinning factor can be
any integer. Notice, however, that the sampling time for a chain
of given length is increased by the same factor, too.

GIBBS also provides a variant of the Gibbs sampler where in
each step a point from the full conditional distribution along
some random direction is sampled. This direction is chosen
uniformly from the sphere in each step.
This method is also known as Hit-and-Run algorithm for
non-uniform distributions.

Our experiences shows that the original Gibbs sampler with
sampling along coordinate axes is superior to random direction
sampling as long as the correlations between the components of
the random vector are not too high.

For both variants transformed density rejection (see methods
@pxref{TDR} and @pxref{ARS}) is used to
sample from the full conditional distributions. In opposition to
the univariate case, it is important that the factor @code{c} is
as large as possible. I.e., for a log-concave density @code{c}
must be set to @code{0.}, since otherwise numerical underflow
might stop the algorithm.

@emph{Important:} GIBBS does not generate independent random
points. The starting point of the Gibbs chain must be in a
"typical" region of the target distribution. If such a point is
not known or would be too expensive, then the first part of the
chain should be discarded (burn-in of the chain).


@subsubheading How To Use


For using the GIBBS method UNU.RAN needs the logarithm of the
PDF of the multivariate joint distribution and its gradient or
partial derivatives.

It provides two variants:
@table @emph
@item coordinate direction sampling (Gibbs sampling) [default]
The coordinates are updated cyclically.
It requires the partial derivatives of the (logarithm of the)
PDF of the target distribution,
see
@ifhtml
@ref{funct:unur_distr_cvec_set_pdlogpdf,@command{unur_distr_cvec_set_pdlogpdf}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_pdlogpdf}.
@end ifnothtml
Otherwise, the gradient of the logPDF
(see
@ifhtml
@ref{funct:unur_distr_cvec_set_dlogpdf,@command{unur_distr_cvec_set_dlogpdf}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_dlogpdf}
@end ifnothtml
)
is used, which is more expensive.

This variant can be selected using
@ifhtml
@ref{funct:unur_gibbs_set_variant_coordinate,@command{unur_gibbs_set_variant_coordinate}.}
@end ifhtml
@ifnothtml
@command{unur_gibbs_set_variant_coordinate}.
@end ifnothtml
@item random direction sampling (nonuniform Hit-and-Run algorithm)
In each step is a direction is sampled uniformly from the sphere
and the next point in the chain is sampled from the full
conditional distribution along this direction.

It requires the gradient of the logPDF and thus each step is
more expensive than each step for coordinate direction sampling.

This variant can be selected using
@ifhtml
@ref{funct:unur_gibbs_set_variant_random_direction,@command{unur_gibbs_set_variant_random_direction}.}
@end ifhtml
@ifnothtml
@command{unur_gibbs_set_variant_random_direction}.
@end ifnothtml
@end table

It is important that the @code{c} parameter for the TDR method
is as large as possible. For logconcave distribution it must be
set to @code{0}, since otherwise numerical underflow can cause
the algorithm to stop.

The starting point of the Gibbs chain must be "typical" for the
target distribution. If such a point is not known or would be
too expensive, then the first part of the chain should be
discarded (burn-in of the chain). When using the
@ifhtml
@ref{funct:unur_gibbs_set_burnin,@command{unur_gibbs_set_burnin}}
@end ifhtml
@ifnothtml
@command{unur_gibbs_set_burnin}
@end ifnothtml
call this is done during the setup
of the Gibbs sampler object.

In case of a fatal error in the generator for conditional
distributions the methods generates points that contain
UNUR_INFINITY.

@strong{Warning:} The algorithm requires that all full
conditionals for the given distribution object are
@i{T}-concave. However, this property is not checked.
If this property is not satisfied, then generation from the
conditional distributions becomes (very) slow and might fail or
(even worse) produces random vectors from an incorrect
distribution.
When using
@ifhtml
@ref{funct:unur_gibbs_set_burnin,@command{unur_gibbs_set_burnin}}
@end ifhtml
@ifnothtml
@command{unur_gibbs_set_burnin}
@end ifnothtml
then the setup already
might fail. Thus when in doubt whether GIBBS can be used for
the targent distribution it is a good idea to use a burn-in for
checking.

@emph{Remark:} It might happen (very rarely) that the chain
becomes stuck due to numerical errors. (This is in particular the
case when the given PDF does not fulfill the condition of this
method.)
When this happens during burn-in then the setup is aborted
(i.e. it fails). Otherwise the chain restarts again from its
starting point.

@strong{Warning:} Be carefull with debugging flags. If it
contains flag @code{0x01000000u} it produces a lot of output for
each step in the algorithm.
(This flag is switched of in the default debugging flags).




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_gibbs_new,unur_gibbs_new}
@item @ref{funct:unur_gibbs_set_variant_coordinate,unur_gibbs_set_variant_coordinate}
@item @ref{funct:unur_gibbs_set_variant_random_direction,unur_gibbs_set_variant_random_direction}
@item @ref{funct:unur_gibbs_set_c,unur_gibbs_set_c}
@item @ref{funct:unur_gibbs_set_startingpoint,unur_gibbs_set_startingpoint}
@item @ref{funct:unur_gibbs_set_thinning,unur_gibbs_set_thinning}
@item @ref{funct:unur_gibbs_set_burnin,unur_gibbs_set_burnin}
@item @ref{funct:unur_gibbs_get_state,unur_gibbs_get_state}
@item @ref{funct:unur_gibbs_chg_state,unur_gibbs_chg_state}
@item @ref{funct:unur_gibbs_reset_state,unur_gibbs_reset_state}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_gibbs_new}
@deftypefn Function {UNUR_PAR*} unur_gibbs_new (const @var{UNUR_DISTR* distribution})
...........................................................................
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_gibbs_new}
@deftypefn {} {UNUR_PAR*} unur_gibbs_new (const @var{UNUR_DISTR* distribution})
...........................................................................
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_gibbs_set_variant_coordinate}
@deftypefn Function {int} unur_gibbs_set_variant_coordinate (UNUR_PAR* @var{parameters})
Coordinate Direction Sampling:
Sampling along the coordinate directions (cyclic).

This is the default.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_gibbs_set_variant_coordinate}
@deftypefn {} {int} unur_gibbs_set_variant_coordinate (UNUR_PAR* @var{parameters})
Coordinate Direction Sampling:
Sampling along the coordinate directions (cyclic).

This is the default.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_gibbs_set_variant_random_direction}
@deftypefn Function {int} unur_gibbs_set_variant_random_direction (UNUR_PAR* @var{parameters})
Random Direction Sampling:
Sampling along the random directions.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_gibbs_set_variant_random_direction}
@deftypefn {} {int} unur_gibbs_set_variant_random_direction (UNUR_PAR* @var{parameters})
Random Direction Sampling:
Sampling along the random directions.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_gibbs_set_c}
@deftypefn Function {int} unur_gibbs_set_c (UNUR_PAR* @var{parameters}, double @var{c})
Set parameter @var{c} for transformation
@math{T}
of the
transformed density rejection method.
Currently only values between @code{0} and @code{-0.5} are
allowed. If @code{c} is between @code{0} and @code{-0.5} it is set
to @code{-0.5}.

For @var{c} @code{=0} (for logconcave densities) method ARS
(@pxref{ARS}) is used which is very robust against badly
normalized PDFs. For other values method TDR (@pxref{TDR}) is used.

The value for @var{c} should be as large as possible to avoid
fatal numerical underflows. Thus for log-concave distributions
@var{c} must be set to @code{0.}

Default is @code{0}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_gibbs_set_c}
@deftypefn {} {int} unur_gibbs_set_c (UNUR_PAR* @var{parameters}, double @var{c})
Set parameter @var{c} for transformation
@iftex
@math{T}
@end iftex
@ifhtml
@html
<I>T</I>
@end html
@end ifhtml
of the
transformed density rejection method.
Currently only values between @code{0} and @code{-0.5} are
allowed. If @code{c} is between @code{0} and @code{-0.5} it is set
to @code{-0.5}.

For @var{c} @code{=0} (for logconcave densities) method ARS
(@pxref{ARS}) is used which is very robust against badly
normalized PDFs. For other values method TDR (@pxref{TDR}) is used.

The value for @var{c} should be as large as possible to avoid
fatal numerical underflows. Thus for log-concave distributions
@var{c} must be set to @code{0.}

Default is @code{0}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_gibbs_set_startingpoint}
@deftypefn Function {int} unur_gibbs_set_startingpoint (UNUR_PAR* @var{parameters}, const @var{double* x0})
Sets the starting point of the Gibbs sampler. @var{x0} must be
a "typical" point of the given distribution.
If such a "typical" point is not known and a starting point is
merely guessed, the first part of the Gibbs chain should be
discarded (@emph{burn-in}), e.g.\ by mean of the
@ifhtml
@ref{funct:unur_gibbs_set_burnin,@command{unur_gibbs_set_burnin}}
@end ifhtml
@ifnothtml
@command{unur_gibbs_set_burnin}
@end ifnothtml
call.

Default is the result of
@ifhtml
@ref{funct:unur_distr_cvec_get_center,@command{unur_distr_cvec_get_center}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_get_center}
@end ifnothtml
for the
given distribution object.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_gibbs_set_startingpoint}
@deftypefn {} {int} unur_gibbs_set_startingpoint (UNUR_PAR* @var{parameters}, const @var{double* x0})
Sets the starting point of the Gibbs sampler. @var{x0} must be
a "typical" point of the given distribution.
If such a "typical" point is not known and a starting point is
merely guessed, the first part of the Gibbs chain should be
discarded (@emph{burn-in}), e.g.\ by mean of the
@ifhtml
@ref{funct:unur_gibbs_set_burnin,@command{unur_gibbs_set_burnin}}
@end ifhtml
@ifnothtml
@command{unur_gibbs_set_burnin}
@end ifnothtml
call.

Default is the result of
@ifhtml
@ref{funct:unur_distr_cvec_get_center,@command{unur_distr_cvec_get_center}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_get_center}
@end ifnothtml
for the
given distribution object.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_gibbs_set_thinning}
@deftypefn Function {int} unur_gibbs_set_thinning (UNUR_PAR* @var{parameters}, int @var{thinning})
Sets the @var{thinning} parameter. When @var{thinning} is set to
@i{k} then every @i{k}-th point from the iteration is returned by
the sampling algorithm.

@emph{Notice}: This parameter must satisfy @var{thinning}>=1.

Default: @code{1}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_gibbs_set_thinning}
@deftypefn {} {int} unur_gibbs_set_thinning (UNUR_PAR* @var{parameters}, int @var{thinning})
Sets the @var{thinning} parameter. When @var{thinning} is set to
@i{k} then every @i{k}-th point from the iteration is returned by
the sampling algorithm.

@emph{Notice}: This parameter must satisfy @var{thinning}>=1.

Default: @code{1}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_gibbs_set_burnin}
@deftypefn Function {int} unur_gibbs_set_burnin (UNUR_PAR* @var{parameters}, int @var{burnin})
If a "typical" point for the target distribution is not known but
merely guessed, the first part of the Gibbs chain should be
discarded (@emph{burn-in}). This can be done during the
initialization of the generator object.
The length of the burn-in can is then @var{burnin}.

When method GIBBS is not applicable for the target distribution
then the initialization already might fail during the burn-in.
Thus this reduces the risk of running a generator that returns
UNUR_INFINITY cased by some fatal error during sampling.

The thinning factor set by a
@ifhtml
@ref{funct:unur_gibbs_set_thinning,@command{unur_gibbs_set_thinning}}
@end ifhtml
@ifnothtml
@command{unur_gibbs_set_thinning}
@end ifnothtml
call has
no effect on the length of the burn-in, i.e., for the burn-in
always a thinning factor @code{1} is used.

@emph{Notice}: This parameter must satisfy @var{thinning}>=0.

Default: @code{0}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_gibbs_set_burnin}
@deftypefn {} {int} unur_gibbs_set_burnin (UNUR_PAR* @var{parameters}, int @var{burnin})
If a "typical" point for the target distribution is not known but
merely guessed, the first part of the Gibbs chain should be
discarded (@emph{burn-in}). This can be done during the
initialization of the generator object.
The length of the burn-in can is then @var{burnin}.

When method GIBBS is not applicable for the target distribution
then the initialization already might fail during the burn-in.
Thus this reduces the risk of running a generator that returns
UNUR_INFINITY cased by some fatal error during sampling.

The thinning factor set by a
@ifhtml
@ref{funct:unur_gibbs_set_thinning,@command{unur_gibbs_set_thinning}}
@end ifhtml
@ifnothtml
@command{unur_gibbs_set_thinning}
@end ifnothtml
call has
no effect on the length of the burn-in, i.e., for the burn-in
always a thinning factor @code{1} is used.

@emph{Notice}: This parameter must satisfy @var{thinning}>=0.

Default: @code{0}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_gibbs_get_state}
@anchor{funct:unur_gibbs_chg_state}
@deftypefn Function {const double*} unur_gibbs_get_state (UNUR_GEN* @var{generator})
@deftypefnx Function {int} unur_gibbs_chg_state (UNUR_GEN* @var{generator}, const @var{double* state})
Get and change the current state of the Gibbs chain.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_gibbs_get_state}
@anchor{funct:unur_gibbs_chg_state}
@deftypefn {} {const double*} unur_gibbs_get_state (UNUR_GEN* @var{generator})
@deftypefnx {} {int} unur_gibbs_chg_state (UNUR_GEN* @var{generator}, const @var{double* state})
Get and change the current state of the Gibbs chain.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_gibbs_reset_state}
@deftypefn Function {int} unur_gibbs_reset_state (UNUR_GEN* @var{generator})
Reset state of chain to starting point.

@emph{Notice:} Currently this function does not reset
the generators for conditional distributions. Thus it is not
possible to get the same Gibbs chain even when the underlying
uniform random number generator is reset.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_gibbs_reset_state}
@deftypefn {} {int} unur_gibbs_reset_state (UNUR_GEN* @var{generator})
Reset state of chain to starting point.

@emph{Notice:} Currently this function does not reset
the generators for conditional distributions. Thus it is not
possible to get the same Gibbs chain even when the underlying
uniform random number generator is reset.
@end deftypefn
@end ifnotinfo




@c
@c end of gibbs.h
@c -------------------------------------
@c -------------------------------------
@c hitro.h
@c

@page
@node HITRO
@subsection   HITRO  --  Markov Chain - HIT-and-run sampler with Ratio-Of-uniforms

@table @i
@item Required:
PDF
@item Optional:
mode, center, bounding rectangle for acceptance region
@item Speed:
Set-up: fast, Sampling: fast
@item Reinit:
not implemented
@item Reference:
@ifhtml
@ref{bib:KLPa05,, [KLPa05]}
@end ifhtml
@ifnothtml
[KLPa05]
@end ifnothtml

@end table


HITRO is an implementation of a hit-and-run sampler that runs on
the acceptance region of the multivariate ratio-of-uniforms
method, see @ref{Ratio-of-Uniforms}.

The Ratio-of-Uniforms transforms the region below the density
into some region that we call "region of acceptance" in the
following. The minimal bounding hyperrectangle of this region
is given by
@iftex

@quotation
@math{ v^+ = \sup\limits_{x} (f(x))^{1/r\,d+1}, \hfil\break u^-_i = \inf\limits_{x_i} (x_i-\mu_i) (f(x))^{r/r\,d+1}, \hfil\break u^+_i = \sup\limits_{x_i} (x_i-\mu_i) (f(x))^{r/r\,d+1}, }
@end quotation

@end iftex
@ifhtml
@quotation
@html
<I>v</I><SUP>+</SUP> = sup_<I>x</I> (<I>f</I>(<I>x</I>))<SUP>1/<I>r</I> <I>d</I>+1</SUP>, @*<I>u</I><SUP>-</SUP>_<I>i</I> = inf_<I>x</I>_<I>i</I> (<I>x</I>_<I>i</I>- mu_<I>i</I>) (<I>f</I>(<I>x</I>))<SUP><I>r</I>/<I>r</I> <I>d</I>+1</SUP>, @*<I>u</I><SUP>+</SUP>_<I>i</I> = sup_<I>x</I>_<I>i</I> (<I>x</I>_<I>i</I>- mu_<I>i</I>) (<I>f</I>(<I>x</I>))<SUP><I>r</I>/<I>r</I> <I>d</I>+1</SUP>,
@end html
@end quotation
@end ifhtml
@ifinfo
@quotation
@math{v^+ = sup_(x) (f(x))^(1/r d+1), @*u^-_i = inf_(x_i) (x_i- mu_i) (f(x))^(r/r d+1), @*u^+_i = sup_(x_i) (x_i- mu_i) (f(x))^(r/r d+1),}
@end quotation
@end ifinfo

@noindent
where @i{d} denotes the dimension of the distribution;
@iftex
@math{x_i}
@end iftex
@ifhtml
@html
<I>x</I>_<I>i</I>
@end html
@end ifhtml
@ifinfo
@math{x_i}
@end ifinfo
is the @i{i}-th coordinate of point @i{x};
@iftex
@math{\mu_i}
@end iftex
@ifhtml
@html
mu_<I>i</I>
@end html
@end ifhtml
@ifinfo
@math{mu_i}
@end ifinfo
is the @i{i}-th coordinate of the center
@iftex
@math{\mu}
@end iftex
@ifhtml
@html
mu
@end html
@end ifhtml
@ifinfo
@math{mu}
@end ifinfo
of the distribution, i.e., a point in the
"main region" of the distribution.
Using the center is important, since otherwise the acceptance
region can become a very long and skinny ellipsoid along a
diagonal of the (huge) bounding rectangle.

For each step of the Hit-and-Run algorithm we have to choose
some direction. This direction together with the current point
of the chain determines a straight line. Then a point is sampled
uniformly on intersection of this line and the region of
acceptance. This is done by rejection from a uniform distribution
on a line segment that covers it.
Depending of the chosen variant the endpoints of this covering
line are computed either by means of a (not necessary minimal)
bounding hyper-rectangle, or just the "covering plate" of the
bounding hyper-rectangle.

The required bounds of the hyper-rectable can be given directly
by the user. Otherwise, these are computed automatically by
means of a numerical routine by Hooke and Jeeves
@ifhtml
@ref{bib:HJa61,, [HJa61]}
@end ifhtml
@ifnothtml
[HJa61]
@end ifnothtml
called direct search (see
@file{src/utils/hooke.c} for further references and details).
However, this expensive computation can be avoided by determine
these bounds "on the fly" by the following adaptive algorithm:
Start with some (small) hyper-rectangle and enlarge it whenever
the endpoints of the covering line segment are not contained in
the acceptance region of the Ratio-of-Unfiorms method.
This approach works reliable as long as the region of acceptance
is convex.

The performance of the uniform sampling from the line segment is
much improved if the covering line is adjusted (shortened)
whenever a point is rejected (adaptive sampling). This technique
reduces the expected number of iterations enormously.

Method HITRO requires that the region of acceptance of the
Ratio-of-Uniforms method is bounded. The shape of this region
can be controlled by a parameter @i{r}. Higher values of @i{r}
result in larger classes of distributions with bounded region
of acceptance. (A distribution that has such a bounded region for
some @i{r} also has a bounded region for every @i{r'} greater
than @i{r}.) On the other hand the acceptance probability
decreases with increasing @i{r}. Moreover, round-off errors are
more likely and (for large values of @i{r}) might result in a
chain with a stationary distribution different from the target
distribution.

Method HITRO works optimal for distributions whose region of
acceptance is convex. This is in particular the case for all
log-concave distributions when we set @i{r} = @code{1}.
For bounded but non-convex regions of acceptance convergence is
yet not guarenteed by mathematical theory.



@subsubheading How To Use


Method HITRO requires the PDF of the target distribution
(derivatives are not necessary).

The acceptance region of the Ratio-of-Uniforms transformation
must be bounded. Its shape is controlled by parameter @i{r}.
By default this parameter is set to @code{1} as this guarentees
a convex region of acceptance when the PDF of the given
distribution is log-concave. It should only be set to a
different (higher!) value using
@ifhtml
@ref{funct:unur_vnrou_set_r,@command{unur_vnrou_set_r}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_r}
@end ifnothtml
if otherwise
@iftex
@math{x_i\,(f(x))^{r/r\,d+1}}
@end iftex
@ifhtml
@html
<I>x</I>_<I>i</I> (<I>f</I>(<I>x</I>))<SUP><I>r</I>/<I>r</I> <I>d</I>+1</SUP>
@end html
@end ifhtml
@ifinfo
@math{x_i (f(x))^(r/r d+1)}
@end ifinfo
were not
bounded for each coordinate.

There are two variants of the HITRO sampler:
@table @emph
@item coordinate direction sampling. [default]
The coordinates are updated cyclically.
This can be seen as a Gibbs sampler running on the acceptance
region of the Ratio-of-Uniforms method.
This variant can be selected using
@ifhtml
@ref{funct:unur_hitro_set_variant_coordinate,@command{unur_hitro_set_variant_coordinate}.}
@end ifhtml
@ifnothtml
@command{unur_hitro_set_variant_coordinate}.
@end ifnothtml
@item random direction sampling.
In each step is a direction is sampled uniformly from the
sphere.

This variant can be selected using
@ifhtml
@ref{funct:unur_hitro_set_variant_random_direction,@command{unur_hitro_set_variant_random_direction}.}
@end ifhtml
@ifnothtml
@command{unur_hitro_set_variant_random_direction}.
@end ifnothtml
@end table

Notice that each iteration of the coordinate direction sampler is
cheaper than an iteration of the random direction sampler.

Sampling uniformly from the line segment can be adjusted in
several ways:

@table @emph
@item Adaptive line sampling vs. simple rejection.
When adaptive line sampling is switched on, the covering line is
shortened whenever a point is rejected. However, when the region
of acceptance is not convex the line segment from which we have
to sample might not be connected. We found that the algorithm
still works but at the time being there is no formal proof that
the generated Markov chain has the required stationary
distribution.

Adaptive line sampling can switch on/off by means of the
@ifhtml
@ref{funct:unur_hitro_set_use_adaptiveline,@command{unur_hitro_set_use_adaptiveline}}
@end ifhtml
@ifnothtml
@command{unur_hitro_set_use_adaptiveline}
@end ifnothtml
call.

@item Bounding hyper-rectangle vs. "covering plate".
For computing the covering line we can use the bounding
hyper-rectangle or just its upper bound.
The latter saves computing time during the setup and
when computing the covering during at each iteration step
at the expense of a longer covering line. When adaptive line
sampling is used the total generation time for the entire chain
is shorter when only the "covering plate" is used.

@emph{Notice:} When coordinate sampling is used the entire
bounding rectangle is used.

Using the entire bounding hyper-rectangle can be switched on/off
by means of the
@ifhtml
@ref{funct:unur_hitro_set_use_boundingrectangle,@command{unur_hitro_set_use_boundingrectangle}}
@end ifhtml
@ifnothtml
@command{unur_hitro_set_use_boundingrectangle}
@end ifnothtml
call.

@item Deterministic vs. adaptive bounding hyper-rectangle.
A bounding rectangle can be given by the
@ifhtml
@ref{funct:unur_vnrou_set_u,@command{unur_vnrou_set_u}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_u}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_vnrou_set_v,@command{unur_vnrou_set_v}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_v}
@end ifnothtml
calls.
Otherwise, the minimal bounding rectangle is computed
automatically during the setup by means of a numerical
algorithm. However, this is (very) slow especially in higher
dimensions and it might happen that this algorithm (like
any other numerical algorithm) does not return a correct result.

Alternatively the bounding rectangle can be computed
adaptively. In the latter case
@ifhtml
@ref{funct:unur_vnrou_set_u,@command{unur_vnrou_set_u}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_u}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_vnrou_set_v,@command{unur_vnrou_set_v}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_v}
@end ifnothtml
can be used to provide a starting rectangle
which must be sufficiently small.
Then both endpoints of the covering line segment are always
check whether they are outside the acceptance region of the
Ratio-of-Uniforms method. If they are not, then the line segment
and the ("bounding") rectangle are enlarged using a factor that
can be given using the
@ifhtml
@ref{funct:unur_hitro_set_adaptive_multiplier,@command{unur_hitro_set_adaptive_multiplier}}
@end ifhtml
@ifnothtml
@command{unur_hitro_set_adaptive_multiplier}
@end ifnothtml
call.

Notice, that running this method in the adaptive rectangle
mode requires that the region of acceptance is convex when random
directions are used, or the given PDF is unimodal when
coordinate direction sampling is used.
Moreover, it requires two additional calls to the PDF in each
iteration step of the chain.

Using addaptive bounding rectangles can be switched on/off
by means of the
@ifhtml
@ref{funct:unur_hitro_set_use_adaptiverectangle,@command{unur_hitro_set_use_adaptiverectangle}}
@end ifhtml
@ifnothtml
@command{unur_hitro_set_use_adaptiverectangle}
@end ifnothtml
call.

@end table

The algorithm takes of a bounded rectangular domain given by a
@ifhtml
@ref{funct:unur_distr_cvec_set_domain_rect,@command{unur_distr_cvec_set_domain_rect}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_domain_rect}
@end ifnothtml
call, i.e. the PDF is set to
zero for every @i{x} outside the given domain.
However, it is only the coordinate direction sampler where the
boundary values are directly used to get the endpoins of the
coverline line for the line sampling step.


@emph{Important:} The bounding rectangle has to be
provided for the function
@iftex
@math{PDF(x-center)!}
@end iftex
@ifhtml
@html
<I>PDF</I>(<I>x</I>-<I>center</I>)!
@end html
@end ifhtml
@ifinfo
@math{PDF(x-center)!}
@end ifinfo
Notice that @code{center} is the center of the given
distribution, see
@ifhtml
@ref{funct:unur_distr_cvec_set_center,@command{unur_distr_cvec_set_center}.}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_center}.
@end ifnothtml
If in doubt or if this value is not optimal, it can be changed
(overridden) by a
@ifhtml
@ref{funct:unur_distr_cvec_set_center,@command{unur_distr_cvec_set_center}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_center}
@end ifnothtml
call.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_hitro_new,unur_hitro_new}
@item @ref{funct:unur_hitro_set_variant_coordinate,unur_hitro_set_variant_coordinate}
@item @ref{funct:unur_hitro_set_variant_random_direction,unur_hitro_set_variant_random_direction}
@item @ref{funct:unur_hitro_set_use_adaptiveline,unur_hitro_set_use_adaptiveline}
@item @ref{funct:unur_hitro_set_use_boundingrectangle,unur_hitro_set_use_boundingrectangle}
@item @ref{funct:unur_hitro_set_use_adaptiverectangle,unur_hitro_set_use_adaptiverectangle}
@item @ref{funct:unur_hitro_set_r,unur_hitro_set_r}
@item @ref{funct:unur_hitro_set_v,unur_hitro_set_v}
@item @ref{funct:unur_hitro_set_u,unur_hitro_set_u}
@item @ref{funct:unur_hitro_set_adaptive_multiplier,unur_hitro_set_adaptive_multiplier}
@item @ref{funct:unur_hitro_set_startingpoint,unur_hitro_set_startingpoint}
@item @ref{funct:unur_hitro_set_thinning,unur_hitro_set_thinning}
@item @ref{funct:unur_hitro_set_burnin,unur_hitro_set_burnin}
@item @ref{funct:unur_hitro_get_state,unur_hitro_get_state}
@item @ref{funct:unur_hitro_chg_state,unur_hitro_chg_state}
@item @ref{funct:unur_hitro_reset_state,unur_hitro_reset_state}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_hitro_new}
@deftypefn Function {UNUR_PAR*} unur_hitro_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hitro_new}
@deftypefn {} {UNUR_PAR*} unur_hitro_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hitro_set_variant_coordinate}
@deftypefn Function {int} unur_hitro_set_variant_coordinate (UNUR_PAR* @var{parameters})
Coordinate Direction Sampling:
Sampling along the coordinate directions (cyclic).

@emph{Notice:} For this variant the entire bounding rectangle is
always used independent of the
@ifhtml
@ref{funct:unur_hitro_set_use_boundingrectangle,@command{unur_hitro_set_use_boundingrectangle}}
@end ifhtml
@ifnothtml
@command{unur_hitro_set_use_boundingrectangle}
@end ifnothtml
call.

This is the default.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hitro_set_variant_coordinate}
@deftypefn {} {int} unur_hitro_set_variant_coordinate (UNUR_PAR* @var{parameters})
Coordinate Direction Sampling:
Sampling along the coordinate directions (cyclic).

@emph{Notice:} For this variant the entire bounding rectangle is
always used independent of the
@ifhtml
@ref{funct:unur_hitro_set_use_boundingrectangle,@command{unur_hitro_set_use_boundingrectangle}}
@end ifhtml
@ifnothtml
@command{unur_hitro_set_use_boundingrectangle}
@end ifnothtml
call.

This is the default.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hitro_set_variant_random_direction}
@deftypefn Function {int} unur_hitro_set_variant_random_direction (UNUR_PAR* @var{parameters})
Random Direction Sampling:
Sampling along the random directions.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hitro_set_variant_random_direction}
@deftypefn {} {int} unur_hitro_set_variant_random_direction (UNUR_PAR* @var{parameters})
Random Direction Sampling:
Sampling along the random directions.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hitro_set_use_adaptiveline}
@deftypefn Function {int} unur_hitro_set_use_adaptiveline (UNUR_PAR* @var{parameters}, int @var{adaptive})
When @var{adaptive} is set to @code{TRUE} adaptive line sampling is
applied, otherwise simple rejection is used.

@emph{Notice:} When adaptive line sampling is switched off,
the entire bounding rectangle must be used since otherwise the
sampling time can be arbitrarily slow.

@emph{Warning:} When adaptive line sampling is switched off,
sampling can be arbitrarily slow. In particular this happens
when random direction sampling is used for distributions with
rectangular domains. Then the algorithm can be trapped into
a vertex (or even edge).

Default is @code{TRUE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hitro_set_use_adaptiveline}
@deftypefn {} {int} unur_hitro_set_use_adaptiveline (UNUR_PAR* @var{parameters}, int @var{adaptive})
When @var{adaptive} is set to @code{TRUE} adaptive line sampling is
applied, otherwise simple rejection is used.

@emph{Notice:} When adaptive line sampling is switched off,
the entire bounding rectangle must be used since otherwise the
sampling time can be arbitrarily slow.

@emph{Warning:} When adaptive line sampling is switched off,
sampling can be arbitrarily slow. In particular this happens
when random direction sampling is used for distributions with
rectangular domains. Then the algorithm can be trapped into
a vertex (or even edge).

Default is @code{TRUE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hitro_set_use_boundingrectangle}
@deftypefn Function {int} unur_hitro_set_use_boundingrectangle (UNUR_PAR* @var{parameters}, int @var{rectangle})
When @var{rectangle} is set to @code{TRUE} the entire bounding rectangle is used
for computing the covering line. Otherwise, only an upper bound for the
acceptance region is used.

@emph{Notice:} When coordinate sampling is used the entire
bounding rectangle has is always used and this call has no effect.

Default: @code{FALSE} for random direction samplig, @code{TRUE} for coordinate
direction sampling.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hitro_set_use_boundingrectangle}
@deftypefn {} {int} unur_hitro_set_use_boundingrectangle (UNUR_PAR* @var{parameters}, int @var{rectangle})
When @var{rectangle} is set to @code{TRUE} the entire bounding rectangle is used
for computing the covering line. Otherwise, only an upper bound for the
acceptance region is used.

@emph{Notice:} When coordinate sampling is used the entire
bounding rectangle has is always used and this call has no effect.

Default: @code{FALSE} for random direction samplig, @code{TRUE} for coordinate
direction sampling.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hitro_set_use_adaptiverectangle}
@deftypefn Function {int} unur_hitro_set_use_adaptiverectangle (UNUR_PAR* @var{parameters}, int @var{adaptive})
When @var{adaptive} is set to @code{FALSE} the bounding rectangle is
determined during the setup. Either, it is computed automatically by
a (slow) numerical method, or it must be provided by
@ifhtml
@ref{funct:unur_vnrou_set_u,@command{unur_vnrou_set_u}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_u}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_vnrou_set_v,@command{unur_vnrou_set_v}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_v}
@end ifnothtml
calls.

If @var{adaptive} is set to @code{TRUE} the bounding rectangle is computed
adaptively. In this case the
@ifhtml
@ref{funct:unur_vnrou_set_u,@command{unur_vnrou_set_u}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_u}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_vnrou_set_v,@command{unur_vnrou_set_v}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_v}
@end ifnothtml
calls can be used to provide a starting
rectangle. This should be sufficiently small.
If not given then we assume
@math{v_(max) = 1,}
@math{u_(min)=(-0.001,-0.001,...,-0.001),}
and
@math{u_(max)=(0.001,0.001,...,0.001).}
Adaptive enlargements of the bounding hyperrectangle can be
controlled set setting an enlargement factor given
by a
@ifhtml
@ref{funct:unur_hitro_set_adaptive_multiplier,@command{unur_hitro_set_adaptive_multiplier}}
@end ifhtml
@ifnothtml
@command{unur_hitro_set_adaptive_multiplier}
@end ifnothtml
call.

Using adaptive computation of the bounding rectangle reduces the
setup time significantly (when it is not given by the user) at the
expense of two additional PDF evaluations during each iteration
step.

@emph{Important:} Using adaptive bounding rectangles requires that
the region of acceptance is convex when random directions are used,
or a unimodal PDF when coordinate direction sampling is used.

Default: @code{FALSE} for random direction samplig, @code{TRUE} for coordinate
direction sampling.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hitro_set_use_adaptiverectangle}
@deftypefn {} {int} unur_hitro_set_use_adaptiverectangle (UNUR_PAR* @var{parameters}, int @var{adaptive})
When @var{adaptive} is set to @code{FALSE} the bounding rectangle is
determined during the setup. Either, it is computed automatically by
a (slow) numerical method, or it must be provided by
@ifhtml
@ref{funct:unur_vnrou_set_u,@command{unur_vnrou_set_u}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_u}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_vnrou_set_v,@command{unur_vnrou_set_v}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_v}
@end ifnothtml
calls.

If @var{adaptive} is set to @code{TRUE} the bounding rectangle is computed
adaptively. In this case the
@ifhtml
@ref{funct:unur_vnrou_set_u,@command{unur_vnrou_set_u}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_u}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_vnrou_set_v,@command{unur_vnrou_set_v}}
@end ifhtml
@ifnothtml
@command{unur_vnrou_set_v}
@end ifnothtml
calls can be used to provide a starting
rectangle. This should be sufficiently small.
If not given then we assume
@iftex
@math{v_{max} = 1,}
@end iftex
@ifhtml
@html
<I>v</I>_<I>max</I> = 1,
@end html
@end ifhtml
@iftex
@math{u_{min}=(-0.001,-0.001,\ldots,-0.001),}
@end iftex
@ifhtml
@html
<I>u</I>_<I>min</I>=(-0.001,-0.001,...,-0.001),
@end html
@end ifhtml
and
@iftex
@math{u_{max}=(0.001,0.001,\ldots,0.001).}
@end iftex
@ifhtml
@html
<I>u</I>_<I>max</I>=(0.001,0.001,...,0.001).
@end html
@end ifhtml
Adaptive enlargements of the bounding hyperrectangle can be
controlled set setting an enlargement factor given
by a
@ifhtml
@ref{funct:unur_hitro_set_adaptive_multiplier,@command{unur_hitro_set_adaptive_multiplier}}
@end ifhtml
@ifnothtml
@command{unur_hitro_set_adaptive_multiplier}
@end ifnothtml
call.

Using adaptive computation of the bounding rectangle reduces the
setup time significantly (when it is not given by the user) at the
expense of two additional PDF evaluations during each iteration
step.

@emph{Important:} Using adaptive bounding rectangles requires that
the region of acceptance is convex when random directions are used,
or a unimodal PDF when coordinate direction sampling is used.

Default: @code{FALSE} for random direction samplig, @code{TRUE} for coordinate
direction sampling.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hitro_set_r}
@deftypefn Function {int} unur_hitro_set_r (UNUR_PAR* @var{parameters}, double @var{r})
Sets the parameter @var{r} of the generalized multivariate
ratio-of-uniforms method.

@emph{Notice}: This parameter must satisfy @var{r}>0.

Default: @code{1}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hitro_set_r}
@deftypefn {} {int} unur_hitro_set_r (UNUR_PAR* @var{parameters}, double @var{r})
Sets the parameter @var{r} of the generalized multivariate
ratio-of-uniforms method.

@emph{Notice}: This parameter must satisfy @var{r}>0.

Default: @code{1}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hitro_set_v}
@deftypefn Function {int} unur_hitro_set_v (UNUR_PAR* @var{parameters}, double @var{vmax})
Set upper boundary for bounding hyper-rectangle.
If not set not set the mode of the distribution is used.

If adaptive bounding rectangles the value is used for the
starting rectangle. If not given (and the mode of the distribution
is not known) then @var{vmax}=@code{1e-3} is used.

If deterministic bounding rectangles these values are the given
values are used for the rectangle. If no value is given
(and the mode of the distribution is not known), the upper
bound of the minimal bounding hyper-rectangle is computed
numerically (slow).

Default: not set.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hitro_set_v}
@deftypefn {} {int} unur_hitro_set_v (UNUR_PAR* @var{parameters}, double @var{vmax})
Set upper boundary for bounding hyper-rectangle.
If not set not set the mode of the distribution is used.

If adaptive bounding rectangles the value is used for the
starting rectangle. If not given (and the mode of the distribution
is not known) then @var{vmax}=@code{1e-3} is used.

If deterministic bounding rectangles these values are the given
values are used for the rectangle. If no value is given
(and the mode of the distribution is not known), the upper
bound of the minimal bounding hyper-rectangle is computed
numerically (slow).

Default: not set.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hitro_set_u}
@deftypefn Function {int} unur_hitro_set_u (UNUR_PAR* @var{parameters}, const @var{double* umin}, const @var{double* umax})
Sets left and right boundaries of bounding hyper-rectangle.

If adaptive bounding rectangles these values are used for the
starting rectangle. If not given then
@var{umin}=@code{@{-b,-b,@dots{},-b@}} and
@var{umax}=@code{@{b,b,@dots{},b@}} with @code{b=1.e-3} is used.

If deterministic bounding rectangles these values are the given
values are used for the rectangle. If no values are given, the
boundary of the minimal bounding hyper-rectangle is computed
numerically (slow).

@strong{Important}: The boundaries are those of the density shifted
by the center of the distribution, i.e., for the
function
@math{PDF(x-center)!}

@emph{Notice}: Computing the minimal bounding rectangle may fail
under some circumstances. Moreover, for multimodal distributions
the bounds might be too small as only local extrema are computed.
Nevertheless, for log-concave distributions it should work.

Default: not set.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hitro_set_u}
@deftypefn {} {int} unur_hitro_set_u (UNUR_PAR* @var{parameters}, const @var{double* umin}, const @var{double* umax})
Sets left and right boundaries of bounding hyper-rectangle.

If adaptive bounding rectangles these values are used for the
starting rectangle. If not given then
@var{umin}=@code{@{-b,-b,@dots{},-b@}} and
@var{umax}=@code{@{b,b,@dots{},b@}} with @code{b=1.e-3} is used.

If deterministic bounding rectangles these values are the given
values are used for the rectangle. If no values are given, the
boundary of the minimal bounding hyper-rectangle is computed
numerically (slow).

@strong{Important}: The boundaries are those of the density shifted
by the center of the distribution, i.e., for the
function
@iftex
@math{PDF(x-center)!}
@end iftex
@ifhtml
@html
<I>PDF</I>(<I>x</I>-<I>center</I>)!
@end html
@end ifhtml

@emph{Notice}: Computing the minimal bounding rectangle may fail
under some circumstances. Moreover, for multimodal distributions
the bounds might be too small as only local extrema are computed.
Nevertheless, for log-concave distributions it should work.

Default: not set.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hitro_set_adaptive_multiplier}
@deftypefn Function {int} unur_hitro_set_adaptive_multiplier (UNUR_PAR* @var{parameters}, double @var{factor})
Adaptive enlargements of the bounding hyperrectangle can be
controlled set setting the enlargement @var{factor}.
This must be greater than 1. Values close to 1 result in small
adaptive steps and thus reduce the risk of too large bounding
rectangles. On the other hand many adaptive steps might be
necessary.

@emph{Notice:} For practical reasons this call does not accept
values for @var{factor} less than @code{1.0001}. If this value is
UNUR_INFINITY this results in infinite loops.

Default: @code{1.1}
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hitro_set_adaptive_multiplier}
@deftypefn {} {int} unur_hitro_set_adaptive_multiplier (UNUR_PAR* @var{parameters}, double @var{factor})
Adaptive enlargements of the bounding hyperrectangle can be
controlled set setting the enlargement @var{factor}.
This must be greater than 1. Values close to 1 result in small
adaptive steps and thus reduce the risk of too large bounding
rectangles. On the other hand many adaptive steps might be
necessary.

@emph{Notice:} For practical reasons this call does not accept
values for @var{factor} less than @code{1.0001}. If this value is
UNUR_INFINITY this results in infinite loops.

Default: @code{1.1}
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hitro_set_startingpoint}
@deftypefn Function {int} unur_hitro_set_startingpoint (UNUR_PAR* @var{parameters}, const @var{double* x0})
Sets the starting point of the HITRO sampler in the original
scale. @var{x0} must be a "typical" point of the given distribution.
If such a "typical" point is not known and a starting point is
merely guessed, the first part of the HITRO chain should be
discarded (@emph{burn-in}), e.g.\ by mean of the
@ifhtml
@ref{funct:unur_hitro_set_burnin,@command{unur_hitro_set_burnin}}
@end ifhtml
@ifnothtml
@command{unur_hitro_set_burnin}
@end ifnothtml
call.

@emph{Important:} The PDF of the distribution must not vanish at
the given point @var{x0}.

Default is the result of
@ifhtml
@ref{funct:unur_distr_cvec_get_center,@command{unur_distr_cvec_get_center}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_get_center}
@end ifnothtml
for the
given distribution object.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hitro_set_startingpoint}
@deftypefn {} {int} unur_hitro_set_startingpoint (UNUR_PAR* @var{parameters}, const @var{double* x0})
Sets the starting point of the HITRO sampler in the original
scale. @var{x0} must be a "typical" point of the given distribution.
If such a "typical" point is not known and a starting point is
merely guessed, the first part of the HITRO chain should be
discarded (@emph{burn-in}), e.g.\ by mean of the
@ifhtml
@ref{funct:unur_hitro_set_burnin,@command{unur_hitro_set_burnin}}
@end ifhtml
@ifnothtml
@command{unur_hitro_set_burnin}
@end ifnothtml
call.

@emph{Important:} The PDF of the distribution must not vanish at
the given point @var{x0}.

Default is the result of
@ifhtml
@ref{funct:unur_distr_cvec_get_center,@command{unur_distr_cvec_get_center}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_get_center}
@end ifnothtml
for the
given distribution object.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hitro_set_thinning}
@deftypefn Function {int} unur_hitro_set_thinning (UNUR_PAR* @var{parameters}, int @var{thinning})
Sets the @var{thinning} parameter. When @var{thinning} is set to
@i{k} then every @i{k}-th point from the iteration is returned by
the sampling algorithm.
If thinning has to be set such that each coordinate is updated
when using coordinate direction sampling, then @var{thinning}
should be @code{dim+1} (or any multiple of it) where
@code{dim} is the dimension of the distribution object.

@emph{Notice}: This parameter must satisfy @var{thinning}>=1.

Default: @code{1}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hitro_set_thinning}
@deftypefn {} {int} unur_hitro_set_thinning (UNUR_PAR* @var{parameters}, int @var{thinning})
Sets the @var{thinning} parameter. When @var{thinning} is set to
@i{k} then every @i{k}-th point from the iteration is returned by
the sampling algorithm.
If thinning has to be set such that each coordinate is updated
when using coordinate direction sampling, then @var{thinning}
should be @code{dim+1} (or any multiple of it) where
@code{dim} is the dimension of the distribution object.

@emph{Notice}: This parameter must satisfy @var{thinning}>=1.

Default: @code{1}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hitro_set_burnin}
@deftypefn Function {int} unur_hitro_set_burnin (UNUR_PAR* @var{parameters}, int @var{burnin})
If a "typical" point for the target distribution is not known but
merely guessed, the first part of the HITRO chain should be
discarded (@emph{burn-in}). This can be done during the
initialization of the generator object.
The length of the burn-in can is then @var{burnin}.

The thinning factor set by a
@ifhtml
@ref{funct:unur_hitro_set_thinning,@command{unur_hitro_set_thinning}}
@end ifhtml
@ifnothtml
@command{unur_hitro_set_thinning}
@end ifnothtml
call has
no effect on the length of the burn-in, i.e., for the burn-in
always a thinning factor @code{1} is used.

@emph{Notice}: This parameter must satisfy @var{thinning}>=0.

Default: @code{0}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hitro_set_burnin}
@deftypefn {} {int} unur_hitro_set_burnin (UNUR_PAR* @var{parameters}, int @var{burnin})
If a "typical" point for the target distribution is not known but
merely guessed, the first part of the HITRO chain should be
discarded (@emph{burn-in}). This can be done during the
initialization of the generator object.
The length of the burn-in can is then @var{burnin}.

The thinning factor set by a
@ifhtml
@ref{funct:unur_hitro_set_thinning,@command{unur_hitro_set_thinning}}
@end ifhtml
@ifnothtml
@command{unur_hitro_set_thinning}
@end ifnothtml
call has
no effect on the length of the burn-in, i.e., for the burn-in
always a thinning factor @code{1} is used.

@emph{Notice}: This parameter must satisfy @var{thinning}>=0.

Default: @code{0}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hitro_get_state}
@anchor{funct:unur_hitro_chg_state}
@deftypefn Function {const double*} unur_hitro_get_state (UNUR_GEN* @var{generator})
@deftypefnx Function {int} unur_hitro_chg_state (UNUR_GEN* @var{generator}, const @var{double* state})
Get and change the current state of the HITRO chain.

@emph{Notice:} The state variable contains the point in the
@code{dim+1} dimensional point in the (tansformed) region of
acceptance of the Ratio-of-Uniforms method. Its coordinate
are stored in the following order:
@code{state[] = @{v, u1, u2, @dots{}, udim@}}.

If the state can only be changed if the given @var{state} is inside
this region.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hitro_get_state}
@anchor{funct:unur_hitro_chg_state}
@deftypefn {} {const double*} unur_hitro_get_state (UNUR_GEN* @var{generator})
@deftypefnx {} {int} unur_hitro_chg_state (UNUR_GEN* @var{generator}, const @var{double* state})
Get and change the current state of the HITRO chain.

@emph{Notice:} The state variable contains the point in the
@code{dim+1} dimensional point in the (tansformed) region of
acceptance of the Ratio-of-Uniforms method. Its coordinate
are stored in the following order:
@code{state[] = @{v, u1, u2, @dots{}, udim@}}.

If the state can only be changed if the given @var{state} is inside
this region.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_hitro_reset_state}
@deftypefn Function {int} unur_hitro_reset_state (UNUR_GEN* @var{generator})
Reset state of chain to starting point.

@emph{Notice:} Currently this function does not reset
the generators for conditional distributions. Thus it is not
possible to get the same HITRO chain even when the underlying
uniform random number generator is reset.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_hitro_reset_state}
@deftypefn {} {int} unur_hitro_reset_state (UNUR_GEN* @var{generator})
Reset state of chain to starting point.

@emph{Notice:} Currently this function does not reset
the generators for conditional distributions. Thus it is not
possible to get the same HITRO chain even when the underlying
uniform random number generator is reset.
@end deftypefn
@end ifnotinfo




@c
@c end of hitro.h
@c -------------------------------------
@c -------------------------------------
@c methods.dh
@c

@page
@node Methods_for_CVEMP
@section   Methods for continuous empirical multivariate distributions

@menu
* VEMPK:: (Vector) EMPirical distribution with Kernel smoothing
@end menu



@subheading Overview of methods

@include methods_cvemp.texi

@subheading Example

@smallexample
@include ref_example_vemp.texi
@end smallexample

@subheading Example (String API)

(not implemented)



@c
@c end of methods.dh
@c -------------------------------------
@c -------------------------------------
@c vempk.h
@c

@page
@node VEMPK
@subsection   VEMPK  --  (Vector) EMPirical distribution with Kernel smoothing

@table @i
@item Required:
observed sample
@item Speed:
Set-up: slow, Sampling: slow (depends on dimension)
@item Reinit:
not implemented
@item Reference:
@ifhtml
@ref{bib:HLa00,, [HLa00]}
@end ifhtml
@ifnothtml
[HLa00]
@end ifnothtml
@ifhtml
@ref{bib:HLD04,, [HLD04: Sect.12.2.1]}
@end ifhtml
@ifnothtml
[HLD04: Sect.12.2.1]
@end ifnothtml

@end table


VEMPK generates random variates from a multivariate empirical
distribution that is given by an observed sample. The idea is
that simply choosing a random point from the sample and to
return it with some added noise results in a method that has
very nice properties, as it can be seen as sampling from a
kernel density estimate.
Clearly we have to decide about the density of the noise (called kernel)
and about the covariance matrix of the noise.
The mathematical theory of kernel density estimation shows us that we
are comparatively free in choosing the kernel.
It also supplies us with a simple formula to compute the optimal
standarddeviation of the noise, called bandwidth (or window
width) of the kernel.

Currently only a Gaussian kernel with the same covariance matrix
as the given sample is implemented.
However it is possible to choose between a variance corrected
version or those with optimal MISE.
Additionally a smoothing factor can be set to adjust the
estimated density to non-bell-shaped data densities.


@subsubheading How To Use


VEMPK uses empirical distributions. The main parameter would be
the choice if of kernel density. However, currently only
Gaussian kernels are supported. The parameters for the density
are computed by a simple but robust method. However, it is
possible to control its behavior by changing the smoothing
factor.
Additionally, variance correction can be swithed on (at the
price of suboptimal MISE).




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_vempk_new,unur_vempk_new}
@item @ref{funct:unur_vempk_set_smoothing,unur_vempk_set_smoothing}
@item @ref{funct:unur_vempk_chg_smoothing,unur_vempk_chg_smoothing}
@item @ref{funct:unur_vempk_set_varcor,unur_vempk_set_varcor}
@item @ref{funct:unur_vempk_chg_varcor,unur_vempk_chg_varcor}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_vempk_new}
@deftypefn Function {UNUR_PAR*} unur_vempk_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_vempk_new}
@deftypefn {} {UNUR_PAR*} unur_vempk_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_vempk_set_smoothing}
@anchor{funct:unur_vempk_chg_smoothing}
@deftypefn Function {int} unur_vempk_set_smoothing (UNUR_PAR* @var{parameters}, double @var{smoothing})
@deftypefnx Function {int} unur_vempk_chg_smoothing (UNUR_GEN* @var{generator}, double @var{smoothing})
Set and change the smoothing factor.
The smoothing factor controlles how ``smooth'' the resulting density
estimation will be. A smoothing factor equal to 0 results in naive
resampling. A very large smoothing factor (together with the
variance correction) results in a density which is approximately
equal to the kernel.
Default is 1 which results in a smoothing parameter minimising
the MISE (mean integrated squared error) if the data are not too
far away from normal. If a large smoothing factor is used, then
variance correction must be switched on.

Default: @code{1}
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_vempk_set_smoothing}
@anchor{funct:unur_vempk_chg_smoothing}
@deftypefn {} {int} unur_vempk_set_smoothing (UNUR_PAR* @var{parameters}, double @var{smoothing})
@deftypefnx {} {int} unur_vempk_chg_smoothing (UNUR_GEN* @var{generator}, double @var{smoothing})
Set and change the smoothing factor.
The smoothing factor controlles how ``smooth'' the resulting density
estimation will be. A smoothing factor equal to 0 results in naive
resampling. A very large smoothing factor (together with the
variance correction) results in a density which is approximately
equal to the kernel.
Default is 1 which results in a smoothing parameter minimising
the MISE (mean integrated squared error) if the data are not too
far away from normal. If a large smoothing factor is used, then
variance correction must be switched on.

Default: @code{1}
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_vempk_set_varcor}
@anchor{funct:unur_vempk_chg_varcor}
@deftypefn Function {int} unur_vempk_set_varcor (UNUR_PAR* @var{parameters}, int @var{varcor})
@deftypefnx Function {int} unur_vempk_chg_varcor (UNUR_GEN* @var{generator}, int @var{varcor})
Switch variance correction in generator on/off.
If @var{varcor} is @code{TRUE} then the variance of the used
density estimation is the same as the sample variance. However this
increases the MISE of the estimation a little bit.

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_vempk_set_varcor}
@anchor{funct:unur_vempk_chg_varcor}
@deftypefn {} {int} unur_vempk_set_varcor (UNUR_PAR* @var{parameters}, int @var{varcor})
@deftypefnx {} {int} unur_vempk_chg_varcor (UNUR_GEN* @var{generator}, int @var{varcor})
Switch variance correction in generator on/off.
If @var{varcor} is @code{TRUE} then the variance of the used
density estimation is the same as the sample variance. However this
increases the MISE of the estimation a little bit.

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo




@c
@c end of vempk.h
@c -------------------------------------
@c -------------------------------------
@c methods.dh
@c

@page
@node Methods_for_DISCR
@section   Methods for discrete univariate distributions

@menu
* DARI:: Discrete Automatic Rejection Inversion
* DAU:: (Discrete) Alias-Urn method
* DEXT:: wrapper for Discrete EXTernal generators
* DGT:: (Discrete) Guide Table method (indexed search)
* DSROU:: Discrete Simple Ratio-Of-Uniforms method
* DSS:: (Discrete) Sequential Search method
* DSTD:: Discrete STandarD distributions
@end menu



@subheading Overview of methods

@include methods_discr.texi

@subheading Example

@smallexample
@include ref_example_discr.texi
@end smallexample

@subheading Example (String API)

@smallexample
@include ref_example_discr_str.texi
@end smallexample



@c
@c end of methods.dh
@c -------------------------------------
@c -------------------------------------
@c dari.h
@c

@page
@node DARI
@subsection   DARI  --  Discrete Automatic Rejection Inversion

@table @i
@item Required:
T-concave PMF, mode, approximate area
@item Speed:
Set-up: moderate, Sampling: fast
@item Reinit:
supported
@item Reference:
@ifhtml
@ref{bib:HDa96,, [HDa96]}
@end ifhtml
@ifnothtml
[HDa96]
@end ifnothtml
@ifhtml
@ref{bib:HLD04,, [HLD04: Sect.10.2; Alg.10.4]}
@end ifhtml
@ifnothtml
[HLD04: Sect.10.2; Alg.10.4]
@end ifnothtml

@end table


DARI is based on rejection inversion, which can be seen as an
adaptation of transformed density rejection to discrete
distributions. The used transformation is
@iftex
@math{-1/\sqrt{x}}
@end iftex
@ifhtml
@html
-1/sqrt(<I>x</I>)
@end html
@end ifhtml
@ifinfo
@math{-1/sqrt(x)}
@end ifinfo
.

DARI uses three almost optimal points for constructing the
(continuous) hat. Rejection is then done in horizontal
direction. Rejection inversion uses only one uniform random
variate per trial.

DARI has moderate set-up times (the PMF is evaluated nine
times), and good marginal speed, especially if an auxiliary
array is used to store values during generation.

DARI works for all
@iftex
@math{T_{-1/2}}
@end iftex
@ifhtml
@html
<I>T</I>_-1/2
@end html
@end ifhtml
@ifinfo
@math{T_(-1/2)}
@end ifinfo
-concave distributions. It requires the PMF
and the location of the mode. Moreover the approximate sum over the PMF
is used. (If no sum is given for the distribution the algorithm
assumes that it is approximately 1.)
The rejection constant is bounded from above by 4 for all @i{T}-concave
distributions.


@subsubheading How To Use


DARI works for discrete distribution object with given PMF.
The sum over probabilities should be approximately
one. Otherwise it must be set by a
@ifhtml
@ref{funct:unur_distr_discr_set_pmfsum,@command{unur_distr_discr_set_pmfsum}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_set_pmfsum}
@end ifnothtml
call to its (approximate) value.

The size of an auxiliary table can be set by
@ifhtml
@ref{funct:unur_dari_set_tablesize,@command{unur_dari_set_tablesize}.}
@end ifhtml
@ifnothtml
@command{unur_dari_set_tablesize}.
@end ifnothtml
The expected number of evaluations can be reduced by switching
the use of squeezes by means of
@ifhtml
@ref{funct:unur_dari_set_squeeze,@command{unur_dari_set_squeeze}.}
@end ifhtml
@ifnothtml
@command{unur_dari_set_squeeze}.
@end ifnothtml
It is possible to change the parameters and the domain of the chosen
distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator object.
Notice, that derived parameters like the mode must also be (re-) set
if the parameters or the domain has be changed.

There exists a test mode that verifies whether the conditions for
the method are satisfied or not. It can be switched on by calling
@ifhtml
@ref{funct:unur_dari_set_verify,@command{unur_dari_set_verify}}
@end ifhtml
@ifnothtml
@command{unur_dari_set_verify}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_dari_chg_verify,@command{unur_dari_chg_verify},}
@end ifhtml
@ifnothtml
@command{unur_dari_chg_verify},
@end ifnothtml
respectively.
Notice however that sampling is (much) slower then.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_dari_new,unur_dari_new}
@item @ref{funct:unur_dari_set_squeeze,unur_dari_set_squeeze}
@item @ref{funct:unur_dari_set_tablesize,unur_dari_set_tablesize}
@item @ref{funct:unur_dari_set_cpfactor,unur_dari_set_cpfactor}
@item @ref{funct:unur_dari_set_verify,unur_dari_set_verify}
@item @ref{funct:unur_dari_chg_verify,unur_dari_chg_verify}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_dari_new}
@deftypefn Function {UNUR_PAR*} unur_dari_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dari_new}
@deftypefn {} {UNUR_PAR*} unur_dari_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_dari_set_squeeze}
@deftypefn Function {int} unur_dari_set_squeeze (UNUR_PAR* @var{parameters}, int @var{squeeze})
Turn utilization of the squeeze of the algorithm on/off.
This squeeze does not resamble the squeeze of the continuous TDR
method. It was especially designed for rejection inversion.

The squeeze is not necessary if the size of the auxiliary table is
big enough (for the given distribution).
Using a squeeze is suggested to speed up the algorithm if the
domain of the distribution is very big or if only small samples are
produced.

Default: no squeeze.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dari_set_squeeze}
@deftypefn {} {int} unur_dari_set_squeeze (UNUR_PAR* @var{parameters}, int @var{squeeze})
Turn utilization of the squeeze of the algorithm on/off.
This squeeze does not resamble the squeeze of the continuous TDR
method. It was especially designed for rejection inversion.

The squeeze is not necessary if the size of the auxiliary table is
big enough (for the given distribution).
Using a squeeze is suggested to speed up the algorithm if the
domain of the distribution is very big or if only small samples are
produced.

Default: no squeeze.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_dari_set_tablesize}
@deftypefn Function {int} unur_dari_set_tablesize (UNUR_PAR* @var{parameters}, int @var{size})
Set the size for the auxiliary table, that stores constants
computed during generation.
If @var{size} is set to @code{0} no table is used.
The speed-up can be impressive if the PMF is expensive to
evaluate and the ``main part of the distribution'' is concentrated
in an interval shorter than the size of the table.

Default is @code{100}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dari_set_tablesize}
@deftypefn {} {int} unur_dari_set_tablesize (UNUR_PAR* @var{parameters}, int @var{size})
Set the size for the auxiliary table, that stores constants
computed during generation.
If @var{size} is set to @code{0} no table is used.
The speed-up can be impressive if the PMF is expensive to
evaluate and the ``main part of the distribution'' is concentrated
in an interval shorter than the size of the table.

Default is @code{100}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_dari_set_cpfactor}
@deftypefn Function {int} unur_dari_set_cpfactor (UNUR_PAR* @var{parameters}, double @var{cp_factor})
Set factor for position of the left and right construction point,
resp.
The @var{cp_factor} is used to find almost optimal construction
points for the hat function.
The @var{cp_factor} must be positive and should not exceed 2.
There is no need to change this factor in almost all situations.

Default is @code{0.664}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dari_set_cpfactor}
@deftypefn {} {int} unur_dari_set_cpfactor (UNUR_PAR* @var{parameters}, double @var{cp_factor})
Set factor for position of the left and right construction point,
resp.
The @var{cp_factor} is used to find almost optimal construction
points for the hat function.
The @var{cp_factor} must be positive and should not exceed 2.
There is no need to change this factor in almost all situations.

Default is @code{0.664}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_dari_set_verify}
@anchor{funct:unur_dari_chg_verify}
@deftypefn Function {int} unur_dari_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx Function {int} unur_dari_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the condition is violated for some @i{x} then @code{unur_errno}
is set to @code{UNUR_ERR_GEN_CONDITION}. However notice that this
might happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dari_set_verify}
@anchor{funct:unur_dari_chg_verify}
@deftypefn {} {int} unur_dari_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx {} {int} unur_dari_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the condition is violated for some @i{x} then @code{unur_errno}
is set to @code{UNUR_ERR_GEN_CONDITION}. However notice that this
might happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo




@c
@c end of dari.h
@c -------------------------------------
@c -------------------------------------
@c dau.h
@c

@page
@node DAU
@subsection   DAU  --  (Discrete) Alias-Urn method

@table @i
@item Required:
probability vector (PV)
@item Speed:
Set-up: slow (linear with the vector-length), Sampling: very fast
@item Reinit:
supported
@item Reference:
@ifhtml
@ref{bib:WAa77,, [WAa77]}
@end ifhtml
@ifnothtml
[WAa77]
@end ifnothtml
@ifhtml
@ref{bib:HLD04,, [HLD04: Sect.3.2]}
@end ifhtml
@ifnothtml
[HLD04: Sect.3.2]
@end ifnothtml

@end table


DAU samples from distributions with arbitrary but finite
probability vectors (PV) of length @i{N}.
The algorithmus is based on an ingeneous method by A.J. Walker
and requires a table of size (at least) @i{N}.
It needs one random numbers and only one comparison for each
generated random variate. The setup time for constructing the
tables is @i{O(N)}.

By default the probability vector is indexed starting at
@code{0}. However this can be changed in the distribution object by
a
@ifhtml
@ref{funct:unur_distr_discr_set_domain,@command{unur_distr_discr_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_set_domain}
@end ifnothtml
call.

The method also works when no probability vector but a PMF is
given. However then additionally a bounded (not too large) domain
must be given or the sum over the PMF (see
@ifhtml
@ref{funct:unur_distr_discr_make_pv,@command{unur_distr_discr_make_pv}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_make_pv}
@end ifnothtml
for details).


@subsubheading How To Use


Create an object for a discrete distribution either by setting a
probability vector or a PMF. The performance can be slightly
influenced by setting the size of the used table which can be
changed by
@ifhtml
@ref{funct:unur_dau_set_urnfactor,@command{unur_dau_set_urnfactor}.}
@end ifhtml
@ifnothtml
@command{unur_dau_set_urnfactor}.
@end ifnothtml
It is possible to change the parameters and the domain of the chosen
distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator object.



@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_dau_new,unur_dau_new}
@item @ref{funct:unur_dau_set_urnfactor,unur_dau_set_urnfactor}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_dau_new}
@deftypefn Function {UNUR_PAR*} unur_dau_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dau_new}
@deftypefn {} {UNUR_PAR*} unur_dau_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_dau_set_urnfactor}
@deftypefn Function {int} unur_dau_set_urnfactor (UNUR_PAR* @var{parameters}, double @var{factor})
Set size of urn table relative to length of the probability
vector. It must not be less than 1. Larger tables result in
(slightly) faster generation times but require a more expensive
setup. However sizes larger than 2 are not recommended.

Default is @code{1}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dau_set_urnfactor}
@deftypefn {} {int} unur_dau_set_urnfactor (UNUR_PAR* @var{parameters}, double @var{factor})
Set size of urn table relative to length of the probability
vector. It must not be less than 1. Larger tables result in
(slightly) faster generation times but require a more expensive
setup. However sizes larger than 2 are not recommended.

Default is @code{1}.
@end deftypefn
@end ifnotinfo




@c
@c end of dau.h
@c -------------------------------------
@c -------------------------------------
@c dext.h
@c

@page
@node DEXT
@subsection   DEXT  --  wrapper for Discrete EXTernal generators

@table @i
@item Required:
routine for sampling discrete random variates
@item Speed:
depends on external generator
@item Reinit:
supported
@end table


Method DEXT is a wrapper for external generators for discrete
univariate distributions. It allows the usage of external
random variate generators within the UNU.RAN framework.


@subsubheading How To Use


The following steps are required to use some external generator
within the UNU.RAN framework (some of these are optional):

@enumerate
@item
Make an empty generator object using a
@ifhtml
@ref{funct:unur_dext_new,@command{unur_dext_new}}
@end ifhtml
@ifnothtml
@command{unur_dext_new}
@end ifnothtml
call.
The argument @var{distribution} is optional and can be replaced
by @code{NULL}. However, it is required if you want to pass
parameters of the generated distribution to the external
generator or for running some validation tests provided by
UNU.RAN.

@item
Create an initialization routine of type
@code{int (*init)(UNUR_GEN *gen)} and plug it into the generator
object using the
@ifhtml
@ref{funct:unur_dext_set_init,@command{unur_dext_set_init}}
@end ifhtml
@ifnothtml
@command{unur_dext_set_init}
@end ifnothtml
call. Notice that the
@var{init} routine must return @code{UNUR_SUCCESS} when it has
been executed successfully and @code{UNUR_FAILURE} otherwise.
It is possible to get the size of and the pointer to the array
of parameters of the underlying distribution object by the
respective calls
@ifhtml
@ref{funct:unur_dext_get_ndistrparams,@command{unur_dext_get_ndistrparams}}
@end ifhtml
@ifnothtml
@command{unur_dext_get_ndistrparams}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_dext_get_distrparams,@command{unur_dext_get_distrparams}.}
@end ifhtml
@ifnothtml
@command{unur_dext_get_distrparams}.
@end ifnothtml
Parameters for the external generator that are computed in the
@var{init} routine can be stored in a single array or structure
which is available by the
@ifhtml
@ref{funct:unur_dext_get_params,@command{unur_dext_get_params}}
@end ifhtml
@ifnothtml
@command{unur_dext_get_params}
@end ifnothtml
call.

Using an @var{init} routine is optional and can be omitted.

@item
Create a sampling routine of type
@code{int (*sample)(UNUR_GEN *gen)} and plug it into the
generator object using the
@ifhtml
@ref{funct:unur_dext_set_sample,@command{unur_dext_set_sample}}
@end ifhtml
@ifnothtml
@command{unur_dext_set_sample}
@end ifnothtml
call.

Uniform random numbers are provided by the
@ifhtml
@ref{funct:unur_sample_urng,@command{unur_sample_urng}}
@end ifhtml
@ifnothtml
@command{unur_sample_urng}
@end ifnothtml
call. Do not use your own implementation of a uniform random
number generator directly. If you want to use your own random
number generator we recommend to use the UNU.RAN interface (see
@pxref{URNG,,Using uniform random number generators}).

The array or structure that contains parameters for the external
generator that are computed in the @var{init} routine are
available using the
@ifhtml
@ref{funct:unur_dext_get_params,@command{unur_dext_get_params}}
@end ifhtml
@ifnothtml
@command{unur_dext_get_params}
@end ifnothtml
call.

Using a @var{sample} routine is of course obligatory.
@end enumerate

It is possible to change the parameters and the domain of the
chosen distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the
generator object. The @var{init} routine is then called again.

Here is a short example that demonstrates the application of
this method by means of the geometric distribution:

@smallexample
@include ref_example_dext.texi
@end smallexample




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_dext_new,unur_dext_new}
@item @ref{funct:unur_dext_set_init,unur_dext_set_init}
@item @ref{funct:unur_dext_set_sample,unur_dext_set_sample}
@item @ref{funct:unur_dext_get_params,unur_dext_get_params}
@item @ref{funct:unur_dext_get_distrparams,unur_dext_get_distrparams}
@item @ref{funct:unur_dext_get_ndistrparams,unur_dext_get_ndistrparams}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_dext_new}
@deftypefn Function {UNUR_PAR*} unur_dext_new (const @var{UNUR_DISTR* distribution})
Get default parameters for new generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dext_new}
@deftypefn {} {UNUR_PAR*} unur_dext_new (const @var{UNUR_DISTR* distribution})
Get default parameters for new generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_dext_set_init}
@deftypefn Function {int} unur_dext_set_init (UNUR_PAR* @var{parameters}, int (* @var{init})(UNUR_GEN* gen ))
Set initialization routine for external generator. Inside the

@emph{Important:} The routine @var{init} must return
@code{UNUR_SUCCESS} when the generator was initialized successfully
and @code{UNUR_FAILURE} otherwise.

Parameters that are computed in the @var{init} routine can be
stored in an array or structure that is avaiable by means of the
@ifhtml
@ref{funct:unur_dext_get_params,@command{unur_dext_get_params}}
@end ifhtml
@ifnothtml
@command{unur_dext_get_params}
@end ifnothtml
call. Parameters of the underlying
distribution object can be obtained by the
@ifhtml
@ref{funct:unur_dext_get_distrparams,@command{unur_dext_get_distrparams}}
@end ifhtml
@ifnothtml
@command{unur_dext_get_distrparams}
@end ifnothtml
call.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dext_set_init}
@deftypefn {} {int} unur_dext_set_init (UNUR_PAR* @var{parameters}, int (* @var{init})(UNUR_GEN* gen ))
Set initialization routine for external generator. Inside the

@emph{Important:} The routine @var{init} must return
@code{UNUR_SUCCESS} when the generator was initialized successfully
and @code{UNUR_FAILURE} otherwise.

Parameters that are computed in the @var{init} routine can be
stored in an array or structure that is avaiable by means of the
@ifhtml
@ref{funct:unur_dext_get_params,@command{unur_dext_get_params}}
@end ifhtml
@ifnothtml
@command{unur_dext_get_params}
@end ifnothtml
call. Parameters of the underlying
distribution object can be obtained by the
@ifhtml
@ref{funct:unur_dext_get_distrparams,@command{unur_dext_get_distrparams}}
@end ifhtml
@ifnothtml
@command{unur_dext_get_distrparams}
@end ifnothtml
call.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_dext_set_sample}
@deftypefn Function {int} unur_dext_set_sample (UNUR_PAR* @var{parameters}, int (* @var{sample})(UNUR_GEN* gen ))
Set sampling routine for external generator.

@emph{Important:}
Use @code{unur_sample_urng(gen)} to get a uniform random number.
The pointer to the array or structure that contains the parameters
that are precomputed in the @var{init} routine are available by
@code{unur_dext_get_params(gen,0)}.
Additionally one can use the
@ifhtml
@ref{funct:unur_dext_get_distrparams,@command{unur_dext_get_distrparams}}
@end ifhtml
@ifnothtml
@command{unur_dext_get_distrparams}
@end ifnothtml
call.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dext_set_sample}
@deftypefn {} {int} unur_dext_set_sample (UNUR_PAR* @var{parameters}, int (* @var{sample})(UNUR_GEN* gen ))
Set sampling routine for external generator.

@emph{Important:}
Use @code{unur_sample_urng(gen)} to get a uniform random number.
The pointer to the array or structure that contains the parameters
that are precomputed in the @var{init} routine are available by
@code{unur_dext_get_params(gen,0)}.
Additionally one can use the
@ifhtml
@ref{funct:unur_dext_get_distrparams,@command{unur_dext_get_distrparams}}
@end ifhtml
@ifnothtml
@command{unur_dext_get_distrparams}
@end ifnothtml
call.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_dext_get_params}
@deftypefn Function {void*} unur_dext_get_params (UNUR_GEN* @var{generator}, size_t @var{size})
Get pointer to memory block for storing parameters of external
generator. A memory block of size @var{size} is automatically (re-)
allocated if necessary and the pointer to this block is stored in
the @var{generator} object. If one only needs the pointer to this
memory block set @var{size} to @code{0}.

Notice, that @var{size} is the size of the memory block and not the
length of an array.

@emph{Important:} This rountine should only be used in the
initialization and sampling routine of the external generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dext_get_params}
@deftypefn {} {void*} unur_dext_get_params (UNUR_GEN* @var{generator}, size_t @var{size})
Get pointer to memory block for storing parameters of external
generator. A memory block of size @var{size} is automatically (re-)
allocated if necessary and the pointer to this block is stored in
the @var{generator} object. If one only needs the pointer to this
memory block set @var{size} to @code{0}.

Notice, that @var{size} is the size of the memory block and not the
length of an array.

@emph{Important:} This rountine should only be used in the
initialization and sampling routine of the external generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_dext_get_distrparams}
@anchor{funct:unur_dext_get_ndistrparams}
@deftypefn Function {double*} unur_dext_get_distrparams (UNUR_GEN* @var{generator})
@deftypefnx Function {int} unur_dext_get_ndistrparams (UNUR_GEN* @var{generator})
Get size of and pointer to array of parameters of underlying
distribution in @var{generator} object.

@emph{Important:} These rountines should only be used in the
initialization and sampling routine of the external generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dext_get_distrparams}
@anchor{funct:unur_dext_get_ndistrparams}
@deftypefn {} {double*} unur_dext_get_distrparams (UNUR_GEN* @var{generator})
@deftypefnx {} {int} unur_dext_get_ndistrparams (UNUR_GEN* @var{generator})
Get size of and pointer to array of parameters of underlying
distribution in @var{generator} object.

@emph{Important:} These rountines should only be used in the
initialization and sampling routine of the external generator.
@end deftypefn
@end ifnotinfo




@c
@c end of dext.h
@c -------------------------------------
@c -------------------------------------
@c dgt.h
@c

@page
@node DGT
@subsection   DGT  --  (Discrete) Guide Table method (indexed search)

@table @i
@item Required:
probability vector (PV)
@item Speed:
Set-up: slow (linear with the vector-length), Sampling: very fast
@item Reinit:
supported
@item Reference:
@ifhtml
@ref{bib:CAa74,, [CAa74]}
@end ifhtml
@ifnothtml
[CAa74]
@end ifnothtml
@ifhtml
@ref{bib:HLD04,, [HLD04: Sect.3.1.2]}
@end ifhtml
@ifnothtml
[HLD04: Sect.3.1.2]
@end ifnothtml

@end table


DGT samples from arbitrary but finite probability vectors. Random
numbers are generated by the inversion method, i.e.,

@enumerate
@item
Generate a random number U ~ U(0,1).
@item
Find smallest integer I such that F(I) = P(X<=I) >= U.
@end enumerate

Step (2) is the crucial step. Using sequential search requires
@i{O(E(X))} comparisons, where @i{E(X)} is the expectation of
the distribution. Indexed search, however, uses a guide table to
jump to some @i{I'} <= @i{I} near @i{I} to find @i{X} in constant
time. Indeed the expected number of comparisons is reduced to 2,
when the guide table has the same size as the probability vector
(this is the default). For larger guide tables this number
becomes smaller (but is always larger than 1), for smaller
tables it becomes larger. For the limit case of table size 1 the
algorithm simply does sequential search (but uses a more expensive
setup then method DSS (@pxref{DSS}). On the other hand the
setup time for guide table is @i{O(N)}, where @i{N} denotes the
length of the probability vector (for size 1 no preprocessing is
required). Moreover, for very large guide tables memory effects might
even reduce the speed of the algorithm. So we do not recommend to
use guide tables that are more than three times larger than the
given probability vector. If only a few random numbers have to be
generated, (much) smaller table sizes are better.
The size of the guide table relative to the length of the given
probability vector can be set by a
@ifhtml
@ref{funct:unur_dgt_set_guidefactor,@command{unur_dgt_set_guidefactor}}
@end ifhtml
@ifnothtml
@command{unur_dgt_set_guidefactor}
@end ifnothtml
call.

There exist two variants for the setup step which can be set by a
@ifhtml
@ref{funct:unur_dgt_set_variant,@command{unur_dgt_set_variant}}
@end ifhtml
@ifnothtml
@command{unur_dgt_set_variant}
@end ifnothtml
call: Variants 1 and 2.
Variant 2 is faster but more sensitive to roundoff errors when the
guide table is large. By default variant 2 is used for short
probability vectors (@i{N}<1000) and variant 1 otherwise.

By default the probability vector is indexed starting at
@code{0}. However this can be changed in the distribution object by
a
@ifhtml
@ref{funct:unur_distr_discr_set_domain,@command{unur_distr_discr_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_set_domain}
@end ifnothtml
call.

The method also works when no probability vector but a PMF is
given. However, then additionally a bounded (not too large) domain
must be given or the sum over the PMF. In the latter case the
domain of the distribution is trucated (see
@ifhtml
@ref{funct:unur_distr_discr_make_pv,@command{unur_distr_discr_make_pv}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_make_pv}
@end ifnothtml
for details).


@subsubheading How To Use


Create an object for a discrete distribution either by setting a
probability vector or a PMF. The performance can be slightly
influenced by setting the size of the used table which can be
changed by
@ifhtml
@ref{funct:unur_dgt_set_guidefactor,@command{unur_dgt_set_guidefactor}.}
@end ifhtml
@ifnothtml
@command{unur_dgt_set_guidefactor}.
@end ifnothtml
It is possible to change the parameters and the domain of the chosen
distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator object.



@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_dgt_new,unur_dgt_new}
@item @ref{funct:unur_dgt_set_guidefactor,unur_dgt_set_guidefactor}
@item @ref{funct:unur_dgt_set_variant,unur_dgt_set_variant}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_dgt_new}
@deftypefn Function {UNUR_PAR*} unur_dgt_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dgt_new}
@deftypefn {} {UNUR_PAR*} unur_dgt_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_dgt_set_guidefactor}
@deftypefn Function {int} unur_dgt_set_guidefactor (UNUR_PAR* @var{parameters}, double @var{factor})
Set size of guide table relative to length of PV.
Larger guide tables result in faster generation time but require a
more expensive setup. Sizes larger than 3 are not recommended.
If the relative size is set to 0, sequential search is used.
However, this is not recommended, except in exceptional cases, since
method DSS (@pxref{DSS}) is has almost no setup and is thus faster
(but requires the sum over the PV as input parameter).

Default is @code{1}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dgt_set_guidefactor}
@deftypefn {} {int} unur_dgt_set_guidefactor (UNUR_PAR* @var{parameters}, double @var{factor})
Set size of guide table relative to length of PV.
Larger guide tables result in faster generation time but require a
more expensive setup. Sizes larger than 3 are not recommended.
If the relative size is set to 0, sequential search is used.
However, this is not recommended, except in exceptional cases, since
method DSS (@pxref{DSS}) is has almost no setup and is thus faster
(but requires the sum over the PV as input parameter).

Default is @code{1}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_dgt_set_variant}
@deftypefn Function {int} unur_dgt_set_variant (UNUR_PAR* @var{parameters}, unsigned @var{variant})
Set variant for setup step. Possible values are @code{1} or
@code{2}.
Variant @code{2} is faster but more sensitive to roundoff errors
when the guide table is large.
By default variant @code{2} is used for short probability
vectors (@i{N}<1000) and variant @code{1} otherwise.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dgt_set_variant}
@deftypefn {} {int} unur_dgt_set_variant (UNUR_PAR* @var{parameters}, unsigned @var{variant})
Set variant for setup step. Possible values are @code{1} or
@code{2}.
Variant @code{2} is faster but more sensitive to roundoff errors
when the guide table is large.
By default variant @code{2} is used for short probability
vectors (@i{N}<1000) and variant @code{1} otherwise.
@end deftypefn
@end ifnotinfo




@c
@c end of dgt.h
@c -------------------------------------
@c -------------------------------------
@c dsrou.h
@c

@page
@node DSROU
@subsection   DSROU  --  Discrete Simple Ratio-Of-Uniforms method

@table @i
@item Required:
T-concave PMF, mode, sum over PMF
@item Speed:
Set-up: fast, Sampling: slow
@item Reinit:
supported
@item Reference:
@ifhtml
@ref{bib:LJa01,, [LJa01]}
@end ifhtml
@ifnothtml
[LJa01]
@end ifnothtml
@ifhtml
@ref{bib:HLD04,, [HLD04: Sect.10.3.2; Alg.10.6]}
@end ifhtml
@ifnothtml
[HLD04: Sect.10.3.2; Alg.10.6]
@end ifnothtml

@end table


DSROU is based on the ratio-of-uniforms method
(@pxref{Ratio-of-Uniforms}) but uses universal
inequalities for constructing a (universal) bounding rectangle.
It works for all @i{T}-concave distributions with
@iftex
@math{T(x) = -1/\sqrt{x}}
@end iftex
@ifhtml
@html
<I>T</I>(<I>x</I>) = -1/sqrt(<I>x</I>)
@end html
@end ifhtml
@ifinfo
@math{T(x) = -1/sqrt(x)}
@end ifinfo
.

The method requires the PMF, the (exact) location of the mode
and the sum over the given PDF. The rejection constant is 4 for
all @i{T}-concave distributions. Optionally the CDF at the mode
can be given to increase the performance of the algorithm. Then
the rejection constant is reduced to 2.


@subsubheading How To Use


The method works for @i{T}-concave discrete distributions with
given PMF. The sum over of the PMF or an upper bound of this sum
must be known.

Optionally the CDF at the mode can be given to increase the
performance using
@ifhtml
@ref{funct:unur_dsrou_set_cdfatmode,@command{unur_dsrou_set_cdfatmode}.}
@end ifhtml
@ifnothtml
@command{unur_dsrou_set_cdfatmode}.
@end ifnothtml
However, this @strong{must not} be called if the sum over the
PMF is replaced by an upper bound.

It is possible to change the parameters and the domain of the chosen
distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator object.

If any of mode, CDF at mode, or the sum over the PMF has been
changed, then
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
must be executed.
(Otherwise the generator produces garbage).

There exists a test mode that verifies whether the conditions
for the method are satisfied or not while sampling. It can be
switched on or off by calling
@ifhtml
@ref{funct:unur_dsrou_set_verify,@command{unur_dsrou_set_verify}}
@end ifhtml
@ifnothtml
@command{unur_dsrou_set_verify}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_dsrou_chg_verify,@command{unur_dsrou_chg_verify},}
@end ifhtml
@ifnothtml
@command{unur_dsrou_chg_verify},
@end ifnothtml
respectively.
Notice however that sampling is (a little bit) slower then.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_dsrou_new,unur_dsrou_new}
@item @ref{funct:unur_dsrou_set_cdfatmode,unur_dsrou_set_cdfatmode}
@item @ref{funct:unur_dsrou_set_verify,unur_dsrou_set_verify}
@item @ref{funct:unur_dsrou_chg_verify,unur_dsrou_chg_verify}
@item @ref{funct:unur_dsrou_chg_cdfatmode,unur_dsrou_chg_cdfatmode}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_dsrou_new}
@deftypefn Function {UNUR_PAR*} unur_dsrou_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dsrou_new}
@deftypefn {} {UNUR_PAR*} unur_dsrou_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_dsrou_set_cdfatmode}
@deftypefn Function {int} unur_dsrou_set_cdfatmode (UNUR_PAR* @var{parameters}, double @var{Fmode})
Set CDF at mode.
When set, the performance of the algorithm is increased by factor 2.
However, when the parameters of the distribution are changed
@ifhtml
@ref{funct:unur_dsrou_chg_cdfatmode,@command{unur_dsrou_chg_cdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_dsrou_chg_cdfatmode}
@end ifnothtml
has to be used to update this value.
Notice that the algorithm detects a mode at the left boundary of
the domain automatically and it is not necessary to use this call
for a monotonically decreasing PMF.

Default: not set.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dsrou_set_cdfatmode}
@deftypefn {} {int} unur_dsrou_set_cdfatmode (UNUR_PAR* @var{parameters}, double @var{Fmode})
Set CDF at mode.
When set, the performance of the algorithm is increased by factor 2.
However, when the parameters of the distribution are changed
@ifhtml
@ref{funct:unur_dsrou_chg_cdfatmode,@command{unur_dsrou_chg_cdfatmode}}
@end ifhtml
@ifnothtml
@command{unur_dsrou_chg_cdfatmode}
@end ifnothtml
has to be used to update this value.
Notice that the algorithm detects a mode at the left boundary of
the domain automatically and it is not necessary to use this call
for a monotonically decreasing PMF.

Default: not set.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_dsrou_set_verify}
@anchor{funct:unur_dsrou_chg_verify}
@deftypefn Function {int} unur_dsrou_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx Function {int} unur_dsrou_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the condition squeeze(@i{x}) <= PMF(@i{x}) <= hat(@i{x}) is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dsrou_set_verify}
@anchor{funct:unur_dsrou_chg_verify}
@deftypefn {} {int} unur_dsrou_set_verify (UNUR_PAR* @var{parameters}, int @var{verify})
@deftypefnx {} {int} unur_dsrou_chg_verify (UNUR_GEN* @var{generator}, int @var{verify})
Turn verifying of algorithm while sampling on/off.
If the condition squeeze(@i{x}) <= PMF(@i{x}) <= hat(@i{x}) is
violated for some @i{x} then @code{unur_errno} is set to
@code{UNUR_ERR_GEN_CONDITION}. However notice that this might
happen due to round-off errors for a few values of
@i{x} (less than 1%).

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_dsrou_chg_cdfatmode}
@deftypefn Function {int} unur_dsrou_chg_cdfatmode (UNUR_GEN* @var{generator}, double @var{Fmode})
Change CDF at mode of distribution.
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
must be executed before sampling from the
generator again.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dsrou_chg_cdfatmode}
@deftypefn {} {int} unur_dsrou_chg_cdfatmode (UNUR_GEN* @var{generator}, double @var{Fmode})
Change CDF at mode of distribution.
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
must be executed before sampling from the
generator again.
@end deftypefn
@end ifnotinfo




@c
@c end of dsrou.h
@c -------------------------------------
@c -------------------------------------
@c dss.h
@c

@page
@node DSS
@subsection   DSS  --  (Discrete) Sequential Search method

@table @i
@item Required:
probability vector (PV) and sum over PV; or probability mass function(PMF), sum over PV and domain; or or cumulative distribution function (CDF)
@item Speed:
Set-up: fast, Sampling: very slow (linear in expectation)
@item Reinit:
supported
@item Reference:
@ifhtml
@ref{bib:HLD04,, [HLD04: Sect.3.1.1; Alg.3.1]}
@end ifhtml
@ifnothtml
[HLD04: Sect.3.1.1; Alg.3.1]
@end ifnothtml

@end table


DSS samples from arbitrary discrete distributions.
Random numbers are generated by the inversion method, i.e.,

@enumerate
@item
Generate a random number U ~ U(0,1).
@item
Find smallest integer I such that F(I) = P(X<=I) >= U.
@end enumerate

Step (2) is the crucial step. Using sequential search requires
@i{O(E(X))} comparisons, where @i{E(X)} is the expectation of
the distribution. Thus this method is only recommended when only
a few random variates from the given distribution are required.
Otherwise, table methods like DGT (@pxref{DGT}) or DAU (@pxref{DAU})
are much faster. These methods also need not the sum over the
PMF (or PV) as input. On the other hand, however, these methods
always compute a table.

DSS runs with the PV, the PMF, or the CDF of the distribution.
It uses actually uses the first one in this list (in this
ordering) that could be found.


@subsubheading How To Use


It works with a discrete distribution object with contains at
least the PV, the PMF, or the CDF.

It is possible to change the parameters and the domain of the chosen
distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator object.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_dss_new,unur_dss_new}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_dss_new}
@deftypefn Function {UNUR_PAR*} unur_dss_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dss_new}
@deftypefn {} {UNUR_PAR*} unur_dss_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo




@c
@c end of dss.h
@c -------------------------------------
@c -------------------------------------
@c dstd.h
@c

@page
@node DSTD
@subsection   DSTD  --  Discrete STandarD distributions

@table @i
@item Required:
standard distribution from UNU.RAN library (@pxref{Stddist,,Standard distributions}) or discrete distribution with inverse CDF.
@item Speed:
Set-up: fast, Sampling: depends on distribution and generator
@item Reinit:
supported
@end table


DSTD is a wrapper for special generators for discrete univariate
standard distributions. It only works for distributions in the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions})
or for discrete distributions where the inverse CDF is given.
If a distribution object is provided that is build from scratch,
it must provide the inverse CDF. Then CSTD implements the
inversion method. Otherwise, the @code{NULL} pointer is returned.

For some distributions more than one special generator
is possible.


@subsubheading How To Use


Create a distribution object for a standard distribution
from the UNU.RAN library
(@pxref{Stddist,,Standard distributions}),
or create a discrete distribution object and set the function
for the inverse CDF using
@ifhtml
@ref{funct:unur_distr_discr_set_invcdf,@command{unur_distr_discr_set_invcdf}.}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_set_invcdf}.
@end ifnothtml
For some distributions more than one special generator
(@emph{variants}) is possible. These can be choosen by a
@ifhtml
@ref{funct:unur_dstd_set_variant,@command{unur_dstd_set_variant}}
@end ifhtml
@ifnothtml
@command{unur_dstd_set_variant}
@end ifnothtml
call. For possible variants
@xref{Stddist,,Standard distributions}.
However the following are common to all distributions:

@table @code
@item UNUR_STDGEN_DEFAULT
the default generator.
@item UNUR_STDGEN_FAST
the fastest available special generator.
@item UNUR_STDGEN_INVERSION
the inversion method (if available).
@end table

Notice that the variant @code{UNUR_STDGEN_FAST} for a special
generator might be slower than one of the universal algorithms!
Additional variants may exist for particular distributions.

Sampling from truncated distributions (which can be constructed by
changing the default domain of a distribution by means of
@ifhtml
@ref{funct:unur_distr_discr_set_domain,@command{unur_distr_discr_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_set_domain}
@end ifnothtml
or unur_dstd_chg_truncated calls)
is possible but requires the inversion method. Moreover the CDF
of the distribution must be implemented.

It is possible to change the parameters and the domain of the chosen
distribution and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator object.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_dstd_new,unur_dstd_new}
@item @ref{funct:unur_dstd_set_variant,unur_dstd_set_variant}
@item @ref{funct:unur_dstd_chg_truncated,unur_dstd_chg_truncated}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_dstd_new}
@deftypefn Function {UNUR_PAR*} unur_dstd_new (const @var{UNUR_DISTR* distribution})
Get default parameters for new generator. It requires a distribution object
for a discrete univariant distribution from the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions}).

Using a truncated distribution is allowed only if the inversion method
is available and selected by the
@ifhtml
@ref{funct:unur_dstd_set_variant,@command{unur_dstd_set_variant}}
@end ifhtml
@ifnothtml
@command{unur_dstd_set_variant}
@end ifnothtml
call immediately
after creating the parameter object.
Use a
@ifhtml
@ref{funct:unur_distr_discr_set_domain,@command{unur_distr_discr_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_set_domain}
@end ifnothtml
call to get a truncated
distribution.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dstd_new}
@deftypefn {} {UNUR_PAR*} unur_dstd_new (const @var{UNUR_DISTR* distribution})
Get default parameters for new generator. It requires a distribution object
for a discrete univariant distribution from the
UNU.RAN library of standard distributions
(@pxref{Stddist,,Standard distributions}).

Using a truncated distribution is allowed only if the inversion method
is available and selected by the
@ifhtml
@ref{funct:unur_dstd_set_variant,@command{unur_dstd_set_variant}}
@end ifhtml
@ifnothtml
@command{unur_dstd_set_variant}
@end ifnothtml
call immediately
after creating the parameter object.
Use a
@ifhtml
@ref{funct:unur_distr_discr_set_domain,@command{unur_distr_discr_set_domain}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_set_domain}
@end ifnothtml
call to get a truncated
distribution.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_dstd_set_variant}
@deftypefn Function {int} unur_dstd_set_variant (UNUR_PAR* @var{parameters}, unsigned @var{variant})
Set variant (special generator) for sampling from a given distribution.
For possible variants
@pxref{Stddist,,Standard distributions}.

Common variants are @code{UNUR_STDGEN_DEFAULT} for the default generator,
@code{UNUR_STDGEN_FAST} for (one of the) fastest implemented
special generators, and @code{UNUR_STDGEN_INVERSION} for the
inversion method (if available).
If the selected variant number is not implemented, then an error code is
returned and the variant is not changed.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dstd_set_variant}
@deftypefn {} {int} unur_dstd_set_variant (UNUR_PAR* @var{parameters}, unsigned @var{variant})
Set variant (special generator) for sampling from a given distribution.
For possible variants
@pxref{Stddist,,Standard distributions}.

Common variants are @code{UNUR_STDGEN_DEFAULT} for the default generator,
@code{UNUR_STDGEN_FAST} for (one of the) fastest implemented
special generators, and @code{UNUR_STDGEN_INVERSION} for the
inversion method (if available).
If the selected variant number is not implemented, then an error code is
returned and the variant is not changed.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_dstd_chg_truncated}
@deftypefn Function {int} unur_dstd_chg_truncated (UNUR_GEN* @var{generator}, int @var{left}, int @var{right})
Change left and right border of the domain of the (truncated) distribution.
This is only possible if the inversion method is used.
Otherwise this call has no effect and an error code is returned.

Notice that the given truncated domain must be a subset of the
domain of the given distribution. The generator always uses the
intersection of the domain of the distribution and the truncated
domain given by this call.

It is not required to run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
after this call has been used.

@emph{Important:} If the CDF is (almost) the same for @var{left} and
@var{right} and (almost) equal to @code{0} or @code{1}, then the truncated
domain is not chanced and the call returns an error code.

@emph{Notice:} If the parameters of the distribution has been changed
it is recommended to set the truncated domain again, since the
former call might change the domain of the distribution but not
update the values for the boundaries of the truncated
distribution.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_dstd_chg_truncated}
@deftypefn {} {int} unur_dstd_chg_truncated (UNUR_GEN* @var{generator}, int @var{left}, int @var{right})
Change left and right border of the domain of the (truncated) distribution.
This is only possible if the inversion method is used.
Otherwise this call has no effect and an error code is returned.

Notice that the given truncated domain must be a subset of the
domain of the given distribution. The generator always uses the
intersection of the domain of the distribution and the truncated
domain given by this call.

It is not required to run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
after this call has been used.

@emph{Important:} If the CDF is (almost) the same for @var{left} and
@var{right} and (almost) equal to @code{0} or @code{1}, then the truncated
domain is not chanced and the call returns an error code.

@emph{Notice:} If the parameters of the distribution has been changed
it is recommended to set the truncated domain again, since the
former call might change the domain of the distribution but not
update the values for the boundaries of the truncated
distribution.
@end deftypefn
@end ifnotinfo




@c
@c end of dstd.h
@c -------------------------------------
@c -------------------------------------
@c methods.dh
@c

@page
@node Methods_for_MATR
@section   Methods for random matrices

@menu
* MCORR:: Random CORRelation matrix
@end menu



@subheading Overview of methods

@include methods_matr.texi



@c
@c end of methods.dh
@c -------------------------------------
@c -------------------------------------
@c mcorr.h
@c

@page
@node MCORR
@subsection   MCORR  --  Random CORRelation matrix

@table @i
@item Required:
Distribution object for random correlation matrix
@item Speed:
Set-up: fast, Sampling: depends on dimension
@item Reinit:
supported
@item Reference:
@ifhtml
@ref{bib:DLa86,, [DLa86: Sect.6.1; p.605]}
@end ifhtml
@ifnothtml
[DLa86: Sect.6.1; p.605]
@end ifnothtml
@ifhtml
@ref{bib:MOa84,, [MOa84]}
@end ifhtml
@ifnothtml
[MOa84]
@end ifnothtml

@end table


MCORR generates a random correlation matrix
(Pearson's correlation).
Two methods are used:

@enumerate
@item
When a random correlation matrix having given eigenvalues is
sought, the method of Marsaglia and Olkin [MOa84] is used.
In this case, the correlation matrix
@iftex
@math{R}
@end iftex
@ifhtml
@html
<I>R</I>
@end html
@end ifhtml
@ifinfo
@math{R}
@end ifinfo
is given as
@iftex
@math{R=PDP'}
@end iftex
@ifhtml
@html
<I>R</I>=<I>PDP</I>'
@end html
@end ifhtml
@ifinfo
@math{R=PDP'}
@end ifinfo
where
@iftex
@math{D}
@end iftex
@ifhtml
@html
<I>D</I>
@end html
@end ifhtml
@ifinfo
@math{D}
@end ifinfo
is a diagonal
matrix containing the eigenvalues and
@iftex
@math{P}
@end iftex
@ifhtml
@html
<I>P</I>
@end html
@end ifhtml
@ifinfo
@math{P}
@end ifinfo
is a random
orthonormal matrix. In higher dimensions, the rounding-errors
introduced in the previous matrix multiplications could lead
to a non-symmetric correlation matrix. Therefore the symmetric
correlation matrix is computed as
@iftex
@math{R=(PDP'+P'DP)/2}
@end iftex
@ifhtml
@html
<I>R</I>=(<I>PDP</I>'+<I>P</I>'<I>DP</I>)/2
@end html
@end ifhtml
@ifinfo
@math{R=(PDP'+P'DP)/2}
@end ifinfo
.

@item
A matrix
@iftex
@math{H}
@end iftex
@ifhtml
@html
<I>H</I>
@end html
@end ifhtml
@ifinfo
@math{H}
@end ifinfo
is generated where all rows are
independent random vectors of unit length uniformly on a sphere.
Then
@iftex
@math{HH'}
@end iftex
@ifhtml
@html
<I>HH</I>'
@end html
@end ifhtml
@ifinfo
@math{HH'}
@end ifinfo
is a correlation matrix (and vice versa if
@iftex
@math{HH'}
@end iftex
@ifhtml
@html
<I>HH</I>'
@end html
@end ifhtml
@ifinfo
@math{HH'}
@end ifinfo
is a correlation matrix then the rows of
@iftex
@math{H}
@end iftex
@ifhtml
@html
<I>H</I>
@end html
@end ifhtml
@ifinfo
@math{H}
@end ifinfo
are random vectors on a sphere).

@end enumerate

Notice that due to round-off errors the generated matrices might
not be positive definite in extremely rare cases
(especially when the given eigenvalues are amost 0).

There are many other possibilites (distributions) of sampling
the random rows from a sphere. The chosen methods are simple but
does not result in a uniform distriubution of the random
correlation matrices.

It only works with distribution objects of random correlation
matrices (@pxref{correlation,,Random Correlation Matrix}).


@subsubheading How To Use


Create a distibution object for random correlation matrices by a
@code{unur_distr_correlation} call
(@pxref{correlation,,Random Correlation Matrix}).

When a correlation matrix with given eigenvalues should be
generated, these eigenvalues can be set by a
@ifhtml
@ref{funct:unur_mcorr_set_eigenvalues,@command{unur_mcorr_set_eigenvalues}}
@end ifhtml
@ifnothtml
@command{unur_mcorr_set_eigenvalues}
@end ifnothtml
call.

Otherwise, a faster algorithm is used that generates
correlation matrices with random eigenstructure.

Notice that due to round-off errors,
there is a (small) chance that the resulting matrix is
not positive definite for a Cholesky decomposition algorithm,
especially when the dimension of the distribution is high.

It is possible to change the given eigenvalues using
@ifhtml
@ref{funct:unur_mcorr_chg_eigenvalues,@command{unur_mcorr_chg_eigenvalues}}
@end ifhtml
@ifnothtml
@command{unur_mcorr_chg_eigenvalues}
@end ifnothtml
and run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to
reinitialize the generator object.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_mcorr_new,unur_mcorr_new}
@item @ref{funct:unur_mcorr_set_eigenvalues,unur_mcorr_set_eigenvalues}
@item @ref{funct:unur_mcorr_chg_eigenvalues,unur_mcorr_chg_eigenvalues}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_mcorr_new}
@deftypefn Function {UNUR_PAR*} unur_mcorr_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_mcorr_new}
@deftypefn {} {UNUR_PAR*} unur_mcorr_new (const @var{UNUR_DISTR* distribution})
Get default parameters for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_mcorr_set_eigenvalues}
@deftypefn Function {int} unur_mcorr_set_eigenvalues (UNUR_PAR* @var{par}, const @var{double* eigenvalues})
Sets the (optional) eigenvalues of the correlation matrix.
If set, then the Marsaglia and Olkin algorithm will be used
to generate random correlation matrices with given eigenvalues.

Important: the given eigenvalues of the correlation matrix must be
strictly positive and sum to the dimension of the matrix.
If non-positive eigenvalues are attempted, no eigenvalues are set
and an error code is returned.
In case, that their sum is different from the dimension, an implicit
scaling to give the correct sum is performed.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_mcorr_set_eigenvalues}
@deftypefn {} {int} unur_mcorr_set_eigenvalues (UNUR_PAR* @var{par}, const @var{double* eigenvalues})
Sets the (optional) eigenvalues of the correlation matrix.
If set, then the Marsaglia and Olkin algorithm will be used
to generate random correlation matrices with given eigenvalues.

Important: the given eigenvalues of the correlation matrix must be
strictly positive and sum to the dimension of the matrix.
If non-positive eigenvalues are attempted, no eigenvalues are set
and an error code is returned.
In case, that their sum is different from the dimension, an implicit
scaling to give the correct sum is performed.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_mcorr_chg_eigenvalues}
@deftypefn Function {int} unur_mcorr_chg_eigenvalues (UNUR_GEN* @var{gen}, const @var{double* eigenvalues})
Change the eigenvalues of the correlation matrix.
One must run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator
object then.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_mcorr_chg_eigenvalues}
@deftypefn {} {int} unur_mcorr_chg_eigenvalues (UNUR_GEN* @var{gen}, const @var{double* eigenvalues})
Change the eigenvalues of the correlation matrix.
One must run
@ifhtml
@ref{funct:unur_reinit,@command{unur_reinit}}
@end ifhtml
@ifnothtml
@command{unur_reinit}
@end ifnothtml
to reinitialize the generator
object then.
@end deftypefn
@end ifnotinfo




@c
@c end of mcorr.h
@c -------------------------------------
@c -------------------------------------
@c methods.dh
@c

@page
@node Methods_for_UNID
@section   Methods for uniform univariate distributions

@menu
* UNIF:: wrapper for UNIForm random number generator
@end menu




@c
@c end of methods.dh
@c -------------------------------------
@c -------------------------------------
@c unif.h
@c

@page
@node UNIF
@subsection   UNIF  --  wrapper for UNIForm random number generator


UNIF is a simple wrapper that makes it possible to use a uniform
random number generator as a UNU.RAN generator. There are no
parameters for this method.


@subsubheading How To Use


Create a generator object with @code{NULL} as argument. The created generator
object returns raw random numbers from the underlying uniform
random number generator.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_unif_new,unur_unif_new}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_unif_new}
@deftypefn Function {UNUR_PAR*} unur_unif_new (const @var{UNUR_DISTR* dummy})
Get default parameters for generator.
UNIF does not need a distribution object. @var{dummy} is not used and
can (should) be set to @code{NULL}. It is used to keep the API consistent.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_unif_new}
@deftypefn {} {UNUR_PAR*} unur_unif_new (const @var{UNUR_DISTR* dummy})
Get default parameters for generator.
UNIF does not need a distribution object. @var{dummy} is not used and
can (should) be set to @code{NULL}. It is used to keep the API consistent.
@end deftypefn
@end ifnotinfo




@c
@c end of unif.h
@c -------------------------------------
@c -------------------------------------
@c methods.dh
@c

@page
@node Meta_Methods
@section   Meta Methods for univariate distributions

@menu
* MIXT:: MIXTure of distributions
@end menu



@subheading Example

@smallexample
@include ref_example_mixt.texi
@end smallexample

@subheading Example (Inversion)

@smallexample
@include ref_example_mixt_inv.texi
@end smallexample



@c
@c end of methods.dh
@c -------------------------------------
@c -------------------------------------
@c mixt.h
@c

@page
@node MIXT
@subsection   MIXT  --  MIXTure of distributions


MIXT allows to sample from a mixture of univariate
distributions.

Let
@iftex
@math{f_1,\ldots,f_n}
@end iftex
@ifhtml
@html
<I>f</I>_1,...,<I>f</I>_<I>n</I>
@end html
@end ifhtml
@ifinfo
@math{f_1,...,f_n}
@end ifinfo
be PDFs of various distributions
called the components and
@iftex
@math{(p_1,\ldots,p_n)}
@end iftex
@ifhtml
@html
(<I>p</I>_1,...,<I>p</I>_<I>n</I>)
@end html
@end ifhtml
@ifinfo
@math{(p_1,...,p_n)}
@end ifinfo
be a
probability vector. Then
@iftex
@math{f(x) = p_1\cdot f_1(x) + \ldots + p_n\cdot f_n(x)}
@end iftex
@ifhtml
@html
<I>f</I>(<I>x</I>) = <I>p</I>_1 * <I>f</I>_1(<I>x</I>) + ...+ <I>p</I>_<I>n</I> * <I>f</I>_<I>n</I>(<I>x</I>)
@end html
@end ifhtml
@ifinfo
@math{f(x) = p_1 * f_1(x) + ...+ p_n * f_n(x)}
@end ifinfo
is the PDF of the so called mixture of these distributions.

Method MIXT takes generator objects for the components and
a probability vector and creates a generator object for
this mixture.

The sampling part works as follows:

@enumerate
@item
Generate an index @i{J} as the realisation of a discrete
random variate with the given probability vector.
This is done by means of method DGT
(@pxref{DGT,Guide Table method}).
@item
Generate a random variate @i{X} with PDF
@iftex
@math{f_J.}
@end iftex
@ifhtml
@html
<I>f</I>_<I>J</I>.
@end html
@end ifhtml
@ifinfo
@math{f_J.}
@end ifinfo
@end enumerate

When the (interior of the) domains of the the components are
disjoint then it is possible to sample from the mixture by
inversion, provided that the following conditions are met:

@itemize @minus
@item
The generator objects must use an inversion method for each
component.
@item
The domains of the PDFs
@iftex
@math{f_i}
@end iftex
@ifhtml
@html
<I>f</I>_<I>i</I>
@end html
@end ifhtml
@ifinfo
@math{f_i}
@end ifinfo
must not overlap.
@item
The components must be ordered with respect to their domains.
@end itemize


@subsubheading How To Use


Create generator objects for the components of the mixture and
store the corresponding pointers in an array.
Store all probabilities an a double array of the same size.
Create the parameter object for the generator of the mixture
distribution by means of
@ifhtml
@ref{funct:unur_mixt_new,@command{unur_mixt_new}.}
@end ifhtml
@ifnothtml
@command{unur_mixt_new}.
@end ifnothtml
The components of the mixture can be any continuous or discrete
univariate distributions. This also includes generators for
empirical distributions and mixtures of distributions.
In particular, mixtures can also be defined recursively.

@emph{Remark:}
The components of the mixture can be continuous or discrete
distributions. The resulting mixture, however, is always a
continuous distribution and thus
@ifhtml
@ref{funct:unur_sample_cont,@command{unur_sample_cont}}
@end ifhtml
@ifnothtml
@command{unur_sample_cont}
@end ifnothtml
must be used!

The inversion method can be switched on by means of
@ifhtml
@ref{funct:unur_mixt_set_useinversion,@command{unur_mixt_set_useinversion}}
@end ifhtml
@ifnothtml
@command{unur_mixt_set_useinversion}
@end ifnothtml
call.
However, the conditions for this method must then be met.
Otherwise, initialization of the mixture object fails.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_mixt_new,unur_mixt_new}
@item @ref{funct:unur_mixt_set_useinversion,unur_mixt_set_useinversion}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_mixt_new}
@deftypefn Function {UNUR_PAR*} unur_mixt_new (int @var{n}, const @var{double* prob}, UNUR_GEN** @var{comp})
Get default parameters for the generator for a mixture of the
distributions given in the array @var{comp} (components) of length
@var{n}. The probabilities are given by @var{prob}.

The generators in @var{comp} must be objects for (continuous or
discrete) univariate distributions
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_mixt_new}
@deftypefn {} {UNUR_PAR*} unur_mixt_new (int @var{n}, const @var{double* prob}, UNUR_GEN** @var{comp})
Get default parameters for the generator for a mixture of the
distributions given in the array @var{comp} (components) of length
@var{n}. The probabilities are given by @var{prob}.

The generators in @var{comp} must be objects for (continuous or
discrete) univariate distributions
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_mixt_set_useinversion}
@deftypefn Function {int} unur_mixt_set_useinversion (UNUR_PAR* @var{parameters}, int @var{useinv})
If @var{useinv} is @code{TRUE}, then the inversion method is used for
sampling from the mixture distribution.

However, the following conditions must be satisfied:

@itemize @minus
@item
The generator objects must use an inversion method for each
component.
@item
The domains of the components must not overlap.
@item
The components must be ordered with respect to their domains.
@end itemize

If one of these conditions is violated, then initialization of the
mixture object fails.

Default is @code{FALSE}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_mixt_set_useinversion}
@deftypefn {} {int} unur_mixt_set_useinversion (UNUR_PAR* @var{parameters}, int @var{useinv})
If @var{useinv} is @code{TRUE}, then the inversion method is used for
sampling from the mixture distribution.

However, the following conditions must be satisfied:

@itemize @minus
@item
The generator objects must use an inversion method for each
component.
@item
The domains of the components must not overlap.
@item
The components must be ordered with respect to their domains.
@end itemize

If one of these conditions is violated, then initialization of the
mixture object fails.

Default is @code{FALSE}.
@end deftypefn
@end ifnotinfo




@c
@c end of mixt.h
@c -------------------------------------
@c -------------------------------------
@c urng.h
@c

@node URNG
@chapter   Using uniform random number generators

@menu
* URNG-FVOID:: Simple interface for uniform random number generators
* URNG-GSL:: Interface to GSL uniform random number generators
* URNG-GSLQRNG:: Interface to GSL generators for quasi-random points
* URNG-PRNG:: Interface to Otmar Lendl's pseudo-random number generators
* URNG-RNGSTREAM:: Interface to L'Ecuyer's RNGSTREAM random number generators
* URNG-RANDOMSHIFT:: Combine point set generator with random shifts
@end menu


UNU.RAN is designed to work with many sources of (pseudo-) random
numbers or low discrepancy numbers (so called quasi-random
numbers) for almost all tasks in discrete event simulation,
(quasi-) Monte Carlo integration or any other stochastic
methods. Hence UNU.RAN uses pointers to access uniform (pseudo-)
random number generators (URNG).

Each UNU.RAN (non-uniform random variate) generator object has a
pointer to a URNG object. Thus each UNU.RAN generator object may
have its own (independent) URNG or several generator objects can
share the same URNG.

If no URNG is provided for a parameter or generator object a default
generator is used which is the same for all generators. This URNG is
defined in @file{unuran_config.h} at compile time and can be
changed at runtime.

UNU.RAN uses a unified interface for all sources of random numbers.
Unfortunately, the API for random number generators, like the
@file{GSL} (GNU Scientific Library), Otmar Lendl's @file{prng}
(Pseudo random number generators), or a single function
implemented by the user herself, are quite different.
Hence an object of type @code{UNUR_URNG} is introduced to store
the URNG. Thus it is possible to handle different sources of
such URNGs with the unified API. It is inspired from similar to
Pierre L'Ecuyers @file{RngStreams} library:

@itemize @minus
@item seed the random number generator;
@item get a uniform random number;
@item reset the URNG;
@item skip to the begining next substream;
@item sample antithetic numbers;
@item delete the URNG object.
@end itemize

The routine to create a URNG depends on the chosen random number
generator (i.e. library). Nevertheless, there exist wrapper
functions to simplify this task.

Currently the following sources of uniform random numbers are
directly supported (i.e., there exist wrapper functions).
Of course other random number generation libraries can be used.

@enumerate

@item
@code{FVOID}

URNGs of type @code{double uniform(void *state)}.
The argument @var{state} can be simply ignored in the
implementation of @code{uniform} when a global state variable is
used.
UNU.RAN contains some build-in URNGs of this type in directory
@file{src/uniform/}.

@item
@code{PRNG}

URNGs from Otmar Lendl's @code{prng} library. It provides a very
flexible way to sample form arbitrary URNGs by means of an object
oriented programing paradigma. Similarly to the UNU.RAN library
independent generator objects can be build and used.

This library has been developed by the pLab group at the university
of Salzburg (Austria, EU) and implemented by Otmar Lendl.
It is available from
@uref{http://statmath.wu.ac.at/prng/}
or from the pLab site at
@uref{http://random.mat.sbg.ac.at/}.

This interface must be compiled into UNU.RAN using the
configure flag @code{--with-urng-prng}.

@item
@code{RNGSTREAM}

Pierre L'Ecuyer's @code{RngStream} library for multiple
independent streams of pseudo-random numbers.
A GNU-style package is available from
@uref{http://statmath.wu.ac.at/software/RngStreams/}.

This interface must be compiled into UNU.RAN using the
configure flag @code{--with-urng-rngstream}.

@item
@code{GSL}

URNG from the GNU Scientific Library (GSL).
It is available from
@uref{http://www.gnu.org/software/gsl/}.

This interface must be compiled into UNU.RAN using the
configure flag @code{--with-urng-gsl}.

@end enumerate


@subsubheading How To Use


Each UNU.RAN generator object has a pointer to a uniform
(pseudo-) random number generator (URNG). It can be set via the
@ifhtml
@ref{funct:unur_set_urng,@command{unur_set_urng}}
@end ifhtml
@ifnothtml
@command{unur_set_urng}
@end ifnothtml
call. It is also possible to read this pointer
via
@ifhtml
@ref{funct:unur_get_urng,@command{unur_get_urng}}
@end ifhtml
@ifnothtml
@command{unur_get_urng}
@end ifnothtml
or change the URNG for an existing generator
object by means of
@ifhtml
@ref{funct:unur_chg_urng,@command{unur_chg_urng}.}
@end ifhtml
@ifnothtml
@command{unur_chg_urng}.
@end ifnothtml
It is important to note that these calls only copy the pointer
to the URNG object into the generator object.

If no URNG is provided for a parameter or generator object a default
URNG is used which is the same for all generators. This URNG is
defined in @file{unuran_config.h} at compile time. A pointer to
this default URNG can be obtained via
@ifhtml
@ref{funct:unur_get_default_urng,@command{unur_get_default_urng}.}
@end ifhtml
@ifnothtml
@command{unur_get_default_urng}.
@end ifnothtml
Nevertheless, it is also possible to change this default URNG by
another one at runtime by means of the
@ifhtml
@ref{funct:unur_set_default_urng,@command{unur_set_default_urng}}
@end ifhtml
@ifnothtml
@command{unur_set_default_urng}
@end ifnothtml
call. However, this only takes effect for new parameter objects.

Some generating methods provide the possibility of correlation
induction. For this feature a second auxiliary URNG is required.
It can be set and changed by
@ifhtml
@ref{funct:unur_set_urng_aux,@command{unur_set_urng_aux}}
@end ifhtml
@ifnothtml
@command{unur_set_urng_aux}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_chg_urng_aux,@command{unur_chg_urng_aux}}
@end ifhtml
@ifnothtml
@command{unur_chg_urng_aux}
@end ifnothtml
calls, respectively. Since the auxiliary
URNG is by default the same as the main URNG, the
auxiliary URNG must be set after any
@ifhtml
@ref{funct:unur_set_urng,@command{unur_set_urng}}
@end ifhtml
@ifnothtml
@command{unur_set_urng}
@end ifnothtml
or
@ifhtml
@ref{funct:unur_chg_urng,@command{unur_chg_urng}}
@end ifhtml
@ifnothtml
@command{unur_chg_urng}
@end ifnothtml
call! Since in special cases mixing of two URNG
might cause problems, we supply a default auxiliary generator
that can be used by a
@ifhtml
@ref{funct:unur_use_urng_aux_default,@command{unur_use_urng_aux_default}}
@end ifhtml
@ifnothtml
@command{unur_use_urng_aux_default}
@end ifnothtml
call (after
the main URNG has been set). This default auxiliary generator
can be changed with analogous calls as the (main) default
uniform generator.

Uniform random number generators form different sources have
different programming interfaces. Thus UNU.RAN stores all
information about a particular uniform random number generator
in a structure of type @code{UNUR_URNG}. Before a URNG can be
used with UNU.RAN an appropriate object has to be created ba a
@ifhtml
@ref{funct:unur_urng_new,@command{unur_urng_new}}
@end ifhtml
@ifnothtml
@command{unur_urng_new}
@end ifnothtml
call.
This call takes two arguments: the pointer to the sampling
routine of the generator and a pointer to a possible argument
that stores the state of the generator. The function must be of
type @code{double (*sampleunif)(void *params)}, but functions
without any argument also work.
Additionally one can set pointers to functions for reseting or
jumping the streams generated by the URNG by the corresponding
@code{set} calls.

UNU.RAN provides a unified API to all sources of random numbers.
Notice, however, that not all functions work for all random
number generators (as the respective library has not implemented
the corresponding feature).

There are wrapper functions for some libraries of uniform random
number generators to simplify the task of creating a UNU.RAN
object for URNGs.
These functions must be compiled into UNU.RAN using the
corresponding configure flags (see description of the respective
interface below).




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_get_default_urng,unur_get_default_urng}
@item @ref{funct:unur_set_default_urng,unur_set_default_urng}
@item @ref{funct:unur_set_default_urng_aux,unur_set_default_urng_aux}
@item @ref{funct:unur_get_default_urng_aux,unur_get_default_urng_aux}
@item @ref{funct:unur_set_urng,unur_set_urng}
@item @ref{funct:unur_chg_urng,unur_chg_urng}
@item @ref{funct:unur_get_urng,unur_get_urng}
@item @ref{funct:unur_set_urng_aux,unur_set_urng_aux}
@item @ref{funct:unur_use_urng_aux_default,unur_use_urng_aux_default}
@item @ref{funct:unur_chgto_urng_aux_default,unur_chgto_urng_aux_default}
@item @ref{funct:unur_chg_urng_aux,unur_chg_urng_aux}
@item @ref{funct:unur_get_urng_aux,unur_get_urng_aux}
@item @ref{funct:unur_urng_sample,unur_urng_sample}
@item @ref{funct:unur_sample_urng,unur_sample_urng}
@item @ref{funct:unur_urng_sample_array,unur_urng_sample_array}
@item @ref{funct:unur_urng_reset,unur_urng_reset}
@item @ref{funct:unur_urng_sync,unur_urng_sync}
@item @ref{funct:unur_urng_seed,unur_urng_seed}
@item @ref{funct:unur_urng_anti,unur_urng_anti}
@item @ref{funct:unur_urng_nextsub,unur_urng_nextsub}
@item @ref{funct:unur_urng_resetsub,unur_urng_resetsub}
@item @ref{funct:unur_gen_sync,unur_gen_sync}
@item @ref{funct:unur_gen_seed,unur_gen_seed}
@item @ref{funct:unur_gen_anti,unur_gen_anti}
@item @ref{funct:unur_gen_reset,unur_gen_reset}
@item @ref{funct:unur_gen_nextsub,unur_gen_nextsub}
@item @ref{funct:unur_gen_resetsub,unur_gen_resetsub}
@item @ref{funct:unur_urng_new,unur_urng_new}
@item @ref{funct:unur_urng_free,unur_urng_free}
@item @ref{funct:unur_urng_set_sample_array,unur_urng_set_sample_array}
@item @ref{funct:unur_urng_set_sync,unur_urng_set_sync}
@item @ref{funct:unur_urng_set_seed,unur_urng_set_seed}
@item @ref{funct:unur_urng_set_anti,unur_urng_set_anti}
@item @ref{funct:unur_urng_set_reset,unur_urng_set_reset}
@item @ref{funct:unur_urng_set_nextsub,unur_urng_set_nextsub}
@item @ref{funct:unur_urng_set_resetsub,unur_urng_set_resetsub}
@item @ref{funct:unur_urng_set_delete,unur_urng_set_delete}
@end itemize
@end ifhtml


@subheading Set and get default uniform RNGs

@ifinfo
@anchor{funct:unur_get_default_urng}
@deftypefn Function {UNUR_URNG*} unur_get_default_urng (void)
Get the pointer to the default URNG. The default URNG is used by all
generators where no URNG was set explicitly by a
@ifhtml
@ref{funct:unur_set_urng,@command{unur_set_urng}}
@end ifhtml
@ifnothtml
@command{unur_set_urng}
@end ifnothtml
call.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_get_default_urng}
@deftypefn {} {UNUR_URNG*} unur_get_default_urng (void)
Get the pointer to the default URNG. The default URNG is used by all
generators where no URNG was set explicitly by a
@ifhtml
@ref{funct:unur_set_urng,@command{unur_set_urng}}
@end ifhtml
@ifnothtml
@command{unur_set_urng}
@end ifnothtml
call.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_set_default_urng}
@deftypefn Function {UNUR_URNG*} unur_set_default_urng (UNUR_URNG* @var{urng_new})
Change the default URNG that is used for new parameter objects.
It returns the pointer to the old default URNG that has been used.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_set_default_urng}
@deftypefn {} {UNUR_URNG*} unur_set_default_urng (UNUR_URNG* @var{urng_new})
Change the default URNG that is used for new parameter objects.
It returns the pointer to the old default URNG that has been used.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_set_default_urng_aux}
@anchor{funct:unur_get_default_urng_aux}
@deftypefn Function {UNUR_URNG*} unur_set_default_urng_aux (UNUR_URNG* @var{urng_new})
@deftypefnx Function {UNUR_URNG*} unur_get_default_urng_aux (void)
Analogous calls for default auxiliary generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_set_default_urng_aux}
@anchor{funct:unur_get_default_urng_aux}
@deftypefn {} {UNUR_URNG*} unur_set_default_urng_aux (UNUR_URNG* @var{urng_new})
@deftypefnx {} {UNUR_URNG*} unur_get_default_urng_aux (void)
Analogous calls for default auxiliary generator.
@end deftypefn
@end ifnotinfo

@subheading Set, change and get uniform RNGs in generator objects

@ifinfo
@anchor{funct:unur_set_urng}
@deftypefn Function {int} unur_set_urng (UNUR_PAR* @var{parameters}, UNUR_URNG* @var{urng})
Use the URNG @code{urng} for the new generator. This overrides the
default URNG. It also sets the auxiliary URNG to @code{urng}.

@emph{Important}: For multivariate distributions that use
marginal distributions this call does not work properly.
It is then better first to create the generator object (by
a
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
call) and then change the URNG by means of
@ifhtml
@ref{funct:unur_chg_urng,@command{unur_chg_urng}.}
@end ifhtml
@ifnothtml
@command{unur_chg_urng}.
@end ifnothtml
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_set_urng}
@deftypefn {} {int} unur_set_urng (UNUR_PAR* @var{parameters}, UNUR_URNG* @var{urng})
Use the URNG @code{urng} for the new generator. This overrides the
default URNG. It also sets the auxiliary URNG to @code{urng}.

@emph{Important}: For multivariate distributions that use
marginal distributions this call does not work properly.
It is then better first to create the generator object (by
a
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
call) and then change the URNG by means of
@ifhtml
@ref{funct:unur_chg_urng,@command{unur_chg_urng}.}
@end ifhtml
@ifnothtml
@command{unur_chg_urng}.
@end ifnothtml
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_chg_urng}
@deftypefn Function {UNUR_URNG*} unur_chg_urng (UNUR_GEN* @var{generator}, UNUR_URNG* @var{urng})
Change the URNG for the given generator. It returns the pointer to
the old URNG that has been used by the generator.
It also changes the auxiliary URNG to @code{urng} and thus it
overrides the last
@ifhtml
@ref{funct:unur_chg_urng_aux,@command{unur_chg_urng_aux}}
@end ifhtml
@ifnothtml
@command{unur_chg_urng_aux}
@end ifnothtml
call.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_chg_urng}
@deftypefn {} {UNUR_URNG*} unur_chg_urng (UNUR_GEN* @var{generator}, UNUR_URNG* @var{urng})
Change the URNG for the given generator. It returns the pointer to
the old URNG that has been used by the generator.
It also changes the auxiliary URNG to @code{urng} and thus it
overrides the last
@ifhtml
@ref{funct:unur_chg_urng_aux,@command{unur_chg_urng_aux}}
@end ifhtml
@ifnothtml
@command{unur_chg_urng_aux}
@end ifnothtml
call.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_get_urng}
@deftypefn Function {UNUR_URNG*} unur_get_urng (UNUR_GEN* @var{generator})
Get the pointer to the URNG that is used by the @var{generator}.
This is usefull if two generators should share the same URNG.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_get_urng}
@deftypefn {} {UNUR_URNG*} unur_get_urng (UNUR_GEN* @var{generator})
Get the pointer to the URNG that is used by the @var{generator}.
This is usefull if two generators should share the same URNG.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_set_urng_aux}
@deftypefn Function {int} unur_set_urng_aux (UNUR_PAR* @var{parameters}, UNUR_URNG* @var{urng_aux})
Use the auxiliary URNG @code{urng_aux} for the new generator.
(Default is the default URNG or the URNG from the last
@ifhtml
@ref{funct:unur_set_urng,@command{unur_set_urng}}
@end ifhtml
@ifnothtml
@command{unur_set_urng}
@end ifnothtml
call. Thus if the auxiliary generator should be
different to the main URNG,
@ifhtml
@ref{funct:unur_set_urng_aux,@command{unur_set_urng_aux}}
@end ifhtml
@ifnothtml
@command{unur_set_urng_aux}
@end ifnothtml
must be called after
@ifhtml
@ref{funct:unur_set_urng,@command{unur_set_urng}.}
@end ifhtml
@ifnothtml
@command{unur_set_urng}.
@end ifnothtml
The auxiliary URNG is used as second stream of uniform random
number for correlation induction.
It is not possible to set an auxiliary URNG for a method that does
not need one. In this case an error code is returned.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_set_urng_aux}
@deftypefn {} {int} unur_set_urng_aux (UNUR_PAR* @var{parameters}, UNUR_URNG* @var{urng_aux})
Use the auxiliary URNG @code{urng_aux} for the new generator.
(Default is the default URNG or the URNG from the last
@ifhtml
@ref{funct:unur_set_urng,@command{unur_set_urng}}
@end ifhtml
@ifnothtml
@command{unur_set_urng}
@end ifnothtml
call. Thus if the auxiliary generator should be
different to the main URNG,
@ifhtml
@ref{funct:unur_set_urng_aux,@command{unur_set_urng_aux}}
@end ifhtml
@ifnothtml
@command{unur_set_urng_aux}
@end ifnothtml
must be called after
@ifhtml
@ref{funct:unur_set_urng,@command{unur_set_urng}.}
@end ifhtml
@ifnothtml
@command{unur_set_urng}.
@end ifnothtml
The auxiliary URNG is used as second stream of uniform random
number for correlation induction.
It is not possible to set an auxiliary URNG for a method that does
not need one. In this case an error code is returned.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_use_urng_aux_default}
@deftypefn Function {int} unur_use_urng_aux_default (UNUR_PAR* @var{parameters})
Use the default auxiliary URNG.
(It must be set after
@ifhtml
@ref{funct:unur_get_urng,@command{unur_get_urng}.}
@end ifhtml
@ifnothtml
@command{unur_get_urng}.
@end ifnothtml
)
It is not possible to set an auxiliary URNG for a method that does
not use one (i.e. the call returns an error code).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_use_urng_aux_default}
@deftypefn {} {int} unur_use_urng_aux_default (UNUR_PAR* @var{parameters})
Use the default auxiliary URNG.
(It must be set after
@ifhtml
@ref{funct:unur_get_urng,@command{unur_get_urng}.}
@end ifhtml
@ifnothtml
@command{unur_get_urng}.
@end ifnothtml
)
It is not possible to set an auxiliary URNG for a method that does
not use one (i.e. the call returns an error code).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_chgto_urng_aux_default}
@deftypefn Function {int} unur_chgto_urng_aux_default (UNUR_GEN* @var{generator})
Switch to default auxiliary URNG.
(It must be set after
@ifhtml
@ref{funct:unur_get_urng,@command{unur_get_urng}.}
@end ifhtml
@ifnothtml
@command{unur_get_urng}.
@end ifnothtml
)
It is not possible to set an auxiliary URNG for a method that does
not use one (i.e. the call returns an error code).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_chgto_urng_aux_default}
@deftypefn {} {int} unur_chgto_urng_aux_default (UNUR_GEN* @var{generator})
Switch to default auxiliary URNG.
(It must be set after
@ifhtml
@ref{funct:unur_get_urng,@command{unur_get_urng}.}
@end ifhtml
@ifnothtml
@command{unur_get_urng}.
@end ifnothtml
)
It is not possible to set an auxiliary URNG for a method that does
not use one (i.e. the call returns an error code).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_chg_urng_aux}
@deftypefn Function {UNUR_URNG*} unur_chg_urng_aux (UNUR_GEN* @var{generator}, UNUR_URNG* @var{urng_aux})
Change the auxiliary URNG for the given @var{generator}. It returns
the pointer to the old auxiliary URNG that has been used by the
generator. It has to be called after each
@ifhtml
@ref{funct:unur_chg_urng,@command{unur_chg_urng}}
@end ifhtml
@ifnothtml
@command{unur_chg_urng}
@end ifnothtml
when the
auxiliary URNG should be different from the main URNG.
It is not possible to change the auxiliary URNG for a method that
does not use one (i.e. the call @code{NULL}).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_chg_urng_aux}
@deftypefn {} {UNUR_URNG*} unur_chg_urng_aux (UNUR_GEN* @var{generator}, UNUR_URNG* @var{urng_aux})
Change the auxiliary URNG for the given @var{generator}. It returns
the pointer to the old auxiliary URNG that has been used by the
generator. It has to be called after each
@ifhtml
@ref{funct:unur_chg_urng,@command{unur_chg_urng}}
@end ifhtml
@ifnothtml
@command{unur_chg_urng}
@end ifnothtml
when the
auxiliary URNG should be different from the main URNG.
It is not possible to change the auxiliary URNG for a method that
does not use one (i.e. the call @code{NULL}).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_get_urng_aux}
@deftypefn Function {UNUR_URNG*} unur_get_urng_aux (UNUR_GEN* @var{generator})
Get the pointer to the auxiliary URNG that is used by the
@var{generator}. This is usefull if two generators should share the same
URNG.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_get_urng_aux}
@deftypefn {} {UNUR_URNG*} unur_get_urng_aux (UNUR_GEN* @var{generator})
Get the pointer to the auxiliary URNG that is used by the
@var{generator}. This is usefull if two generators should share the same
URNG.
@end deftypefn
@end ifnotinfo

@subheading Handle uniform RNGs

@emph{Notice:} Some of the below function calls do not work for
every source of random numbers since not every library has
implemented these features.

@ifinfo
@anchor{funct:unur_urng_sample}
@deftypefn Function {double} unur_urng_sample (UNUR_URNG* @var{urng})
Get a uniform random number from @var{urng}.
If the @code{NULL} pointer is given, the default uniform generator is
used.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_sample}
@deftypefn {} {double} unur_urng_sample (UNUR_URNG* @var{urng})
Get a uniform random number from @var{urng}.
If the @code{NULL} pointer is given, the default uniform generator is
used.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_sample_urng}
@deftypefn Function {double} unur_sample_urng (UNUR_GEN* @var{gen})
Get a uniform random number from the underlying uniform
random number generator of generator @var{gen}.
If the @code{NULL} pointer is given, the default uniform generator is
used.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_sample_urng}
@deftypefn {} {double} unur_sample_urng (UNUR_GEN* @var{gen})
Get a uniform random number from the underlying uniform
random number generator of generator @var{gen}.
If the @code{NULL} pointer is given, the default uniform generator is
used.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_urng_sample_array}
@deftypefn Function {int} unur_urng_sample_array (UNUR_URNG* @var{urng}, double* @var{X}, int @var{dim})
Set array @var{X} of length @var{dim} with uniform random numbers
sampled from generator @var{urng}. If @var{urng} is the @code{NULL}
pointer, the default uniform generator is used.

@emph{Important:}
If @var{urng} is based on a point set generator (this is the case
for generators of low discrepance point sets as used in quasi-Monte
Carlo methods) it has a ``natural dimension'' @i{s}.
In this case either only the first @i{s} entries of @var{X} are
filled (if @i{s} < @var{dim}), or the first @var{dim} coordinates
of the generated point are filled.

The called returns the actual number of entries filled. In case of
an error @code{0} is returned.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_sample_array}
@deftypefn {} {int} unur_urng_sample_array (UNUR_URNG* @var{urng}, double* @var{X}, int @var{dim})
Set array @var{X} of length @var{dim} with uniform random numbers
sampled from generator @var{urng}. If @var{urng} is the @code{NULL}
pointer, the default uniform generator is used.

@emph{Important:}
If @var{urng} is based on a point set generator (this is the case
for generators of low discrepance point sets as used in quasi-Monte
Carlo methods) it has a ``natural dimension'' @i{s}.
In this case either only the first @i{s} entries of @var{X} are
filled (if @i{s} < @var{dim}), or the first @var{dim} coordinates
of the generated point are filled.

The called returns the actual number of entries filled. In case of
an error @code{0} is returned.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_urng_reset}
@deftypefn Function {int} unur_urng_reset (UNUR_URNG* @var{urng})
Reset @var{urng} object.
The routine tries two ways to reset the generator (in this order):

@enumerate
@item
It uses the reset function given by an
@ifhtml
@ref{funct:unur_urng_set_reset,@command{unur_urng_set_reset}}
@end ifhtml
@ifnothtml
@command{unur_urng_set_reset}
@end ifnothtml
call.

@item
It uses the seed given by the last
@ifhtml
@ref{funct:unur_urng_seed,@command{unur_urng_seed}}
@end ifhtml
@ifnothtml
@command{unur_urng_seed}
@end ifnothtml
call (which
requires a seeding function given by a
@ifhtml
@ref{funct:unur_urng_set_seed,@command{unur_urng_set_seed}}
@end ifhtml
@ifnothtml
@command{unur_urng_set_seed}
@end ifnothtml
call).
@end enumerate

If neither of the two methods work resetting of the generator is
not possible and an error code is returned.

If the @code{NULL} pointer is given, the default uniform generator is
reset.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_reset}
@deftypefn {} {int} unur_urng_reset (UNUR_URNG* @var{urng})
Reset @var{urng} object.
The routine tries two ways to reset the generator (in this order):

@enumerate
@item
It uses the reset function given by an
@ifhtml
@ref{funct:unur_urng_set_reset,@command{unur_urng_set_reset}}
@end ifhtml
@ifnothtml
@command{unur_urng_set_reset}
@end ifnothtml
call.

@item
It uses the seed given by the last
@ifhtml
@ref{funct:unur_urng_seed,@command{unur_urng_seed}}
@end ifhtml
@ifnothtml
@command{unur_urng_seed}
@end ifnothtml
call (which
requires a seeding function given by a
@ifhtml
@ref{funct:unur_urng_set_seed,@command{unur_urng_set_seed}}
@end ifhtml
@ifnothtml
@command{unur_urng_set_seed}
@end ifnothtml
call).
@end enumerate

If neither of the two methods work resetting of the generator is
not possible and an error code is returned.

If the @code{NULL} pointer is given, the default uniform generator is
reset.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_urng_sync}
@deftypefn Function {int} unur_urng_sync (UNUR_URNG* @var{urng})
Jump into defined state ("sync") of the generator. This is useful
when point generators are used where the coordinates are
sampled via
@ifhtml
@ref{funct:unur_urng_sample,@command{unur_urng_sample}.}
@end ifhtml
@ifnothtml
@command{unur_urng_sample}.
@end ifnothtml
Then this call can be used to
jump to the first coordinate of the next generated point.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_sync}
@deftypefn {} {int} unur_urng_sync (UNUR_URNG* @var{urng})
Jump into defined state ("sync") of the generator. This is useful
when point generators are used where the coordinates are
sampled via
@ifhtml
@ref{funct:unur_urng_sample,@command{unur_urng_sample}.}
@end ifhtml
@ifnothtml
@command{unur_urng_sample}.
@end ifnothtml
Then this call can be used to
jump to the first coordinate of the next generated point.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_urng_seed}
@deftypefn Function {int} unur_urng_seed (UNUR_URNG* @var{urng}, unsigned @var{long seed})
Set @var{seed} for generator @var{urng}.
It returns an error code if this is not possible for the given
URNG. If the @code{NULL} pointer is given, the default uniform generator is
seeded (if possible).

@emph{Notice}: Seeding should be done only once for a particular
generator (except for resetting it to the initial state).
Expertise is required when multiple seeds are used to get independent
streams. Thus we recommend appropriate libraries for this task,
e.g. Pierre L'Ecuyer's @file{RngStreams} package. For this library
only a package seed can be set and thus the
@ifhtml
@ref{funct:unur_urng_seed,@command{unur_urng_seed}}
@end ifhtml
@ifnothtml
@command{unur_urng_seed}
@end ifnothtml
call
will not have any effect to generators of this type. Use
@ifhtml
@ref{funct:unur_urng_reset,@command{unur_urng_reset}}
@end ifhtml
@ifnothtml
@command{unur_urng_reset}
@end ifnothtml
or
@ifhtml
@ref{funct:unur_urng_rngstream_new,@command{unur_urng_rngstream_new}}
@end ifhtml
@ifnothtml
@command{unur_urng_rngstream_new}
@end ifnothtml
instead, depending
whether one wants to reset the stream or get a new stream that is
independent from the previous ones.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_seed}
@deftypefn {} {int} unur_urng_seed (UNUR_URNG* @var{urng}, unsigned @var{long seed})
Set @var{seed} for generator @var{urng}.
It returns an error code if this is not possible for the given
URNG. If the @code{NULL} pointer is given, the default uniform generator is
seeded (if possible).

@emph{Notice}: Seeding should be done only once for a particular
generator (except for resetting it to the initial state).
Expertise is required when multiple seeds are used to get independent
streams. Thus we recommend appropriate libraries for this task,
e.g. Pierre L'Ecuyer's @file{RngStreams} package. For this library
only a package seed can be set and thus the
@ifhtml
@ref{funct:unur_urng_seed,@command{unur_urng_seed}}
@end ifhtml
@ifnothtml
@command{unur_urng_seed}
@end ifnothtml
call
will not have any effect to generators of this type. Use
@ifhtml
@ref{funct:unur_urng_reset,@command{unur_urng_reset}}
@end ifhtml
@ifnothtml
@command{unur_urng_reset}
@end ifnothtml
or
@ifhtml
@ref{funct:unur_urng_rngstream_new,@command{unur_urng_rngstream_new}}
@end ifhtml
@ifnothtml
@command{unur_urng_rngstream_new}
@end ifnothtml
instead, depending
whether one wants to reset the stream or get a new stream that is
independent from the previous ones.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_urng_anti}
@deftypefn Function {int} unur_urng_anti (UNUR_URNG* @var{urng}, int @var{anti})
Switch to antithetic random numbers in @var{urng}.
It returns an error code if this is not possible for the given
URNG.

If the @code{NULL} pointer is given, the antithetic flag of the default
uniform generator is switched (if possible).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_anti}
@deftypefn {} {int} unur_urng_anti (UNUR_URNG* @var{urng}, int @var{anti})
Switch to antithetic random numbers in @var{urng}.
It returns an error code if this is not possible for the given
URNG.

If the @code{NULL} pointer is given, the antithetic flag of the default
uniform generator is switched (if possible).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_urng_nextsub}
@deftypefn Function {int} unur_urng_nextsub (UNUR_URNG* @var{urng})
Jump to start of the next substream of @var{urng}.
It returns an error code if this is not possible for the given
URNG.

If the @code{NULL} pointer is given, the default uniform generator is set
to the start of the next substream (if possible).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_nextsub}
@deftypefn {} {int} unur_urng_nextsub (UNUR_URNG* @var{urng})
Jump to start of the next substream of @var{urng}.
It returns an error code if this is not possible for the given
URNG.

If the @code{NULL} pointer is given, the default uniform generator is set
to the start of the next substream (if possible).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_urng_resetsub}
@deftypefn Function {int} unur_urng_resetsub (UNUR_URNG* @var{urng})
Jump to start of the current substream of @var{urng}.
It returns an error code if this is not possible for the given
URNG.

If the @code{NULL} pointer is given, the default uniform generator is set
to the start of the current substream (if possible).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_resetsub}
@deftypefn {} {int} unur_urng_resetsub (UNUR_URNG* @var{urng})
Jump to start of the current substream of @var{urng}.
It returns an error code if this is not possible for the given
URNG.

If the @code{NULL} pointer is given, the default uniform generator is set
to the start of the current substream (if possible).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_gen_sync}
@anchor{funct:unur_gen_seed}
@anchor{funct:unur_gen_anti}
@anchor{funct:unur_gen_reset}
@anchor{funct:unur_gen_nextsub}
@anchor{funct:unur_gen_resetsub}
@deftypefn Function {int} unur_gen_sync (UNUR_GEN* @var{generator})
@deftypefnx Function {int} unur_gen_seed (UNUR_GEN* @var{generator}, unsigned @var{long seed})
@deftypefnx Function {int} unur_gen_anti (UNUR_GEN* @var{generator}, int @var{anti})
@deftypefnx Function {int} unur_gen_reset (UNUR_GEN* @var{generator})
@deftypefnx Function {int} unur_gen_nextsub (UNUR_GEN* @var{generator})
@deftypefnx Function {int} unur_gen_resetsub (UNUR_GEN* @var{generator})
Analogous to
@ifhtml
@ref{funct:unur_urng_sync,@command{unur_urng_sync},}
@end ifhtml
@ifnothtml
@command{unur_urng_sync},
@end ifnothtml
@ifhtml
@ref{funct:unur_urng_seed,@command{unur_urng_seed}}
@end ifhtml
@ifnothtml
@command{unur_urng_seed}
@end ifnothtml
,
@ifhtml
@ref{funct:unur_urng_anti,@command{unur_urng_anti},}
@end ifhtml
@ifnothtml
@command{unur_urng_anti},
@end ifnothtml
@ifhtml
@ref{funct:unur_urng_reset,@command{unur_urng_reset}}
@end ifhtml
@ifnothtml
@command{unur_urng_reset}
@end ifnothtml
,
@ifhtml
@ref{funct:unur_urng_nextsub,@command{unur_urng_nextsub},}
@end ifhtml
@ifnothtml
@command{unur_urng_nextsub},
@end ifnothtml
and
@ifhtml
@ref{funct:unur_urng_resetsub,@command{unur_urng_resetsub},}
@end ifhtml
@ifnothtml
@command{unur_urng_resetsub},
@end ifnothtml
but act on the URNG object used by the @var{generator} object.

@emph{Warning:} These calls should be used with care as it
influences all generator objects that share the same URNG object!
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_gen_sync}
@anchor{funct:unur_gen_seed}
@anchor{funct:unur_gen_anti}
@anchor{funct:unur_gen_reset}
@anchor{funct:unur_gen_nextsub}
@anchor{funct:unur_gen_resetsub}
@deftypefn {} {int} unur_gen_sync (UNUR_GEN* @var{generator})
@deftypefnx {} {int} unur_gen_seed (UNUR_GEN* @var{generator}, unsigned @var{long seed})
@deftypefnx {} {int} unur_gen_anti (UNUR_GEN* @var{generator}, int @var{anti})
@deftypefnx {} {int} unur_gen_reset (UNUR_GEN* @var{generator})
@deftypefnx {} {int} unur_gen_nextsub (UNUR_GEN* @var{generator})
@deftypefnx {} {int} unur_gen_resetsub (UNUR_GEN* @var{generator})
Analogous to
@ifhtml
@ref{funct:unur_urng_sync,@command{unur_urng_sync},}
@end ifhtml
@ifnothtml
@command{unur_urng_sync},
@end ifnothtml
@ifhtml
@ref{funct:unur_urng_seed,@command{unur_urng_seed}}
@end ifhtml
@ifnothtml
@command{unur_urng_seed}
@end ifnothtml
,
@ifhtml
@ref{funct:unur_urng_anti,@command{unur_urng_anti},}
@end ifhtml
@ifnothtml
@command{unur_urng_anti},
@end ifnothtml
@ifhtml
@ref{funct:unur_urng_reset,@command{unur_urng_reset}}
@end ifhtml
@ifnothtml
@command{unur_urng_reset}
@end ifnothtml
,
@ifhtml
@ref{funct:unur_urng_nextsub,@command{unur_urng_nextsub},}
@end ifhtml
@ifnothtml
@command{unur_urng_nextsub},
@end ifnothtml
and
@ifhtml
@ref{funct:unur_urng_resetsub,@command{unur_urng_resetsub},}
@end ifhtml
@ifnothtml
@command{unur_urng_resetsub},
@end ifnothtml
but act on the URNG object used by the @var{generator} object.

@emph{Warning:} These calls should be used with care as it
influences all generator objects that share the same URNG object!
@end deftypefn
@end ifnotinfo

@subheading API to create a new URNG object

@emph{Notice:} These functions are provided to built a
UNUR_URNG object for a particular external random number
generator from scratch. For some libraries that contain random
number generators (like the GSL) there are special calls,
e.g.
@ifhtml
@ref{funct:unur_urng_gsl_new,@command{unur_urng_gsl_new},}
@end ifhtml
@ifnothtml
@command{unur_urng_gsl_new},
@end ifnothtml
to get such an object. Then there is no
need to change the UNUR_URNG object as it already contains all
available features.

If you have a particular library for random number generators you
can either write wrapper function like those in
@file{src/uniform/urng_gsl.c} or write an email to the authors of
UNU.RAN to write it for you.

@ifinfo
@anchor{funct:unur_urng_new}
@deftypefn Function {UNUR_URNG*} unur_urng_new (double (* @var{sampleunif})(void* state ), void* @var{state})
Get a new URNG object.
@var{sampleunif} is a function to the uniform sampling routine,
@var{state} a pointer to its arguments which usually contains the
state variables of the generator.

Functions @var{sampleunif} with a different type for @var{p} or
without an argument at all also work. A typecast might be necessary
to avoid compiler warnings or error messages.

For functions @var{sampleunif} that does not have any argument
should use @code{NULL} for @var{state}.

@emph{Important:} @var{sampleunif} must not be the @code{NULL} pointer.

There are appropriate calls that simplifies the task of creating
URNG objects for some libraries with uniform random number
generators, see below.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_new}
@deftypefn {} {UNUR_URNG*} unur_urng_new (double (* @var{sampleunif})(void* state ), void* @var{state})
Get a new URNG object.
@var{sampleunif} is a function to the uniform sampling routine,
@var{state} a pointer to its arguments which usually contains the
state variables of the generator.

Functions @var{sampleunif} with a different type for @var{p} or
without an argument at all also work. A typecast might be necessary
to avoid compiler warnings or error messages.

For functions @var{sampleunif} that does not have any argument
should use @code{NULL} for @var{state}.

@emph{Important:} @var{sampleunif} must not be the @code{NULL} pointer.

There are appropriate calls that simplifies the task of creating
URNG objects for some libraries with uniform random number
generators, see below.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_urng_free}
@deftypefn Function {void} unur_urng_free (UNUR_URNG* @var{urng})
Destroy @var{urng} object.
It returns an error code if this is not possible.

If the @code{NULL} is given, this function does nothing.

@emph{Warning:} This call must be used with care. The @var{urng}
object must not be used by any existing generator object!
It is designed to work in conjunction with the wrapper functions
to create URNG objects for generators of a particular library.
Thus an object created by an
@ifhtml
@ref{funct:unur_urng_prng_new,@command{unur_urng_prng_new}}
@end ifhtml
@ifnothtml
@command{unur_urng_prng_new}
@end ifnothtml
call can be
simply destroyed by an
@ifhtml
@ref{funct:unur_urng_free,@command{unur_urng_free}}
@end ifhtml
@ifnothtml
@command{unur_urng_free}
@end ifnothtml
call.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_free}
@deftypefn {} {void} unur_urng_free (UNUR_URNG* @var{urng})
Destroy @var{urng} object.
It returns an error code if this is not possible.

If the @code{NULL} is given, this function does nothing.

@emph{Warning:} This call must be used with care. The @var{urng}
object must not be used by any existing generator object!
It is designed to work in conjunction with the wrapper functions
to create URNG objects for generators of a particular library.
Thus an object created by an
@ifhtml
@ref{funct:unur_urng_prng_new,@command{unur_urng_prng_new}}
@end ifhtml
@ifnothtml
@command{unur_urng_prng_new}
@end ifnothtml
call can be
simply destroyed by an
@ifhtml
@ref{funct:unur_urng_free,@command{unur_urng_free}}
@end ifhtml
@ifnothtml
@command{unur_urng_free}
@end ifnothtml
call.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_urng_set_sample_array}
@deftypefn Function {int} unur_urng_set_sample_array (UNUR_URNG* @var{urng}, unsigned int(* @var{samplearray})(void* state, double* @var{X}, int @var{dim} ))
Set function to fill array @var{X} of length @var{dim} with random
numbers generated by generator @var{urng} (if available).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_set_sample_array}
@deftypefn {} {int} unur_urng_set_sample_array (UNUR_URNG* @var{urng}, unsigned int(* @var{samplearray})(void* state, double* @var{X}, int @var{dim} ))
Set function to fill array @var{X} of length @var{dim} with random
numbers generated by generator @var{urng} (if available).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_urng_set_sync}
@deftypefn Function {int} unur_urng_set_sync (UNUR_URNG* @var{urng}, void (* @var{sync})(void* state ))
Set function for jumping into a defined state (``sync'').
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_set_sync}
@deftypefn {} {int} unur_urng_set_sync (UNUR_URNG* @var{urng}, void (* @var{sync})(void* state ))
Set function for jumping into a defined state (``sync'').
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_urng_set_seed}
@deftypefn Function {int} unur_urng_set_seed (UNUR_URNG* @var{urng}, void (* @var{setseed})(void* state, unsigned @var{long seed} ))
Set function to seed generator @var{urng} (if available).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_set_seed}
@deftypefn {} {int} unur_urng_set_seed (UNUR_URNG* @var{urng}, void (* @var{setseed})(void* state, unsigned @var{long seed} ))
Set function to seed generator @var{urng} (if available).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_urng_set_anti}
@deftypefn Function {int} unur_urng_set_anti (UNUR_URNG* @var{urng}, void (* @var{setanti})(void* state, int @var{anti} ))
Set function to switch the antithetic flag of generator @var{urng}
(if available).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_set_anti}
@deftypefn {} {int} unur_urng_set_anti (UNUR_URNG* @var{urng}, void (* @var{setanti})(void* state, int @var{anti} ))
Set function to switch the antithetic flag of generator @var{urng}
(if available).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_urng_set_reset}
@deftypefn Function {int} unur_urng_set_reset (UNUR_URNG* @var{urng}, void (* @var{reset})(void* state ))
Set function for reseting the uniform random number generator
@var{urng} (if available).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_set_reset}
@deftypefn {} {int} unur_urng_set_reset (UNUR_URNG* @var{urng}, void (* @var{reset})(void* state ))
Set function for reseting the uniform random number generator
@var{urng} (if available).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_urng_set_nextsub}
@deftypefn Function {int} unur_urng_set_nextsub (UNUR_URNG* @var{urng}, void (* @var{nextsub})(void* state ))
Set function that allows jumping to start of the next substream of
@var{urng} (if available).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_set_nextsub}
@deftypefn {} {int} unur_urng_set_nextsub (UNUR_URNG* @var{urng}, void (* @var{nextsub})(void* state ))
Set function that allows jumping to start of the next substream of
@var{urng} (if available).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_urng_set_resetsub}
@deftypefn Function {int} unur_urng_set_resetsub (UNUR_URNG* @var{urng}, void (* @var{resetsub})(void* state ))
Set function that allows jumping to start of the current substream
of @var{urng} (if available).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_set_resetsub}
@deftypefn {} {int} unur_urng_set_resetsub (UNUR_URNG* @var{urng}, void (* @var{resetsub})(void* state ))
Set function that allows jumping to start of the current substream
of @var{urng} (if available).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_urng_set_delete}
@deftypefn Function {int} unur_urng_set_delete (UNUR_URNG* @var{urng}, void (* @var{fpdelete})(void* state ))
Set function for destroying @var{urng} (if available).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_set_delete}
@deftypefn {} {int} unur_urng_set_delete (UNUR_URNG* @var{urng}, void (* @var{fpdelete})(void* state ))
Set function for destroying @var{urng} (if available).
@end deftypefn
@end ifnotinfo




@c
@c end of urng.h
@c -------------------------------------
@c -------------------------------------
@c urng_fvoid.h
@c

@node URNG-FVOID
@section   Simple interface for uniform random number generators


Simple interface for URNGs of type @code{double uniform(void *state)}.

UNU.RAN contains some build-in URNGs of this type:
@table @code
@item unur_urng_MRG31k3p
Combined multiple recursive generator by Pierre L'Ecuyer and
Renee Touzin.
@item unur_urng_fish
Linear congruential generator by Fishman and Moore.
@item unur_urng_mstd
Linear congruential generator "Minimal Standard" by Park and Miller.
@end table

Notice, however, that these generators are provided as a
fallback for the case that no state-of-the-art uniform random
number generators (e.g. @pxref{URNG-RNGSTREAM,Pierre L'Ecuyer's
@file{Rngstream} library, Pierre L'Ecuyer's @file{Rngstream}
library}) are used.


@subsubheading How To Use


Create an URNG object using
@ifhtml
@ref{funct:unur_urng_fvoid_new,@command{unur_urng_fvoid_new}.}
@end ifhtml
@ifnothtml
@command{unur_urng_fvoid_new}.
@end ifnothtml
By this call a pointer to the sampling routine and (optional) a
pointer to a reset routine are copied into the URNG object.
Other functions, like seeding the URNG, switching to antithetic
random number, or jumping to next substream, can be added to the
URNG object by the respective calls, e.g. by
@ifhtml
@ref{funct:unur_urng_set_seed,@command{unur_urng_set_seed}.}
@end ifhtml
@ifnothtml
@command{unur_urng_set_seed}.
@end ifnothtml
The following routines are supported for URNG objects of this
type:

@itemize @minus
@item
@ifhtml
@ref{funct:unur_urng_sample,@command{unur_urng_sample}}
@end ifhtml
@ifnothtml
@command{unur_urng_sample}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_sample_array,@command{unur_urng_sample_array}}
@end ifhtml
@ifnothtml
@command{unur_urng_sample_array}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_seed,@command{unur_urng_seed}}
@end ifhtml
@ifnothtml
@command{unur_urng_seed}
@end ifnothtml
[optional]
@item
@ifhtml
@ref{funct:unur_urng_reset,@command{unur_urng_reset}}
@end ifhtml
@ifnothtml
@command{unur_urng_reset}
@end ifnothtml
[optional]
@item
@ifhtml
@ref{funct:unur_urng_free,@command{unur_urng_free}}
@end ifhtml
@ifnothtml
@command{unur_urng_free}
@end ifnothtml
@end itemize




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_urng_fvoid_new,unur_urng_fvoid_new}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_urng_fvoid_new}
@deftypefn Function {UNUR_URNG*} unur_urng_fvoid_new (double (* @var{urand})(void* state ), void (* @var{reset})(void* state ))
Make a URNG object for a generator that consists of a single
function call @var{urand}.

If there is no @var{reset} function use @code{NULL} for the second argument.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_fvoid_new}
@deftypefn {} {UNUR_URNG*} unur_urng_fvoid_new (double (* @var{urand})(void* state ), void (* @var{reset})(void* state ))
Make a URNG object for a generator that consists of a single
function call @var{urand}.

If there is no @var{reset} function use @code{NULL} for the second argument.
@end deftypefn
@end ifnotinfo




@c
@c end of urng_fvoid.h
@c -------------------------------------
@c -------------------------------------
@c urng_gsl.h
@c

@node URNG-GSL
@section   Interface to GSL uniform random number generators


Interface to the uniform random number generators from the
GNU Scientific Library (GSL). Documentation and source code
of this library is available from
@uref{http://www.gnu.org/software/gsl/}.

The interface to the GSL must be compiled into UNU.RAN using the
configure flag @code{--with-urng-gsl}.
Notice that the GSL has to be installed before running
@code{./configure}.


@subsubheading How To Use


When using this interface @file{unuran_urng_gsl.h} must be included
in the corresponding C file, i.e., one must add the line

@example
#include <unuran_urng_gsl.h>
@end example

@noindent
Moreover, one must not forget to link the executable against
@file{libgsl}.

The following routines are supported for URNG objects of
type GSL:

@itemize @minus
@item
@ifhtml
@ref{funct:unur_urng_sample,@command{unur_urng_sample}}
@end ifhtml
@ifnothtml
@command{unur_urng_sample}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_sample_array,@command{unur_urng_sample_array}}
@end ifhtml
@ifnothtml
@command{unur_urng_sample_array}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_seed,@command{unur_urng_seed}}
@end ifhtml
@ifnothtml
@command{unur_urng_seed}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_reset,@command{unur_urng_reset}}
@end ifhtml
@ifnothtml
@command{unur_urng_reset}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_free,@command{unur_urng_free}}
@end ifhtml
@ifnothtml
@command{unur_urng_free}
@end ifnothtml
@end itemize

@smallexample
@include ref_example_gsl.texi
@end smallexample




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_urng_gsl_new,unur_urng_gsl_new}
@item @ref{funct:unur_urng_gslptr_new,unur_urng_gslptr_new}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_urng_gsl_new}
@deftypefn Function {UNUR_URNG*} unur_urng_gsl_new (const @var{gsl_rng_type* urngtype})
Make object for URNGs from the @file{GSL} (GNU Scientific Library).
@var{urngtype} is the type of the chosen generator as described in the
GSL manual (see Section Random Number Generation). This library is
available from @uref{http://www.gnu.org/software/gsl/}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_gsl_new}
@deftypefn {} {UNUR_URNG*} unur_urng_gsl_new (const @var{gsl_rng_type* urngtype})
Make object for URNGs from the @file{GSL} (GNU Scientific Library).
@var{urngtype} is the type of the chosen generator as described in the
GSL manual (see Section Random Number Generation). This library is
available from @uref{http://www.gnu.org/software/gsl/}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_urng_gslptr_new}
@deftypefn Function {UNUR_URNG*} unur_urng_gslptr_new (gsl_rng* @var{urng})
Similar to
@ifhtml
@ref{funct:unur_urng_gsl_new,@command{unur_urng_gsl_new}}
@end ifhtml
@ifnothtml
@command{unur_urng_gsl_new}
@end ifnothtml
but it uses a pointer to a
generator object as returned by @code{gsl_rng_alloc(rng_type)};
see @file{GSL} manual for details.

@emph{Notice}: There is a subtle but important difference between
these two calls. When a generator object is created by a
@ifhtml
@ref{funct:unur_urng_gsl_new,@command{unur_urng_gsl_new}}
@end ifhtml
@ifnothtml
@command{unur_urng_gsl_new}
@end ifnothtml
call, then resetting of the generator works.
When a generator object is created by a
@ifhtml
@ref{funct:unur_urng_gslptr_new,@command{unur_urng_gslptr_new}}
@end ifhtml
@ifnothtml
@command{unur_urng_gslptr_new}
@end ifnothtml
call, then resetting only works after a
@code{unur_urng_seed(urng,myseed)} call.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_gslptr_new}
@deftypefn {} {UNUR_URNG*} unur_urng_gslptr_new (gsl_rng* @var{urng})
Similar to
@ifhtml
@ref{funct:unur_urng_gsl_new,@command{unur_urng_gsl_new}}
@end ifhtml
@ifnothtml
@command{unur_urng_gsl_new}
@end ifnothtml
but it uses a pointer to a
generator object as returned by @code{gsl_rng_alloc(rng_type)};
see @file{GSL} manual for details.

@emph{Notice}: There is a subtle but important difference between
these two calls. When a generator object is created by a
@ifhtml
@ref{funct:unur_urng_gsl_new,@command{unur_urng_gsl_new}}
@end ifhtml
@ifnothtml
@command{unur_urng_gsl_new}
@end ifnothtml
call, then resetting of the generator works.
When a generator object is created by a
@ifhtml
@ref{funct:unur_urng_gslptr_new,@command{unur_urng_gslptr_new}}
@end ifhtml
@ifnothtml
@command{unur_urng_gslptr_new}
@end ifnothtml
call, then resetting only works after a
@code{unur_urng_seed(urng,myseed)} call.
@end deftypefn
@end ifnotinfo




@c
@c end of urng_gsl.h
@c -------------------------------------
@c -------------------------------------
@c urng_gslqrng.h
@c

@node URNG-GSLQRNG
@section   Interface to GSL generators for quasi-random points


Interface to the generators for quasi-random points (also called
low discrepancy point sets) from the GNU Scientific Library (GSL).
Documentation and source code of this library is available from
@uref{http://www.gnu.org/software/gsl/}.

The interface to the GSL must be compiled into UNU.RAN using the
configure flag @code{--with-urng-gsl}.
Notice that the GSL has to be installed before running
@code{./configure}.


@subsubheading How To Use


When using this interface @file{unuran_urng_gsl.h} must be included
in the corresponding C file, i.e., one must add the line

@example
#include <unuran_urng_gsl.h>
@end example

@noindent
Moreover, one must not forget to link the executable against
@file{libgsl}.

The following routines are supported for URNG objects of this
type:

@itemize @minus
@item
@ifhtml
@ref{funct:unur_urng_sample,@command{unur_urng_sample}}
@end ifhtml
@ifnothtml
@command{unur_urng_sample}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_sample_array,@command{unur_urng_sample_array}}
@end ifhtml
@ifnothtml
@command{unur_urng_sample_array}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_reset,@command{unur_urng_reset}}
@end ifhtml
@ifnothtml
@command{unur_urng_reset}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_sync,@command{unur_urng_sync}}
@end ifhtml
@ifnothtml
@command{unur_urng_sync}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_free,@command{unur_urng_free}}
@end ifhtml
@ifnothtml
@command{unur_urng_free}
@end ifnothtml
@end itemize
@ifhtml
@ref{funct:unur_urng_sync,@command{unur_urng_sync}}
@end ifhtml
@ifnothtml
@command{unur_urng_sync}
@end ifnothtml
is used to jump to the first coordinate of
the next point generated by the generator.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_urng_gslqrng_new,unur_urng_gslqrng_new}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_urng_gslqrng_new}
@deftypefn Function {UNUR_URNG*} unur_urng_gslqrng_new (const @var{gsl_qrng_type* qrngtype}, unsigned @var{int dim})
Make object for quasi-random point generators for dimension
@var{dim} from the @file{GSL} (GNU Scientific Library).
@var{qrngtype} is the type of the chosen generator as described in
the GSL manual (see section Quasi-Random Sequences).
This library is available from @uref{http://www.gnu.org/software/gsl/}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_gslqrng_new}
@deftypefn {} {UNUR_URNG*} unur_urng_gslqrng_new (const @var{gsl_qrng_type* qrngtype}, unsigned @var{int dim})
Make object for quasi-random point generators for dimension
@var{dim} from the @file{GSL} (GNU Scientific Library).
@var{qrngtype} is the type of the chosen generator as described in
the GSL manual (see section Quasi-Random Sequences).
This library is available from @uref{http://www.gnu.org/software/gsl/}.
@end deftypefn
@end ifnotinfo




@c
@c end of urng_gslqrng.h
@c -------------------------------------
@c -------------------------------------
@c urng_prng.h
@c

@node URNG-PRNG
@section   Interface to Otmar Lendl's pseudo-random number generators


URNGs from Otmar Lendl's @code{prng} library. It provides a very
flexible way to sample form arbitrary URNGs by means of an object
oriented programing paradigma. Similarly to the UNU.RAN library
independent generator objects can be build and used.

This library has been developed by the pLab group at the university
of Salzburg (Austria, EU) and implemented by Otmar Lendl.
It is available from
@uref{http://statmath.wu.ac.at/prng/}
or from the pLab site at
@uref{http://random.mat.sbg.ac.at/}.

The interface to the PRNG library must be compiled into UNU.RAN using the
configure flag @code{--with-urng-prng}.
Notice that the PRNG library has to be installed before running
@code{./configure}.


@subsubheading How To Use


When using this interface @file{unuran_urng_prng.h} must be included
in the corresponding C file, i.e., one must add the line

@example
#include <unuran_urng_prng.h>
@end example

@noindent
Moreover, one must not forget to link the executable against
@file{libprng}.

The following routines are supported for URNG objects of
type PRNG:

@itemize @minus
@item
@ifhtml
@ref{funct:unur_urng_sample,@command{unur_urng_sample}}
@end ifhtml
@ifnothtml
@command{unur_urng_sample}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_sample_array,@command{unur_urng_sample_array}}
@end ifhtml
@ifnothtml
@command{unur_urng_sample_array}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_seed,@command{unur_urng_seed}}
@end ifhtml
@ifnothtml
@command{unur_urng_seed}
@end ifnothtml
(availability depends on chosen PRNG generator!)
@item
@ifhtml
@ref{funct:unur_urng_reset,@command{unur_urng_reset}}
@end ifhtml
@ifnothtml
@command{unur_urng_reset}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_free,@command{unur_urng_free}}
@end ifhtml
@ifnothtml
@command{unur_urng_free}
@end ifnothtml
@end itemize




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_urng_prng_new,unur_urng_prng_new}
@item @ref{funct:unur_urng_prngptr_new,unur_urng_prngptr_new}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_urng_prng_new}
@deftypefn Function {UNUR_URNG*} unur_urng_prng_new (const @var{char* prngstr})
Make object for URNGs from Otmar Lendl's @file{prng} package.
@var{prngstr} is a string that contains the necessary information
to create a uniform random number generator. For the format of this
string see the @file{prng} user manual.

The @file{prng} library provides a very flexible way to sample form
arbitrary URNGs by means of an object oriented programing
paradigma. Similarly to the UNU.RAN library independent generator
objects can be build and used. The library has been developed
and implemented by Otmar Lendl as member of the pLab group at the
university of Salzburg (Austria, EU).

It is available via anonymous ftp from
@uref{http://statmath.wu.ac.at/prng/}
or from the pLab site at
@uref{http://random.mat.sbg.ac.at/}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_prng_new}
@deftypefn {} {UNUR_URNG*} unur_urng_prng_new (const @var{char* prngstr})
Make object for URNGs from Otmar Lendl's @file{prng} package.
@var{prngstr} is a string that contains the necessary information
to create a uniform random number generator. For the format of this
string see the @file{prng} user manual.

The @file{prng} library provides a very flexible way to sample form
arbitrary URNGs by means of an object oriented programing
paradigma. Similarly to the UNU.RAN library independent generator
objects can be build and used. The library has been developed
and implemented by Otmar Lendl as member of the pLab group at the
university of Salzburg (Austria, EU).

It is available via anonymous ftp from
@uref{http://statmath.wu.ac.at/prng/}
or from the pLab site at
@uref{http://random.mat.sbg.ac.at/}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_urng_prngptr_new}
@deftypefn Function {UNUR_URNG*} unur_urng_prngptr_new (struct @var{prng* urng})
Similar to
@ifhtml
@ref{funct:unur_urng_prng_new,@command{unur_urng_prng_new}}
@end ifhtml
@ifnothtml
@command{unur_urng_prng_new}
@end ifnothtml
but it uses a pointer to a
generator object as returned by @code{prng_new(prngstr)};
see @file{prng} manual for details.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_prngptr_new}
@deftypefn {} {UNUR_URNG*} unur_urng_prngptr_new (struct @var{prng* urng})
Similar to
@ifhtml
@ref{funct:unur_urng_prng_new,@command{unur_urng_prng_new}}
@end ifhtml
@ifnothtml
@command{unur_urng_prng_new}
@end ifnothtml
but it uses a pointer to a
generator object as returned by @code{prng_new(prngstr)};
see @file{prng} manual for details.
@end deftypefn
@end ifnotinfo




@c
@c end of urng_prng.h
@c -------------------------------------
@c -------------------------------------
@c urng_rngstreams.h
@c

@node URNG-RNGSTREAM
@section   Interface to L'Ecuyer's RNGSTREAM random number generators


URNGs from Pierre L'Ecuyer's @file{RngStream} library for multiple
independent streams of pseudo-random numbers.
This library provides multiple independent streams of
pseudo-random numbers which itselves can be splitted into many
substreams. It is available from
@uref{http://www.iro.umontreal.ca/~lecuyer/myftp/streams00/c/}.
A GNU-style package is available from
@uref{http://statmath.wu.ac.at/software/RngStreams/}.

The interface to the RngStream library must be compiled into UNU.RAN using the
configure flag @code{--with-urng-rngstream}.
Notice that the RngStream library has to be installed before running
@code{./configure}.


@subsubheading How To Use


When using this interface @file{unuran_urng_rngstream.h} must be included
in the corresponding C file, i.e., one must add the line

@example
#include <unuran_urng_rngstream.h>
@end example

@noindent
Moreover, one must not forget to link the executable against the
@file{RngStream} library (i.e., when using the GNU-style package
in UNIX like environments one has to add @code{-lrngstreams}
when linking an executable).

Notice that the @file{rngstream} library uses a package seed,
that means one should seed the uniform random number generator
only once in an application using the routine
@uref{http://statmath.wu.ac.at/software/RngStreams/doc/rngstreams.html#index-RngStream_005fSetPackageSeed-2,,@code{RngStream_SetPackageSeed}}:

@example
unsigned long seed[] = @{111u, 222u, 333u, 444u, 555u, 666u@};
RngStream_SetPackageSeed(seed);
@end example

@noindent
The following routines are supported for URNG objects of this
type:

@itemize @minus
@item
@ifhtml
@ref{funct:unur_urng_sample,@command{unur_urng_sample}}
@end ifhtml
@ifnothtml
@command{unur_urng_sample}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_sample_array,@command{unur_urng_sample_array}}
@end ifhtml
@ifnothtml
@command{unur_urng_sample_array}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_reset,@command{unur_urng_reset}}
@end ifhtml
@ifnothtml
@command{unur_urng_reset}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_nextsub,@command{unur_urng_nextsub}}
@end ifhtml
@ifnothtml
@command{unur_urng_nextsub}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_resetsub,@command{unur_urng_resetsub}}
@end ifhtml
@ifnothtml
@command{unur_urng_resetsub}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_anti,@command{unur_urng_anti}}
@end ifhtml
@ifnothtml
@command{unur_urng_anti}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_free,@command{unur_urng_free}}
@end ifhtml
@ifnothtml
@command{unur_urng_free}
@end ifnothtml
@end itemize




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_urng_rngstream_new,unur_urng_rngstream_new}
@item @ref{funct:unur_urng_rngstreamptr_new,unur_urng_rngstreamptr_new}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_urng_rngstream_new}
@deftypefn Function {UNUR_URNG*} unur_urng_rngstream_new (const @var{char* urngstr})
Make object for URNGs from Pierre L'Ecuyer's @file{RngStream}
library. @var{urngstr} is an arbitrary string to label a stream. It
need not be unique.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_rngstream_new}
@deftypefn {} {UNUR_URNG*} unur_urng_rngstream_new (const @var{char* urngstr})
Make object for URNGs from Pierre L'Ecuyer's @file{RngStream}
library. @var{urngstr} is an arbitrary string to label a stream. It
need not be unique.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_urng_rngstreamptr_new}
@deftypefn Function {UNUR_URNG*} unur_urng_rngstreamptr_new (RngStream @var{rngstream})
Similar to
@ifhtml
@ref{funct:unur_urng_rngstream_new,@command{unur_urng_rngstream_new}}
@end ifhtml
@ifnothtml
@command{unur_urng_rngstream_new}
@end ifnothtml
but it uses a pointer to a
generator object as returned by @code{RngStream_CreateStream()}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_rngstreamptr_new}
@deftypefn {} {UNUR_URNG*} unur_urng_rngstreamptr_new (RngStream @var{rngstream})
Similar to
@ifhtml
@ref{funct:unur_urng_rngstream_new,@command{unur_urng_rngstream_new}}
@end ifhtml
@ifnothtml
@command{unur_urng_rngstream_new}
@end ifnothtml
but it uses a pointer to a
generator object as returned by @code{RngStream_CreateStream()}.
@end deftypefn
@end ifnotinfo




@c
@c end of urng_rngstreams.h
@c -------------------------------------
@c -------------------------------------
@c urng_randomshift.h
@c

@node URNG-RANDOMSHIFT
@section   Combine point set generator with random shifts


Generators of type RANDOMSHIFT combine a point set generator with
generators to apply random shifts as proposed in
@ifhtml
@ref{bib:CPa76,, [CPa76]}
@end ifhtml
@ifnothtml
[CPa76]
@end ifnothtml
:

@enumerate
@item
Sample and store a random vector S.
@item
Run a QMC simulation where S is added to each point of the
generated quasi-random point (mod 1).
@item
Repeat steps 1 and 2.
@end enumerate


@subsubheading How To Use


Create a URNG object for a point set generator and a URNG object
for a generator to create shift vectors at random.
The meta URNG object can then be created using
@ifhtml
@ref{funct:unur_urng_randomshift_new,@command{unur_urng_randomshift_new}.}
@end ifhtml
@ifnothtml
@command{unur_urng_randomshift_new}.
@end ifnothtml
Notice that only pointers to the two underlying URNG generator
objects are copied into the newly created meta generator. Thus
manipulating the meta URNG also changes the underlying URNGs
and vice versa.

The following routines are supported for URNG objects of
type RANDOMSHIFT:

@itemize @minus
@item
@ifhtml
@ref{funct:unur_urng_sample,@command{unur_urng_sample}}
@end ifhtml
@ifnothtml
@command{unur_urng_sample}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_sample_array,@command{unur_urng_sample_array}}
@end ifhtml
@ifnothtml
@command{unur_urng_sample_array}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_reset,@command{unur_urng_reset}}
@end ifhtml
@ifnothtml
@command{unur_urng_reset}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_sync,@command{unur_urng_sync}}
@end ifhtml
@ifnothtml
@command{unur_urng_sync}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_randomshift_nextshift,@command{unur_urng_randomshift_nextshift}}
@end ifhtml
@ifnothtml
@command{unur_urng_randomshift_nextshift}
@end ifnothtml
@item
@ifhtml
@ref{funct:unur_urng_free,@command{unur_urng_free}}
@end ifhtml
@ifnothtml
@command{unur_urng_free}
@end ifnothtml
@end itemize
@ifhtml
@ref{funct:unur_urng_sync,@command{unur_urng_sync}}
@end ifhtml
@ifnothtml
@command{unur_urng_sync}
@end ifnothtml
is used to jump to the first coordinate of
the next point generated by the generator.
@ifhtml
@ref{funct:unur_urng_randomshift_nextshift,@command{unur_urng_randomshift_nextshift}}
@end ifhtml
@ifnothtml
@command{unur_urng_randomshift_nextshift}
@end ifnothtml
allows to replace the shift
vector by another randomly chosen shift vector.

@emph{Important:}
@ifhtml
@ref{funct:unur_urng_sync,@command{unur_urng_sync}}
@end ifhtml
@ifnothtml
@command{unur_urng_sync}
@end ifnothtml
is only available if it is
if it is implemented for the underlying point set generator.

@emph{Important:}
@ifhtml
@ref{funct:unur_urng_reset,@command{unur_urng_reset}}
@end ifhtml
@ifnothtml
@command{unur_urng_reset}
@end ifnothtml
is only available if it is
available for both underlying generators.




@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_urng_randomshift_new,unur_urng_randomshift_new}
@item @ref{funct:unur_urng_randomshift_nextshift,unur_urng_randomshift_nextshift}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_urng_randomshift_new}
@deftypefn Function {UNUR_URNG*} unur_urng_randomshift_new (UNUR_URNG* @var{qrng}, UNUR_URNG* @var{srng}, int @var{dim})
Make object for URNG with randomly shifted point sets.
@var{qrng} is a generated that generates point sets of dimension @var{dim}.
@var{srng} is a generated that generates random numbers or vectors.

@emph{Notice:} Only pointers to the respective objects @var{qrng}
and @var{srng} are copied into the created meta generator. Thus
manipulating the meta URNG also changes the underlying URNGs
and vice versa.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_randomshift_new}
@deftypefn {} {UNUR_URNG*} unur_urng_randomshift_new (UNUR_URNG* @var{qrng}, UNUR_URNG* @var{srng}, int @var{dim})
Make object for URNG with randomly shifted point sets.
@var{qrng} is a generated that generates point sets of dimension @var{dim}.
@var{srng} is a generated that generates random numbers or vectors.

@emph{Notice:} Only pointers to the respective objects @var{qrng}
and @var{srng} are copied into the created meta generator. Thus
manipulating the meta URNG also changes the underlying URNGs
and vice versa.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_urng_randomshift_nextshift}
@deftypefn Function {int} unur_urng_randomshift_nextshift (UNUR_URNG* @var{urng})
Get the next (randomly chosen) vector for shifting the points set, and the
underlying point generator @var{qrng} is reset.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_urng_randomshift_nextshift}
@deftypefn {} {int} unur_urng_randomshift_nextshift (UNUR_URNG* @var{urng})
Get the next (randomly chosen) vector for shifting the points set, and the
underlying point generator @var{qrng} is reset.
@end deftypefn
@end ifnotinfo




@c
@c end of urng_randomshift.h
@c -------------------------------------
@c -------------------------------------
@c stddist.dh
@c

@node Stddist
@chapter   UNU.RAN Library of standard distributions

@menu
* Stddist_CONT:: UNU.RAN Library of continuous univariate distributions
* Stddist_CVEC:: UNU.RAN Library of continuous multivariate distributions
* Stddist_DISCR:: UNU.RAN Library of discrete univariate distributions
* Stddist_MATR:: UNU.RAN Library of random matrices
@end menu


Although it is not its primary target, many
distributions are already implemented in UNU.RAN.
This section presents these available distributions
and their parameters.

The syntax to get a distribuion object for distributions
@code{<dname>} is:

@deftypefn -- {UNUR_DISTR*} unur_distr_@code{<dname>} (double* @var{params}, int @var{n_params})
@var{params} is an array of doubles of size
@var{n_params} holding the parameters.
@end deftypefn

@noindent
E.g. to get an object for the gamma distribution (with shape parameter) use

@example
unur_distr_gamma( params, 1 );
@end example

@noindent
Distributions may have default parameters with need not be given
explicitely.
E.g. The gamma distribution has three parameters: the
shape, scale and location parameter. Only the (first) shape parameter
is required. The others can be omitted and are then set by default
values.

@example
/* alpha = 5; default: beta = 1, gamma = 0 */
double fpar[] = @{5.@};
unur_distr_gamma( fpar, 1 );

/* alpha = 5, beta = 3; default: gamma = 0 */
double fpar[] = @{5., 3.@};
unur_distr_gamma( fpar, 2 );

/* alpha = 5, beta = 3, gamma = -2
double fpar[] = @{5., 3., -2.@};
unur_distr_gamma( fpar, 3 );
@end example

@strong{Important:} Naturally the computational accuracy
limits the possible parameters. There shouldn't be problems
when the parameters of a distribution are in a ``reasonable'' range but
e.g. the normal distribution N(10^15,1) won't yield the desired results.
(In this case it would be better generating N(0,1) and @emph{then}
transform the results.)
@* Of course computational inaccuracy is not specific to UNU.RAN
and should always be kept in mind when working with computers.

@emph{Important:} The routines of the standard library are included
for non-uniform random variate generation and not to provide special
functions for statistical computations.

@subheading Remark

The following keywords are used in the tables:
@table @i
@item PDF
probability density function,
with variable @i{x}.

@item PMF
probability mass function,
with variable @i{k}.

@item constant
normalization constant for given PDF and PMF, resp.
They must be multiplied by @i{constant} to get the
``real'' PDF and PMF.

@item CDF
gives information whether the CDF is implemented in UNU.RAN.

@item domain
domain PDF and PMF, resp.

@item parameters  @var{n_std} (@var{n_total}): @r{list}
list of parameters for distribution, where @var{n_std} is the number
of parameters for the standard form of the distribution and
@var{n_total} the total number for the (non-standard form of the)
distribution. @var{list} is the list of parameters in the order as
they are stored in the array of parameters. Optional parameter that
can be omitted are enclosed in square brackets @code{[@dots{}]}.

A detailed list of these parameters gives then the range of valid
parameters and defaults for optional parameters that are used when
these are omitted.

@item reference
gives reference for distribution
(@pxref{Bibliography}).

@item special generators
lists available special generators for the distribution.
The first number is the variant that to be set by
@ifhtml
@ref{funct:unur_cstd_set_variant,@command{unur_cstd_set_variant}}
@end ifhtml
@ifnothtml
@command{unur_cstd_set_variant}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_dstd_set_variant,@command{unur_dstd_set_variant}}
@end ifhtml
@ifnothtml
@command{unur_dstd_set_variant}
@end ifnothtml
call, respectively.
If no variant is set the default variant @code{DEF} is used.
In the table the respective abbreviations @code{DEF} and @code{INV}
are used for @code{UNUR_STDGEN_DEFAULT} and
@code{UNUR_STDGEN_INVERSION}.
Also the references for these methods are given (@pxref{Bibliography}).

Notice that these generators might be slower than universal methods.

If @code{DEF} is ommited, the first entry is the default generator.

@end table



@c
@c end of stddist.dh
@c -------------------------------------
@c -------------------------------------
@c stddist.dh
@c

@page
@node Stddist_CONT
@section   UNU.RAN Library of continuous univariate distributions

@menu
* F:: F-distribution
* beta:: Beta distribution
* cauchy:: Cauchy distribution
* chi:: Chi distribution
* chisquare:: Chisquare distribution
* exponential:: Exponential distribution
* extremeI:: Extreme value type I (Gumbel-type) distribution
* extremeII:: Extreme value type II (Frechet-type) distribution
* gamma:: Gamma distribution
* gig:: Generalized Inverse Gaussian distribution
* gig2:: Generalized Inverse Gaussian distribution
* hyperbolic:: Hyperbolic distribution
* ig:: Inverse Gaussian distribution
* laplace:: Laplace distribution
* logistic:: Logistic distribution
* lognormal:: Log-Normal distribution
* lomax:: Lomax distribution (Pareto distribution of second kind)
* normal:: Normal distribution
* pareto:: Pareto distribution (of first kind)
* powerexponential:: Powerexponential (Subbotin) distribution
* rayleigh:: Rayleigh distribution
* slash:: Slash distribution
* student:: Student's t distribution
* triangular:: Triangular distribution
* uniform:: Uniform distribution
* weibull:: Weibull distribution
@end menu


@c
@c end of stddist.dh
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node F
@subsection   @code{F}  --  F-distribution
@anchor{funct:unur_distr_F}
@findex unur_distr_F


@table @i
@item PDF:
@iftex
@tex
$(x^{\nu_1/2-1}) / (1+\nu_1/\nu_2 x)^{(\nu_1+\nu_2)/2}$
@end tex
@end iftex
@ifnottex
(x^(nu_1/2-1)) / (1+nu_1/nu_2 x)^((nu_1+nu_2)/2)
@end ifnottex

@item constant:
@iftex
@tex
$(\nu_1/\nu_2)^{\nu_1/2} / B(\nu_1/2,\nu_2/2)$
@end tex
@end iftex
@ifnottex
(nu_1/nu_2)^(nu_1/2) / B(nu_1/2,nu_2/2)
@end ifnottex

@item domain:
@iftex
@tex
$0 < x < \infty$
@end tex
@end iftex
@ifnottex
0 < x < infinity
@end ifnottex

@iftex
@item parameters 2 (2): @r{ nu_1, nu_2}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\nu_1 $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{scale})
@item @code{[1]}
@tab@tex$\nu_2 $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{scale})
@end multitable
@end iftex
@ifnottex
@item parameters 2 (2):  nu_1, nu_2
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab nu_1 @tab > 0 @tab  @tab @i{(scale)}
@item @code{[1]} @tab nu_2 @tab > 0 @tab  @tab @i{(scale)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBc95,, [JKBc95: Ch.27; p.322]}
@end ifhtml
@ifnothtml
[JKBc95: Ch.27; p.322]
@end ifnothtml

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node beta
@subsection   @code{beta}  --  Beta distribution
@anchor{funct:unur_distr_beta}
@findex unur_distr_beta


@table @i
@item PDF:
@iftex
@tex
$(x-a)^{p-1} \,  (b-x)^{q-1}$
@end tex
@end iftex
@ifnottex
(x-a)^(p-1) * (b-x)^(q-1)
@end ifnottex

@item constant:
@iftex
@tex
$1 / (B(p,q) \,  (b-a)^{p+q-1})$
@end tex
@end iftex
@ifnottex
1 / (B(p,q) * (b-a)^(p+q-1))
@end ifnottex

@item domain:
@iftex
@tex
$a < x < b$
@end tex
@end iftex
@ifnottex
a < x < b
@end ifnottex

@iftex
@item parameters 2 (4): @r{ p, q [, a, b ]}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$p $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{scale})
@item @code{[1]}
@tab@tex$q $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{scale})
@item @code{[2]}
@tab@tex$a $@end tex
@tab@tex$ $@end tex
@tab 0
@tab (@i{location, scale})
@item @code{[3]}
@tab@tex$b $@end tex
@tab@tex$> a $@end tex
@tab 1
@tab (@i{location, scale})
@end multitable
@end iftex
@ifnottex
@item parameters 2 (4):  p, q [, a, b ]
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab p @tab > 0 @tab  @tab @i{(scale)}
@item @code{[1]} @tab q @tab > 0 @tab  @tab @i{(scale)}
@item @code{[2]} @tab a @tab  @tab 0 @tab @i{(location, scale)}
@item @code{[3]} @tab b @tab > a @tab 1 @tab @i{(location, scale)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBc95,, [JKBc95: Ch.25; p.210]}
@end ifhtml
@ifnothtml
[JKBc95: Ch.25; p.210]
@end ifnothtml

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node cauchy
@subsection   @code{cauchy}  --  Cauchy distribution
@anchor{funct:unur_distr_cauchy}
@findex unur_distr_cauchy


@table @i
@item PDF:
@iftex
@tex
$1/(1 + ((x-\theta)/\lambda)^2)$
@end tex
@end iftex
@ifnottex
1/(1 + ((x-theta)/lambda)^2)
@end ifnottex

@item constant:
@iftex
@tex
$1/(\pi \,  \lambda)$
@end tex
@end iftex
@ifnottex
1/(pi * lambda)
@end ifnottex

@item domain:
@iftex
@tex
$-\infty < x < \infty$
@end tex
@end iftex
@ifnottex
-infinity < x < infinity
@end ifnottex

@iftex
@item parameters 0 (2): @r{ [ theta [, lambda ] ]}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\theta $@end tex
@tab@tex$ $@end tex
@tab 0
@tab (@i{location})
@item @code{[1]}
@tab@tex$\lambda $@end tex
@tab@tex$> 0 $@end tex
@tab 1
@tab (@i{scale})
@end multitable
@end iftex
@ifnottex
@item parameters 0 (2):  [ theta [, lambda ] ]
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab theta @tab  @tab 0 @tab @i{(location)}
@item @code{[1]} @tab lambda @tab > 0 @tab 1 @tab @i{(scale)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBb94,, [JKBb94: Ch.16; p.299]}
@end ifhtml
@ifnothtml
[JKBb94: Ch.16; p.299]
@end ifnothtml

@item special generators:
@table @code
@item INV
Inversion method
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node chi
@subsection   @code{chi}  --  Chi distribution
@anchor{funct:unur_distr_chi}
@findex unur_distr_chi


@table @i
@item PDF:
@iftex
@tex
$x^{\nu-1} \,  \exp( -x^2/2 )$
@end tex
@end iftex
@ifnottex
x^(nu-1) * exp( -x^2/2 )
@end ifnottex

@item constant:
@iftex
@tex
$1 / (2^{(\nu/2)-1} \,  \Gamma(\nu/2))$
@end tex
@end iftex
@ifnottex
1 / (2^((nu/2)-1) * Gamma(nu/2))
@end ifnottex

@item domain:
@iftex
@tex
$0 \leq x < \infty$
@end tex
@end iftex
@ifnottex
0 <= x < infinity
@end ifnottex

@iftex
@item parameters 1 (1): @r{ nu}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\nu $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{shape})
@end multitable
@end iftex
@ifnottex
@item parameters 1 (1):  nu
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab nu @tab > 0 @tab  @tab @i{(shape)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBb94,, [JKBb94: Ch.18; p.417]}
@end ifhtml
@ifnothtml
[JKBb94: Ch.18; p.417]
@end ifnothtml

@item special generators:
@table @code
@item DEF
@iftex
Ratio of Uniforms with shift (only for
@tex $\nu \geq 1$
@end tex
)  [MJa87]
@end iftex
@ifhtml
Ratio of Uniforms with shift (only for  nu >= 1)  @ref{bib:MJa87, [MJa87]}
@end ifhtml
@ifinfo
Ratio of Uniforms with shift (only for  nu >= 1)  [MJa87]
@end ifinfo
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node chisquare
@subsection   @code{chisquare}  --  Chisquare distribution
@anchor{funct:unur_distr_chisquare}
@findex unur_distr_chisquare


@table @i
@item PDF:
@iftex
@tex
$x^{(\nu/2)-1} \,  \exp( -x/2 )$
@end tex
@end iftex
@ifnottex
x^((nu/2)-1) * exp( -x/2 )
@end ifnottex

@item constant:
@iftex
@tex
$1 / (2^{\nu/2} \,  \Gamma(\nu/2))$
@end tex
@end iftex
@ifnottex
1 / (2^(nu/2) * Gamma(nu/2))
@end ifnottex

@item domain:
@iftex
@tex
$0 \leq x < \infty$
@end tex
@end iftex
@ifnottex
0 <= x < infinity
@end ifnottex

@iftex
@item parameters 1 (1): @r{ nu}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\nu $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{shape (degrees of freedom)})
@end multitable
@end iftex
@ifnottex
@item parameters 1 (1):  nu
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab nu @tab > 0 @tab  @tab @i{(shape (degrees of freedom))}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBb94,, [JKBb94: Ch.18; p.416]}
@end ifhtml
@ifnothtml
[JKBb94: Ch.18; p.416]
@end ifnothtml

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node exponential
@subsection   @code{exponential}  --  Exponential distribution
@anchor{funct:unur_distr_exponential}
@findex unur_distr_exponential


@table @i
@item PDF:
@iftex
@tex
$\exp( -(x-\theta)/\sigma)$
@end tex
@end iftex
@ifnottex
exp( -(x-theta)/sigma)
@end ifnottex

@item constant:
@iftex
@tex
$1/\sigma$
@end tex
@end iftex
@ifnottex
1/sigma
@end ifnottex

@item domain:
@iftex
@tex
$\theta \leq x < \infty$
@end tex
@end iftex
@ifnottex
theta <= x < infinity
@end ifnottex

@iftex
@item parameters 0 (2): @r{ [ sigma [, theta ] ]}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\sigma $@end tex
@tab@tex$> 0 $@end tex
@tab 1
@tab (@i{scale})
@item @code{[1]}
@tab@tex$\theta $@end tex
@tab@tex$ $@end tex
@tab 0
@tab (@i{location})
@end multitable
@end iftex
@ifnottex
@item parameters 0 (2):  [ sigma [, theta ] ]
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab sigma @tab > 0 @tab 1 @tab @i{(scale)}
@item @code{[1]} @tab theta @tab  @tab 0 @tab @i{(location)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBb94,, [JKBb94: Ch.19; p.494]}
@end ifhtml
@ifnothtml
[JKBb94: Ch.19; p.494]
@end ifnothtml

@item special generators:
@table @code
@item INV
Inversion method
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node extremeI
@subsection   @code{extremeI}  --  Extreme value type I (Gumbel-type) distribution
@anchor{funct:unur_distr_extremeI}
@findex unur_distr_extremeI


@table @i
@item PDF:
@iftex
@tex
$\exp( -\exp( -{x-\zeta\over \theta} ) - {x-\zeta\over \theta} )$
@end tex
@end iftex
@ifnottex
exp( -exp( -(x-zeta)/theta ) - (x-zeta)/theta )
@end ifnottex

@item constant:
@iftex
@tex
$1/\theta$
@end tex
@end iftex
@ifnottex
1/theta
@end ifnottex

@item domain:
@iftex
@tex
$-\infty < x <\infty$
@end tex
@end iftex
@ifnottex
-infinity < x <infinity
@end ifnottex

@iftex
@item parameters 0 (2): @r{ [ zeta [, theta ] ]}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\zeta $@end tex
@tab@tex$ $@end tex
@tab 0
@tab (@i{location})
@item @code{[1]}
@tab@tex$\theta $@end tex
@tab@tex$> 0 $@end tex
@tab 1
@tab (@i{scale})
@end multitable
@end iftex
@ifnottex
@item parameters 0 (2):  [ zeta [, theta ] ]
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab zeta @tab  @tab 0 @tab @i{(location)}
@item @code{[1]} @tab theta @tab > 0 @tab 1 @tab @i{(scale)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBc95,, [JKBc95: Ch.22; p.2]}
@end ifhtml
@ifnothtml
[JKBc95: Ch.22; p.2]
@end ifnothtml

@item special generators:
@table @code
@item INV
Inversion method
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node extremeII
@subsection   @code{extremeII}  --  Extreme value type II (Frechet-type) distribution
@anchor{funct:unur_distr_extremeII}
@findex unur_distr_extremeII


@table @i
@item PDF:
@iftex
@tex
$\exp( -({x-\zeta\over \theta})^{-k}) \,  ({x-\zeta\over \theta})^{-k-1}$
@end tex
@end iftex
@ifnottex
exp( -((x-zeta)/theta)^(-k)) * ((x-zeta)/theta)^(-k-1)
@end ifnottex

@item constant:
@iftex
@tex
$k/\theta$
@end tex
@end iftex
@ifnottex
k/theta
@end ifnottex

@item domain:
@iftex
@tex
$\zeta < x <\infty$
@end tex
@end iftex
@ifnottex
zeta < x <infinity
@end ifnottex

@iftex
@item parameters 1 (3): @r{ k [, zeta [, theta ] ]}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$k $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{shape})
@item @code{[1]}
@tab@tex$\zeta $@end tex
@tab@tex$ $@end tex
@tab 0
@tab (@i{location})
@item @code{[2]}
@tab@tex$\theta $@end tex
@tab@tex$> 0 $@end tex
@tab 1
@tab (@i{scale})
@end multitable
@end iftex
@ifnottex
@item parameters 1 (3):  k [, zeta [, theta ] ]
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab k @tab > 0 @tab  @tab @i{(shape)}
@item @code{[1]} @tab zeta @tab  @tab 0 @tab @i{(location)}
@item @code{[2]} @tab theta @tab > 0 @tab 1 @tab @i{(scale)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBc95,, [JKBc95: Ch.22; p.2]}
@end ifhtml
@ifnothtml
[JKBc95: Ch.22; p.2]
@end ifnothtml

@item special generators:
@table @code
@item INV
Inversion method
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node gamma
@subsection   @code{gamma}  --  Gamma distribution
@anchor{funct:unur_distr_gamma}
@findex unur_distr_gamma


@table @i
@item PDF:
@iftex
@tex
$({x-\gamma\over \beta})^{\alpha-1} \,  \exp( -{x-\gamma\over \beta} )$
@end tex
@end iftex
@ifnottex
((x-gamma)/beta)^(alpha-1) * exp( -(x-gamma)/beta )
@end ifnottex

@item constant:
@iftex
@tex
$1 / (\beta \,  \Gamma(\alpha))$
@end tex
@end iftex
@ifnottex
1 / (beta * Gamma(alpha))
@end ifnottex

@item domain:
@iftex
@tex
$\gamma < x < \infty$
@end tex
@end iftex
@ifnottex
gamma < x < infinity
@end ifnottex

@iftex
@item parameters 1 (3): @r{ alpha [, beta [, gamma ] ]}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\alpha $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{shape})
@item @code{[1]}
@tab@tex$\beta $@end tex
@tab@tex$> 0 $@end tex
@tab 1
@tab (@i{scale})
@item @code{[2]}
@tab@tex$\gamma $@end tex
@tab@tex$ $@end tex
@tab 0
@tab (@i{location})
@end multitable
@end iftex
@ifnottex
@item parameters 1 (3):  alpha [, beta [, gamma ] ]
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab alpha @tab > 0 @tab  @tab @i{(shape)}
@item @code{[1]} @tab beta @tab > 0 @tab 1 @tab @i{(scale)}
@item @code{[2]} @tab gamma @tab  @tab 0 @tab @i{(location)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBb94,, [JKBb94: Ch.17; p.337]}
@end ifhtml
@ifnothtml
[JKBb94: Ch.17; p.337]
@end ifnothtml

@item special generators:
@table @code
@item DEF
@iftex
Acceptance Rejection combined with Acceptance Complement  [ADa74] [ADa82]
@end iftex
@ifhtml
Acceptance Rejection combined with Acceptance Complement  @ref{bib:ADa74, [ADa74]} @ref{bib:ADa82, [ADa82]}
@end ifhtml
@ifinfo
Acceptance Rejection combined with Acceptance Complement  [ADa74] [ADa82]
@end ifinfo
@item 2
@iftex
Rejection from \log-\logistic envelopes  [CHa77]
@end iftex
@ifhtml
Rejection from log-logistic envelopes  @ref{bib:CHa77, [CHa77]}
@end ifhtml
@ifinfo
Rejection from log-logistic envelopes  [CHa77]
@end ifinfo
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node gig
@subsection   @code{gig}  --  Generalized Inverse Gaussian distribution
@anchor{funct:unur_distr_gig}
@findex unur_distr_gig


@table @i
@item PDF:
@iftex
@tex
$x^{\theta-1} \,  \exp( -{1\over 2} \,  \omega \,  ({x\over \eta} + {\eta\over x}))$
@end tex
@end iftex
@ifnottex
x^(theta-1) * exp( -1/2 * omega * (x/eta + eta/x))
@end ifnottex

@item constant:
@iftex
@tex
not implemented!
@end tex
@end iftex
@ifnottex
not implemented!
@end ifnottex

@item CDF:
@iftex
@tex
not implemented!
@end tex
@end iftex
@ifnottex
not implemented!
@end ifnottex

@item domain:
@iftex
@tex
$0 < x <\infty$
@end tex
@end iftex
@ifnottex
0 < x <infinity
@end ifnottex

@iftex
@item parameters 2 (3): @r{ theta, omega [, eta ]}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\theta $@end tex
@tab@tex$ $@end tex
@tab
@tab (@i{shape})
@item @code{[1]}
@tab@tex$\omega $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{scale})
@item @code{[2]}
@tab@tex$\eta $@end tex
@tab@tex$> 0 $@end tex
@tab 1
@tab (@i{shape})
@end multitable
@end iftex
@ifnottex
@item parameters 2 (3):  theta, omega [, eta ]
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab theta @tab  @tab  @tab @i{(shape)}
@item @code{[1]} @tab omega @tab > 0 @tab  @tab @i{(scale)}
@item @code{[2]} @tab eta @tab > 0 @tab 1 @tab @i{(shape)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBb94,, [JKBb94: Ch.15; p.84]}
@end ifhtml
@ifnothtml
[JKBb94: Ch.15; p.84]
@end ifnothtml

@item special generators:
@table @code
@item DEF
@iftex
Ratio-of-Uniforms method  [Dag89]
@end iftex
@ifhtml
Ratio-of-Uniforms method  @ref{bib:Dag89, [Dag89]}
@end ifhtml
@ifinfo
Ratio-of-Uniforms method  [Dag89]
@end ifinfo
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node gig2
@subsection   @code{gig2}  --  Generalized Inverse Gaussian distribution
@anchor{funct:unur_distr_gig2}
@findex unur_distr_gig2


@table @i
@item PDF:
@iftex
@tex
$x^{\theta-1} \,  \exp( -{1\over 2} \,  ({\chi\over x} + \psi\, x))$
@end tex
@end iftex
@ifnottex
x^(theta-1) * exp( -1/2 * (chi/x + psi*x))
@end ifnottex

@item constant:
@iftex
@tex
not implemented!
@end tex
@end iftex
@ifnottex
not implemented!
@end ifnottex

@item CDF:
@iftex
@tex
not implemented!
@end tex
@end iftex
@ifnottex
not implemented!
@end ifnottex

@item domain:
@iftex
@tex
$0 < x <\infty$
@end tex
@end iftex
@ifnottex
0 < x <infinity
@end ifnottex

@iftex
@item parameters 3 (3): @r{ theta, psi, chi}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\theta $@end tex
@tab@tex$ $@end tex
@tab
@tab (@i{shape})
@item @code{[1]}
@tab@tex$\psi $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{shape})
@item @code{[2]}
@tab@tex$\chi $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{shape})
@end multitable
@end iftex
@ifnottex
@item parameters 3 (3):  theta, psi, chi
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab theta @tab  @tab  @tab @i{(shape)}
@item @code{[1]} @tab psi @tab > 0 @tab  @tab @i{(shape)}
@item @code{[2]} @tab chi @tab > 0 @tab  @tab @i{(shape)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBb94,, [JKBb94: Ch.15; p.84]}
@end ifhtml
@ifnothtml
[JKBb94: Ch.15; p.84]
@end ifnothtml

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node hyperbolic
@subsection   @code{hyperbolic}  --  Hyperbolic distribution
@anchor{funct:unur_distr_hyperbolic}
@findex unur_distr_hyperbolic


@table @i
@item PDF:
@iftex
@tex
$\exp( -\alpha \,  \sqrt{\delta^2 + (x - \mu)^2} + \beta\, (x-\mu) )$
@end tex
@end iftex
@ifnottex
exp( -alpha * sqrt(delta^2 + (x - mu)^2) + beta*(x-mu) )
@end ifnottex

@item constant:
@iftex
@tex
not implemented!
@end tex
@end iftex
@ifnottex
not implemented!
@end ifnottex

@item CDF:
@iftex
@tex
not implemented!
@end tex
@end iftex
@ifnottex
not implemented!
@end ifnottex

@item domain:
@iftex
@tex
$-\infty < x <\infty$
@end tex
@end iftex
@ifnottex
-infinity < x <infinity
@end ifnottex

@iftex
@item parameters 4 (4): @r{ alpha, beta, delta, mu}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\alpha $@end tex
@tab@tex$>|\beta| $@end tex
@tab
@tab (@i{shape (tail)})
@item @code{[1]}
@tab@tex$\beta $@end tex
@tab@tex$ $@end tex
@tab
@tab (@i{shape (asymmetry)})
@item @code{[2]}
@tab@tex$\delta $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{scale})
@item @code{[3]}
@tab@tex$\mu $@end tex
@tab@tex$ $@end tex
@tab
@tab (@i{location})
@end multitable
@end iftex
@ifnottex
@item parameters 4 (4):  alpha, beta, delta, mu
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab alpha @tab >|beta| @tab  @tab @i{(shape (tail))}
@item @code{[1]} @tab beta @tab  @tab  @tab @i{(shape (asymmetry))}
@item @code{[2]} @tab delta @tab > 0 @tab  @tab @i{(scale)}
@item @code{[3]} @tab mu @tab  @tab  @tab @i{(location)}
@end multitable
@end ifnottex
@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node ig
@subsection   @code{ig}  --  Inverse Gaussian distribution
@anchor{funct:unur_distr_ig}
@findex unur_distr_ig


@table @i
@item PDF:
@iftex
@tex
$\sqrt{ {\lambda\over 2\, \pi\, x^3} } \,  \exp( -{\lambda\, (x-\mu)^2\over 2\, \mu^2\, x} )$
@end tex
@end iftex
@ifnottex
sqrt( lambda/2*pi*x^3 ) * exp( -(lambda*(x-mu)^2)/2*mu^2*x )
@end ifnottex

@item constant:
@iftex
@tex
$1$
@end tex
@end iftex
@ifnottex
1
@end ifnottex

@item CDF:
@iftex
@tex
not implemented!
@end tex
@end iftex
@ifnottex
not implemented!
@end ifnottex

@item domain:
@iftex
@tex
$0 < x <\infty$
@end tex
@end iftex
@ifnottex
0 < x <infinity
@end ifnottex

@iftex
@item parameters 2 (2): @r{ mu, lambda}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\mu $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{mean})
@item @code{[1]}
@tab@tex$\lambda $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{shape})
@end multitable
@end iftex
@ifnottex
@item parameters 2 (2):  mu, lambda
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab mu @tab > 0 @tab  @tab @i{(mean)}
@item @code{[1]} @tab lambda @tab > 0 @tab  @tab @i{(shape)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBb94,, [JKBb94: Ch.15; p.259]}
@end ifhtml
@ifnothtml
[JKBb94: Ch.15; p.259]
@end ifnothtml

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node laplace
@subsection   @code{laplace}  --  Laplace distribution
@anchor{funct:unur_distr_laplace}
@findex unur_distr_laplace


@table @i
@item PDF:
@iftex
@tex
$\exp( -|x-\theta| / \phi )$
@end tex
@end iftex
@ifnottex
exp( -|x-theta| / phi )
@end ifnottex

@item constant:
@iftex
@tex
$1/(2 \,  \phi)$
@end tex
@end iftex
@ifnottex
1/(2 * phi)
@end ifnottex

@item domain:
@iftex
@tex
$-\infty < x <\infty$
@end tex
@end iftex
@ifnottex
-infinity < x <infinity
@end ifnottex

@iftex
@item parameters 0 (2): @r{ [ theta [, phi ] ]}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\theta $@end tex
@tab@tex$ $@end tex
@tab 0
@tab (@i{location})
@item @code{[1]}
@tab@tex$\phi $@end tex
@tab@tex$> 0 $@end tex
@tab 1
@tab (@i{scale})
@end multitable
@end iftex
@ifnottex
@item parameters 0 (2):  [ theta [, phi ] ]
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab theta @tab  @tab 0 @tab @i{(location)}
@item @code{[1]} @tab phi @tab > 0 @tab 1 @tab @i{(scale)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBc95,, [JKBc95: Ch.24; p.164]}
@end ifhtml
@ifnothtml
[JKBc95: Ch.24; p.164]
@end ifnothtml

@item special generators:
@table @code
@item INV
Inversion method
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node logistic
@subsection   @code{logistic}  --  Logistic distribution
@anchor{funct:unur_distr_logistic}
@findex unur_distr_logistic


@table @i
@item PDF:
@iftex
@tex
$\exp(-{x-\alpha\over \beta}) \,  (1 + \exp(-{x-\alpha\over \beta}))^{-2}$
@end tex
@end iftex
@ifnottex
exp(-(x-alpha)/beta) * (1 + exp(-(x-alpha)/beta))^(-2)
@end ifnottex

@item constant:
@iftex
@tex
$1/\beta$
@end tex
@end iftex
@ifnottex
1/beta
@end ifnottex

@item domain:
@iftex
@tex
$-\infty < x <\infty$
@end tex
@end iftex
@ifnottex
-infinity < x <infinity
@end ifnottex

@iftex
@item parameters 0 (2): @r{ [ alpha [, beta ] ]}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\alpha $@end tex
@tab@tex$ $@end tex
@tab 0
@tab (@i{location})
@item @code{[1]}
@tab@tex$\beta $@end tex
@tab@tex$> 0 $@end tex
@tab 1
@tab (@i{scale})
@end multitable
@end iftex
@ifnottex
@item parameters 0 (2):  [ alpha [, beta ] ]
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab alpha @tab  @tab 0 @tab @i{(location)}
@item @code{[1]} @tab beta @tab > 0 @tab 1 @tab @i{(scale)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBc95,, [JKBc95: Ch.23; p.115]}
@end ifhtml
@ifnothtml
[JKBc95: Ch.23; p.115]
@end ifnothtml

@item special generators:
@table @code
@item INV
Inversion method
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node lognormal
@subsection   @code{lognormal}  --  Log-Normal distribution
@anchor{funct:unur_distr_lognormal}
@findex unur_distr_lognormal


@table @i
@item PDF:
@iftex
@tex
$1/(x-\theta) \,  \exp( -(\log(x-\theta)-\zeta)^2/(2 \sigma^2) )$
@end tex
@end iftex
@ifnottex
1/(x-theta) * exp( -(log(x-theta)-zeta)^2/(2 sigma^2) )
@end ifnottex

@item constant:
@iftex
@tex
$1/(\sigma \,  \sqrt{2 \pi})$
@end tex
@end iftex
@ifnottex
1/(sigma * sqrt(2 pi))
@end ifnottex

@item domain:
@iftex
@tex
$\theta \leq x < \infty$
@end tex
@end iftex
@ifnottex
theta <= x < infinity
@end ifnottex

@iftex
@item parameters 2 (3): @r{ zeta, sigma [, theta ]}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\zeta $@end tex
@tab@tex$ $@end tex
@tab
@tab (@i{shape})
@item @code{[1]}
@tab@tex$\sigma $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{shape})
@item @code{[2]}
@tab@tex$\theta $@end tex
@tab@tex$ $@end tex
@tab 0
@tab (@i{location})
@end multitable
@end iftex
@ifnottex
@item parameters 2 (3):  zeta, sigma [, theta ]
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab zeta @tab  @tab  @tab @i{(shape)}
@item @code{[1]} @tab sigma @tab > 0 @tab  @tab @i{(shape)}
@item @code{[2]} @tab theta @tab  @tab 0 @tab @i{(location)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBb94,, [JKBb94: Ch.14; p. 208]}
@end ifhtml
@ifnothtml
[JKBb94: Ch.14; p. 208]
@end ifnothtml

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node lomax
@subsection   @code{lomax}  --  Lomax distribution (Pareto distribution of second kind)
@anchor{funct:unur_distr_lomax}
@findex unur_distr_lomax


@table @i
@item PDF:
@iftex
@tex
$(x+C)^{-(a+1)}$
@end tex
@end iftex
@ifnottex
(x+C)^(-(a+1))
@end ifnottex

@item constant:
@iftex
@tex
$a \,  C^a$
@end tex
@end iftex
@ifnottex
a * C^a
@end ifnottex

@item domain:
@iftex
@tex
$0 \leq x < \infty$
@end tex
@end iftex
@ifnottex
0 <= x < infinity
@end ifnottex

@iftex
@item parameters 1 (2): @r{ a [, C ]}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$a $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{shape})
@item @code{[1]}
@tab@tex$C $@end tex
@tab@tex$> 0 $@end tex
@tab 1
@tab (@i{scale})
@end multitable
@end iftex
@ifnottex
@item parameters 1 (2):  a [, C ]
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab a @tab > 0 @tab  @tab @i{(shape)}
@item @code{[1]} @tab C @tab > 0 @tab 1 @tab @i{(scale)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBb94,, [JKBb94: Ch.20; p.575]}
@end ifhtml
@ifnothtml
[JKBb94: Ch.20; p.575]
@end ifnothtml

@item special generators:
@table @code
@item INV
Inversion method
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node normal
@subsection   @code{normal}  --  Normal distribution
@anchor{funct:unur_distr_normal}
@findex unur_distr_normal


@table @i
@item PDF:
@iftex
@tex
$\exp( -{1\over 2} \,  ({x-\mu\over \sigma})^2 )$
@end tex
@end iftex
@ifnottex
exp( -1/2 * ((x-mu)/sigma)^2 )
@end ifnottex

@item constant:
@iftex
@tex
$1 / (\sigma \,  \sqrt{2 \pi})$
@end tex
@end iftex
@ifnottex
1 / (sigma * sqrt(2 pi))
@end ifnottex

@item domain:
@iftex
@tex
$-\infty < x < \infty$
@end tex
@end iftex
@ifnottex
-infinity < x < infinity
@end ifnottex

@iftex
@item parameters 0 (2): @r{ [ mu [, sigma ] ]}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\mu $@end tex
@tab@tex$ $@end tex
@tab 0
@tab (@i{location})
@item @code{[1]}
@tab@tex$\sigma $@end tex
@tab@tex$> 0 $@end tex
@tab 1
@tab (@i{scale})
@end multitable
@end iftex
@ifnottex
@item parameters 0 (2):  [ mu [, sigma ] ]
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab mu @tab  @tab 0 @tab @i{(location)}
@item @code{[1]} @tab sigma @tab > 0 @tab 1 @tab @i{(scale)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBb94,, [JKBb94: Ch.13; p.80]}
@end ifhtml
@ifnothtml
[JKBb94: Ch.13; p.80]
@end ifnothtml

@item special generators:
@table @code
@item DEF
@iftex
ACR method (Acceptance-Complement Ratio)  [HDa90]
@end iftex
@ifhtml
ACR method (Acceptance-Complement Ratio)  @ref{bib:HDa90, [HDa90]}
@end ifhtml
@ifinfo
ACR method (Acceptance-Complement Ratio)  [HDa90]
@end ifinfo
@item 1
@iftex
Box-Muller method  [BMa58]
@end iftex
@ifhtml
Box-Muller method  @ref{bib:BMa58, [BMa58]}
@end ifhtml
@ifinfo
Box-Muller method  [BMa58]
@end ifinfo
@item 2
@iftex
Polar method with rejection  [MGa62]
@end iftex
@ifhtml
Polar method with rejection  @ref{bib:MGa62, [MGa62]}
@end ifhtml
@ifinfo
Polar method with rejection  [MGa62]
@end ifinfo
@item 3
@iftex
Kindermann-Ramage method  [KRa76]
@end iftex
@ifhtml
Kindermann-Ramage method  @ref{bib:KRa76, [KRa76]}
@end ifhtml
@ifinfo
Kindermann-Ramage method  [KRa76]
@end ifinfo
@item INV
Inversion method (slow)
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node pareto
@subsection   @code{pareto}  --  Pareto distribution (of first kind)
@anchor{funct:unur_distr_pareto}
@findex unur_distr_pareto


@table @i
@item PDF:
@iftex
@tex
$x^{-(a+1)}$
@end tex
@end iftex
@ifnottex
x^(-(a+1))
@end ifnottex

@item constant:
@iftex
@tex
$a \,  k^a$
@end tex
@end iftex
@ifnottex
a * k^a
@end ifnottex

@item domain:
@iftex
@tex
$k < x < \infty$
@end tex
@end iftex
@ifnottex
k < x < infinity
@end ifnottex

@iftex
@item parameters 2 (2): @r{ k, a}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$k $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{shape, location})
@item @code{[1]}
@tab@tex$a $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{shape})
@end multitable
@end iftex
@ifnottex
@item parameters 2 (2):  k, a
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab k @tab > 0 @tab  @tab @i{(shape, location)}
@item @code{[1]} @tab a @tab > 0 @tab  @tab @i{(shape)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBb94,, [JKBb94: Ch.20; p.574]}
@end ifhtml
@ifnothtml
[JKBb94: Ch.20; p.574]
@end ifnothtml

@item special generators:
@table @code
@item INV
Inversion method
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node powerexponential
@subsection   @code{powerexponential}  --  Powerexponential (Subbotin) distribution
@anchor{funct:unur_distr_powerexponential}
@findex unur_distr_powerexponential


@table @i
@item PDF:
@iftex
@tex
$\exp( -|x|^\tau )$
@end tex
@end iftex
@ifnottex
exp( -|x|^tau )
@end ifnottex

@item constant:
@iftex
@tex
$1 / (2 \,  \Gamma(1+1/\tau))$
@end tex
@end iftex
@ifnottex
1 / (2 * Gamma(1+1/tau))
@end ifnottex

@item domain:
@iftex
@tex
$-\infty < x < \infty$
@end tex
@end iftex
@ifnottex
-infinity < x < infinity
@end ifnottex

@iftex
@item parameters 1 (1): @r{ tau}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\tau $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{shape})
@end multitable
@end iftex
@ifnottex
@item parameters 1 (1):  tau
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab tau @tab > 0 @tab  @tab @i{(shape)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBc95,, [JKBc95: Ch.24; p.195]}
@end ifhtml
@ifnothtml
[JKBc95: Ch.24; p.195]
@end ifnothtml

@item special generators:
@table @code
@item DEF
@iftex
Transformed density rejection (only for
@tex $\tau \geq 1$
@end tex
)  [DLa86]
@end iftex
@ifhtml
Transformed density rejection (only for  tau >= 1)  @ref{bib:DLa86, [DLa86]}
@end ifhtml
@ifinfo
Transformed density rejection (only for  tau >= 1)  [DLa86]
@end ifinfo
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node rayleigh
@subsection   @code{rayleigh}  --  Rayleigh distribution
@anchor{funct:unur_distr_rayleigh}
@findex unur_distr_rayleigh


@table @i
@item PDF:
@iftex
@tex
$x \,  \exp( -1/2 \,  ({x\over \sigma})^2 )$
@end tex
@end iftex
@ifnottex
x * exp( -1/2 * (x/sigma)^2 )
@end ifnottex

@item constant:
@iftex
@tex
$1 / \sigma^2$
@end tex
@end iftex
@ifnottex
1 / sigma^2
@end ifnottex

@item domain:
@iftex
@tex
$0 \leq x < \infty$
@end tex
@end iftex
@ifnottex
0 <= x < infinity
@end ifnottex

@iftex
@item parameters 1 (1): @r{ sigma}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\sigma $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{scale})
@end multitable
@end iftex
@ifnottex
@item parameters 1 (1):  sigma
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab sigma @tab > 0 @tab  @tab @i{(scale)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBb94,, [JKBb94: Ch.18; p.456]}
@end ifhtml
@ifnothtml
[JKBb94: Ch.18; p.456]
@end ifnothtml

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node slash
@subsection   @code{slash}  --  Slash distribution
@anchor{funct:unur_distr_slash}
@findex unur_distr_slash


@table @i
@item PDF:
@iftex
@tex
$(1 - \exp(-x^2/2)) / x^2$
@end tex
@end iftex
@ifnottex
(1 - exp(-x^2/2)) / x^2
@end ifnottex

@item constant:
@iftex
@tex
$1 / \sqrt{2 \pi}$
@end tex
@end iftex
@ifnottex
1 / sqrt(2 pi)
@end ifnottex

@item CDF:
@iftex
@tex
not implemented!
@end tex
@end iftex
@ifnottex
not implemented!
@end ifnottex

@item domain:
@iftex
@tex
$-\infty < x < \infty$
@end tex
@end iftex
@ifnottex
-infinity < x < infinity
@end ifnottex

@item reference:
@ifhtml
@ref{bib:JKBb94,, [JKBb94: Ch.12; p.63]}
@end ifhtml
@ifnothtml
[JKBb94: Ch.12; p.63]
@end ifnothtml

@item special generators:
@table @code
@item DEF
Ratio of normal and uniform random variates
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node student
@subsection   @code{student}  --  Student's t distribution
@anchor{funct:unur_distr_student}
@findex unur_distr_student


@table @i
@item PDF:
@iftex
@tex
$(1+{t^2\over \nu})^{-(\nu+1)/2}$
@end tex
@end iftex
@ifnottex
(1+t^2/nu)^(-(nu+1)/2)
@end ifnottex

@item constant:
@iftex
@tex
$1 / (\sqrt{\nu} \,  B(1/2,\nu/2))$
@end tex
@end iftex
@ifnottex
1 / (sqrt(nu) * B(1/2,nu/2))
@end ifnottex

@item CDF:
@iftex
@tex
not implemented!
@end tex
@end iftex
@ifnottex
not implemented!
@end ifnottex

@item domain:
@iftex
@tex
$-\infty < x < \infty$
@end tex
@end iftex
@ifnottex
-infinity < x < infinity
@end ifnottex

@iftex
@item parameters 1 (1): @r{ nu}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\nu $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{shape})
@end multitable
@end iftex
@ifnottex
@item parameters 1 (1):  nu
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab nu @tab > 0 @tab  @tab @i{(shape)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBc95,, [JKBc95: Ch.28; p.362]}
@end ifhtml
@ifnothtml
[JKBc95: Ch.28; p.362]
@end ifnothtml

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node triangular
@subsection   @code{triangular}  --  Triangular distribution
@anchor{funct:unur_distr_triangular}
@findex unur_distr_triangular


@table @i
@item PDF:
@iftex
@tex
$2\, x / H,          \hbox{ for } 0 \leq x \leq H \hfill\break 2\, (1-x) / (1-H),  \hbox{ for } H \leq x \leq 1$
@end tex
@end iftex
@ifnottex
2*x / H,           for  0 <= x <= H

 2*(1-x) / (1-H),   for  H <= x <= 1
@end ifnottex

@item constant:
@iftex
@tex
$1$
@end tex
@end iftex
@ifnottex
1
@end ifnottex

@item domain:
@iftex
@tex
$0 \leq x \leq 1$
@end tex
@end iftex
@ifnottex
0 <= x <= 1
@end ifnottex

@iftex
@item parameters 0 (1): @r{ [ H ]}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$H $@end tex
@tab@tex$0 \leq H \leq 1 $@end tex
@tab 1/2
@tab (@i{shape})
@end multitable
@end iftex
@ifnottex
@item parameters 0 (1):  [ H ]
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab H @tab 0 <= H <= 1 @tab 1/2 @tab @i{(shape)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBc95,, [JKBc95: Ch.26; p.297]}
@end ifhtml
@ifnothtml
[JKBc95: Ch.26; p.297]
@end ifnothtml

@item special generators:
@table @code
@item INV
Inversion method
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node uniform
@subsection   @code{uniform}  --  Uniform distribution
@anchor{funct:unur_distr_uniform}
@findex unur_distr_uniform


@table @i
@item PDF:
@iftex
@tex
$1 / (b-a)$
@end tex
@end iftex
@ifnottex
1 / (b-a)
@end ifnottex

@item constant:
@iftex
@tex
$1$
@end tex
@end iftex
@ifnottex
1
@end ifnottex

@item domain:
@iftex
@tex
$a < x < b$
@end tex
@end iftex
@ifnottex
a < x < b
@end ifnottex

@iftex
@item parameters 0 (2): @r{ [ a, b ]}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$a $@end tex
@tab@tex$ $@end tex
@tab 0
@tab (@i{location})
@item @code{[1]}
@tab@tex$b $@end tex
@tab@tex$> a $@end tex
@tab 1
@tab (@i{location})
@end multitable
@end iftex
@ifnottex
@item parameters 0 (2):  [ a, b ]
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab a @tab  @tab 0 @tab @i{(location)}
@item @code{[1]} @tab b @tab > a @tab 1 @tab @i{(location)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBc95,, [JKBc95: Ch.26; p.276]}
@end ifhtml
@ifnothtml
[JKBc95: Ch.26; p.276]
@end ifnothtml

@item special generators:
@table @code
@item INV
Inversion method
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node weibull
@subsection   @code{weibull}  --  Weibull distribution
@anchor{funct:unur_distr_weibull}
@findex unur_distr_weibull


@table @i
@item PDF:
@iftex
@tex
$({x-\zeta\over \alpha})^{c-1} \,  \exp( -({x-\zeta\over \alpha})^c )$
@end tex
@end iftex
@ifnottex
((x-zeta)/alpha)^(c-1) * exp( -((x-zeta)/alpha)^c )
@end ifnottex

@item constant:
@iftex
@tex
$c / \alpha$
@end tex
@end iftex
@ifnottex
c / alpha
@end ifnottex

@item domain:
@iftex
@tex
$\zeta < x < \infty$
@end tex
@end iftex
@ifnottex
zeta < x < infinity
@end ifnottex

@iftex
@item parameters 1 (3): @r{ c [, alpha [, zeta ] ]}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$c $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{shape})
@item @code{[1]}
@tab@tex$\alpha $@end tex
@tab@tex$> 0 $@end tex
@tab 1
@tab (@i{scale})
@item @code{[2]}
@tab@tex$\zeta $@end tex
@tab@tex$ $@end tex
@tab 0
@tab (@i{location})
@end multitable
@end iftex
@ifnottex
@item parameters 1 (3):  c [, alpha [, zeta ] ]
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab c @tab > 0 @tab  @tab @i{(shape)}
@item @code{[1]} @tab alpha @tab > 0 @tab 1 @tab @i{(scale)}
@item @code{[2]} @tab zeta @tab  @tab 0 @tab @i{(location)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKBb94,, [JKBb94: Ch.21; p.628]}
@end ifhtml
@ifnothtml
[JKBb94: Ch.21; p.628]
@end ifnothtml

@item special generators:
@table @code
@item INV
Inversion method
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c stddist.dh
@c

@page
@node Stddist_CVEC
@section   UNU.RAN Library of continuous multivariate distributions

@menu
* copula:: Copula (distribution with uniform marginals)
* multicauchy:: Multicauchy distribution
* multiexponential:: Multiexponential distribution
* multinormal:: Multinormal distribution
* multistudent:: Multistudent distribution
@end menu


@c
@c end of stddist.dh
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node copula
@subsection   @code{copula}  --  Copula (distribution with uniform marginals)
@anchor{funct:unur_distr_copula}
@findex unur_distr_copula


@table @i
@end table


@code{UNUR_DISTR *unur_distr_copula(int dim, const double *rankcorr)}
creates a distribution object for a copula with @var{dim} components.
@var{rankcorr} is an array of size @var{dim}x@var{dim} and holds the
rank correlation matrix (Spearman's correlation), where the rows of
the matrix are stored consecutively in this array. The @code{NULL} pointer
can be used instead the identity matrix.

If @var{covar} is not a valid rank correlation matrix (i.e., not positive
definite) then no distribution object is created and @code{NULL} is returned.


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node multicauchy
@subsection   @code{multicauchy}  --  Multicauchy distribution
@anchor{funct:unur_distr_multicauchy}
@findex unur_distr_multicauchy


@table @i
@item PDF:
@iftex
@tex
$f(x) = 1 / ( 1 + (x-\mu)^t . \Sigma^{-1} . (x-\mu) )^{(dim+1)/2}$
@end tex
@end iftex
@ifnottex
f(x) = 1 / ( 1 + (x-mu)^t . Sigma^(-1) . (x-mu) )^((dim+1)/2)
@end ifnottex

@item constant:
@iftex
@tex
$\Gamma((dim+1)/2) / ( \pi^{(dim+1)/2} \,  \sqrt{\det(\Sigma)} )$
@end tex
@end iftex
@ifnottex
Gamma((dim+1)/2) / ( pi^((dim+1)/2) * sqrt(det(Sigma)) )
@end ifnottex

@item domain:
@iftex
@tex
$-\infty^{dim} < x < \infty^{dim}$
@end tex
@end iftex
@ifnottex
-infinity^(dim) < x < infinity^(dim)
@end ifnottex

@iftex
@item parameters 0 (2): @r{ [ mu, Sigma ]}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\mu $@end tex
@tab@tex$ $@end tex
@tab (0,@dots{},0)
@tab (@i{location})
@item @code{[1]}
@tab@tex$\Sigma $@end tex
@tab@tex$Symm, Pos. def. $@end tex
@tab I
@tab (@i{shape})
@end multitable
@end iftex
@ifnottex
@item parameters 0 (2):  [ mu, Sigma ]
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab mu @tab  @tab (0,@dots{},0) @tab @i{(location)}
@item @code{[1]} @tab Sigma @tab Symm, Pos. def. @tab I @tab @i{(shape)}
@end multitable
@end ifnottex
@item special generators:
@table @code
@item DEF
Cholesky factor
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node multiexponential
@subsection   @code{multiexponential}  --  Multiexponential distribution
@anchor{funct:unur_distr_multiexponential}
@findex unur_distr_multiexponential


@table @i
@item PDF:
@iftex
@tex
$f(x) = Prod_{i=0}^{i=dim-1} \exp(-(dim-i) (x_{i}-x_{i-1} - (\theta_i-\theta_{i-1}) ) / \sigma_i); with x_{-1}=0 and \theta_{i-1}=0$
@end tex
@end iftex
@ifnottex
f(x) = Prod_(i=0)^(i=dim-1) exp(-(dim-i) (x_(i)-x_(i-1) - (theta_i-theta_(i-1)) ) / sigma_i); with x_(-1)=0 and theta_(i-1)=0
@end ifnottex

@item constant:
@iftex
@tex
$Prod_{i=0}^{i=dim-1} 1/\sigma_i$
@end tex
@end iftex
@ifnottex
Prod_(i=0)^(i=dim-1) 1/sigma_i
@end ifnottex

@item domain:
@iftex
@tex
$0^{dim} \leq x < \infty^{dim}$
@end tex
@end iftex
@ifnottex
0^(dim) <= x < infinity^(dim)
@end ifnottex

@iftex
@item parameters 0 (2): @r{ [ sigma, theta ]}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\sigma $@end tex
@tab@tex$ $@end tex
@tab (1,@dots{},1)
@tab (@i{shape})
@item @code{[1]}
@tab@tex$\theta $@end tex
@tab@tex$ $@end tex
@tab (0,@dots{},0)
@tab (@i{location})
@end multitable
@end iftex
@ifnottex
@item parameters 0 (2):  [ sigma, theta ]
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab sigma @tab  @tab (1,@dots{},1) @tab @i{(shape)}
@item @code{[1]} @tab theta @tab  @tab (0,@dots{},0) @tab @i{(location)}
@end multitable
@end ifnottex
@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node multinormal
@subsection   @code{multinormal}  --  Multinormal distribution
@anchor{funct:unur_distr_multinormal}
@findex unur_distr_multinormal


@table @i
@item PDF:
@iftex
@tex
$f(x) = \exp( -1/2 \,  (x-\mu)^t . \Sigma^{-1} . (x-\mu) )$
@end tex
@end iftex
@ifnottex
f(x) = exp( -1/2 * (x-mu)^t . Sigma^(-1) . (x-mu) )
@end ifnottex

@item constant:
@iftex
@tex
$1 / ( (2 \pi)^{dim/2} \,  \sqrt{\det(\Sigma)} )$
@end tex
@end iftex
@ifnottex
1 / ( (2 pi)^(dim/2) * sqrt(det(Sigma)) )
@end ifnottex

@item domain:
@iftex
@tex
$-\infty^{dim} < x < \infty^{dim}$
@end tex
@end iftex
@ifnottex
-infinity^(dim) < x < infinity^(dim)
@end ifnottex

@iftex
@item parameters 0 (2): @r{ [ mu, Sigma ]}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\mu $@end tex
@tab@tex$ $@end tex
@tab (0,@dots{},0)
@tab (@i{location})
@item @code{[1]}
@tab@tex$\Sigma $@end tex
@tab@tex$Symm, Pos. def. $@end tex
@tab I
@tab (@i{shape})
@end multitable
@end iftex
@ifnottex
@item parameters 0 (2):  [ mu, Sigma ]
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab mu @tab  @tab (0,@dots{},0) @tab @i{(location)}
@item @code{[1]} @tab Sigma @tab Symm, Pos. def. @tab I @tab @i{(shape)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:KBJe00,, [KBJe00: Ch.45; p.105]}
@end ifhtml
@ifnothtml
[KBJe00: Ch.45; p.105]
@end ifnothtml

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node multistudent
@subsection   @code{multistudent}  --  Multistudent distribution
@anchor{funct:unur_distr_multistudent}
@findex unur_distr_multistudent


@table @i
@item PDF:
@iftex
@tex
$f(x) = 1 / ( 1 + (x-\mu)^t . \Sigma^{-1} . (x-\mu) / m)^{(dim+m)/2} )$
@end tex
@end iftex
@ifnottex
f(x) = 1 / ( 1 + (x-mu)^t . Sigma^(-1) . (x-mu) / m)^((dim+m)/2) )
@end ifnottex

@item constant:
@iftex
@tex
$\Gamma((dim+m)/2) / ( \Gamma(m/2) (m\, \pi)^{dim/2} \,  \sqrt{\det(\Sigma)} )$
@end tex
@end iftex
@ifnottex
Gamma((dim+m)/2) / ( Gamma(m/2) (m*pi)^(dim/2) * sqrt(det(Sigma)) )
@end ifnottex

@item domain:
@iftex
@tex
$-\infty^{dim} < x < \infty^{dim}$
@end tex
@end iftex
@ifnottex
-infinity^(dim) < x < infinity^(dim)
@end ifnottex

@iftex
@item parameters 0 (3): @r{ [ m, mu, Sigma ]}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$m $@end tex
@tab@tex$m>0 $@end tex
@tab 1
@tab (@i{location})
@item @code{[1]}
@tab@tex$\mu $@end tex
@tab@tex$ $@end tex
@tab (0,@dots{},0)
@tab (@i{location})
@item @code{[2]}
@tab@tex$\Sigma $@end tex
@tab@tex$Symm, Pos. def. $@end tex
@tab I
@tab (@i{shape})
@end multitable
@end iftex
@ifnottex
@item parameters 0 (3):  [ m, mu, Sigma ]
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab m @tab m>0 @tab 1 @tab @i{(location)}
@item @code{[1]} @tab mu @tab  @tab (0,@dots{},0) @tab @i{(location)}
@item @code{[2]} @tab Sigma @tab Symm, Pos. def. @tab I @tab @i{(shape)}
@end multitable
@end ifnottex
@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c stddist.dh
@c

@page
@node Stddist_DISCR
@section   UNU.RAN Library of discrete univariate distributions

@menu
* binomial:: Binomial distribution
* geometric:: Geometric distribution
* hypergeometric:: Hypergeometric distribution
* logarithmic:: Logarithmic distribution
* negativebinomial:: Negative Binomial distribution
* poisson:: Poisson distribution
@end menu


At the moment there are no CDFs implemented for discrete distribution.
Thus
@ifhtml
@ref{funct:unur_distr_discr_upd_pmfsum,@command{unur_distr_discr_upd_pmfsum}}
@end ifhtml
@ifnothtml
@command{unur_distr_discr_upd_pmfsum}
@end ifnothtml
does not work properly for truncated
distribution.


@c
@c end of stddist.dh
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node binomial
@subsection   @code{binomial}  --  Binomial distribution
@anchor{funct:unur_distr_binomial}
@findex unur_distr_binomial


@table @i
@item PMF:
@iftex
@tex
${n \choose k} \,  p^k \,  (1-p)^{n-k}$
@end tex
@end iftex
@ifnottex
(n \choose k) * p^k * (1-p)^(n-k)
@end ifnottex

@item constant:
@iftex
@tex
$1$
@end tex
@end iftex
@ifnottex
1
@end ifnottex

@item domain:
@iftex
@tex
$0 \leq k \leq n$
@end tex
@end iftex
@ifnottex
0 <= k <= n
@end ifnottex

@iftex
@item parameters 2 (2): @r{ n, p}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$n $@end tex
@tab@tex$\geq 1 $@end tex
@tab
@tab (@i{no. of elements})
@item @code{[1]}
@tab@tex$p $@end tex
@tab@tex$0 < p < 1 $@end tex
@tab
@tab (@i{shape})
@end multitable
@end iftex
@ifnottex
@item parameters 2 (2):  n, p
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab n @tab >= 1 @tab  @tab @i{(no. of elements)}
@item @code{[1]} @tab p @tab 0 < p < 1 @tab  @tab @i{(shape)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKKa92,, [JKKa92: Ch.3; p.105]}
@end ifhtml
@ifnothtml
[JKKa92: Ch.3; p.105]
@end ifnothtml

@item special generators:
@table @code
@item DEF
@iftex
Ratio of Uniforms/Inversion  [STa89]
@end iftex
@ifhtml
Ratio of Uniforms/Inversion  @ref{bib:STa89, [STa89]}
@end ifhtml
@ifinfo
Ratio of Uniforms/Inversion  [STa89]
@end ifinfo
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node geometric
@subsection   @code{geometric}  --  Geometric distribution
@anchor{funct:unur_distr_geometric}
@findex unur_distr_geometric


@table @i
@item PMF:
@iftex
@tex
$p \,  (1-p)^k$
@end tex
@end iftex
@ifnottex
p * (1-p)^k
@end ifnottex

@item constant:
@iftex
@tex
$1$
@end tex
@end iftex
@ifnottex
1
@end ifnottex

@item domain:
@iftex
@tex
$0 \leq k < \infty$
@end tex
@end iftex
@ifnottex
0 <= k < infinity
@end ifnottex

@iftex
@item parameters 1 (1): @r{ p}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$p $@end tex
@tab@tex$0 < p < 1 $@end tex
@tab
@tab (@i{shape})
@end multitable
@end iftex
@ifnottex
@item parameters 1 (1):  p
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab p @tab 0 < p < 1 @tab  @tab @i{(shape)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKKa92,, [JKKa92: Ch.5.2; p.201]}
@end ifhtml
@ifnothtml
[JKKa92: Ch.5.2; p.201]
@end ifnothtml

@item special generators:
@table @code
@item INV
Inversion method
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node hypergeometric
@subsection   @code{hypergeometric}  --  Hypergeometric distribution
@anchor{funct:unur_distr_hypergeometric}
@findex unur_distr_hypergeometric


@table @i
@item PMF:
@iftex
@tex
${M \choose k} \,  {N-M \choose n-k} / {N \choose n}$
@end tex
@end iftex
@ifnottex
(M \choose k) * (N-M \choose n-k) / (N \choose n)
@end ifnottex

@item constant:
@iftex
@tex
$1$
@end tex
@end iftex
@ifnottex
1
@end ifnottex

@item domain:
@iftex
@tex
$\max(0,n-N+M) \leq k \leq \min(n,M)$
@end tex
@end iftex
@ifnottex
max(0,n-N+M) <= k <= min(n,M)
@end ifnottex

@iftex
@item parameters 3 (3): @r{ N, M, n}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$N $@end tex
@tab@tex$\geq 1 $@end tex
@tab
@tab (@i{no. of elements})
@item @code{[1]}
@tab@tex$M $@end tex
@tab@tex$1 \leq M \leq N $@end tex
@tab
@tab (@i{shape})
@item @code{[2]}
@tab@tex$n $@end tex
@tab@tex$1 \leq n \leq N $@end tex
@tab
@tab (@i{shape})
@end multitable
@end iftex
@ifnottex
@item parameters 3 (3):  N, M, n
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab N @tab >= 1 @tab  @tab @i{(no. of elements)}
@item @code{[1]} @tab M @tab 1 <= M <= N @tab  @tab @i{(shape)}
@item @code{[2]} @tab n @tab 1 <= n <= N @tab  @tab @i{(shape)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKKa92,, [JKKa92: Ch.6; p.237]}
@end ifhtml
@ifnothtml
[JKKa92: Ch.6; p.237]
@end ifnothtml

@item special generators:
@table @code
@item DEF
@iftex
Ratio of Uniforms/Inversion  [STa89]
@end iftex
@ifhtml
Ratio of Uniforms/Inversion  @ref{bib:STa89, [STa89]}
@end ifhtml
@ifinfo
Ratio of Uniforms/Inversion  [STa89]
@end ifinfo
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node logarithmic
@subsection   @code{logarithmic}  --  Logarithmic distribution
@anchor{funct:unur_distr_logarithmic}
@findex unur_distr_logarithmic


@table @i
@item PMF:
@iftex
@tex
$\theta^k / k$
@end tex
@end iftex
@ifnottex
theta^k / k
@end ifnottex

@item constant:
@iftex
@tex
$- \log( 1.-\theta);$
@end tex
@end iftex
@ifnottex
- log( 1.-theta);
@end ifnottex

@item domain:
@iftex
@tex
$1 \leq k < \infty$
@end tex
@end iftex
@ifnottex
1 <= k < infinity
@end ifnottex

@iftex
@item parameters 1 (1): @r{ theta}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\theta $@end tex
@tab@tex$0 < \theta < 1 $@end tex
@tab
@tab (@i{shape})
@end multitable
@end iftex
@ifnottex
@item parameters 1 (1):  theta
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab theta @tab 0 < theta < 1 @tab  @tab @i{(shape)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKKa92,, [JKKa92: Ch.7; p.285]}
@end ifhtml
@ifnothtml
[JKKa92: Ch.7; p.285]
@end ifnothtml

@item special generators:
@table @code
@item DEF
@iftex
Inversion/Transformation  [KAa81]
@end iftex
@ifhtml
Inversion/Transformation  @ref{bib:KAa81, [KAa81]}
@end ifhtml
@ifinfo
Inversion/Transformation  [KAa81]
@end ifinfo
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node negativebinomial
@subsection   @code{negativebinomial}  --  Negative Binomial distribution
@anchor{funct:unur_distr_negativebinomial}
@findex unur_distr_negativebinomial


@table @i
@item PMF:
@iftex
@tex
${k+r-1 \choose r-1} \,  p^r \,  (1-p)^k$
@end tex
@end iftex
@ifnottex
(k+r-1 \choose r-1) * p^r * (1-p)^k
@end ifnottex

@item constant:
@iftex
@tex
$1$
@end tex
@end iftex
@ifnottex
1
@end ifnottex

@item domain:
@iftex
@tex
$0 \leq k < \infty$
@end tex
@end iftex
@ifnottex
0 <= k < infinity
@end ifnottex

@iftex
@item parameters 2 (2): @r{ p, r}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$p $@end tex
@tab@tex$0 < p < 1 $@end tex
@tab
@tab (@i{shape})
@item @code{[1]}
@tab@tex$r $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{shape})
@end multitable
@end iftex
@ifnottex
@item parameters 2 (2):  p, r
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab p @tab 0 < p < 1 @tab  @tab @i{(shape)}
@item @code{[1]} @tab r @tab > 0 @tab  @tab @i{(shape)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKKa92,, [JKKa92: Ch.5.1; p.200]}
@end ifhtml
@ifnothtml
[JKKa92: Ch.5.1; p.200]
@end ifnothtml

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node poisson
@subsection   @code{poisson}  --  Poisson distribution
@anchor{funct:unur_distr_poisson}
@findex unur_distr_poisson


@table @i
@item PMF:
@iftex
@tex
$\theta^k / k!$
@end tex
@end iftex
@ifnottex
theta^k / k!
@end ifnottex

@item constant:
@iftex
@tex
$\exp(\theta)$
@end tex
@end iftex
@ifnottex
exp(theta)
@end ifnottex

@item domain:
@iftex
@tex
$0 \leq k < \infty$
@end tex
@end iftex
@ifnottex
0 <= k < infinity
@end ifnottex

@iftex
@item parameters 1 (1): @r{ theta}

@multitable {No.} {namex} {999999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]}
@tab@tex$\theta $@end tex
@tab@tex$> 0 $@end tex
@tab
@tab (@i{shape})
@end multitable
@end iftex
@ifnottex
@item parameters 1 (1):  theta
@multitable {No.xx} {namexxx} {99999999999} {defaultx} {xxxxxxxxxxxxxxxxxxxxxxxx}
@item No. @tab name @tab @tab default
@item @code{[0]} @tab theta @tab > 0 @tab  @tab @i{(shape)}
@end multitable
@end ifnottex
@item reference:
@ifhtml
@ref{bib:JKKa92,, [JKKa92: Ch.4; p.151]}
@end ifhtml
@ifnothtml
[JKKa92: Ch.4; p.151]
@end ifnothtml

@item special generators:
@table @code
@item DEF
@iftex
Tabulated Inversion combined with Acceptance Complement  [ADb82]
@end iftex
@ifhtml
Tabulated Inversion combined with Acceptance Complement  @ref{bib:ADb82, [ADb82]}
@end ifhtml
@ifinfo
Tabulated Inversion combined with Acceptance Complement  [ADb82]
@end ifinfo
@item 2
@iftex
Tabulated Inversion combined with Patchwork Rejection  [ZHa94]
@end iftex
@ifhtml
Tabulated Inversion combined with Patchwork Rejection  @ref{bib:ZHa94, [ZHa94]}
@end ifhtml
@ifinfo
Tabulated Inversion combined with Patchwork Rejection  [ZHa94]
@end ifinfo
@end table

@end table


@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c stddist.dh
@c

@page
@node Stddist_MATR
@section   UNU.RAN Library of random matrices

@menu
* correlation:: Random correlation matrix
@end menu


@c
@c end of stddist.dh
@c -------------------------------------
@c -------------------------------------
@c unur_distributions.h
@c

@node correlation
@subsection   @code{correlation}  --  Random correlation matrix
@anchor{funct:unur_distr_correlation}
@findex unur_distr_correlation


@table @i
@end table


@code{UNUR_DISTR *unur_distr_correlation( int n )}
creates a distribution object for a random correlation matrix of
@var{n} rows and columns. It can be used with method MCORR
(@pxref{MCORR,,Random Correlation Matrix}) to
generate random correlation matrices of the given size.



@c
@c end of unur_distributions.h
@c -------------------------------------
@c -------------------------------------
@c error_debug.dh
@c

@node Error_Debug
@chapter   Error handling and Debugging

@menu
* Output_streams:: Output streams
* Debug:: Debugging
* Error_reporting:: Error reporting
* Errno:: Error codes
* Error_handlers:: Error handlers
@end menu


UNU.RAN routines report an error whenever they cannot perform the
requested task. Additionally it is possible to get information
about the generated distribution of generator objects for debugging
purposes. However, the latter must be enabled when compiling and
installing the library. (It is disabled by default.)
This chapter describes all necessary details:

@itemize
@item Choose an output stream to for writing the requested
information.
@item Select a debugging level.
@item Select an error handler.
@item Write your own error handler.
@item Get more information for a particular error code.
@end itemize



@c
@c end of error_debug.dh
@c -------------------------------------
@c -------------------------------------
@c stream.h
@c

@node Output_streams
@section   Output streams


@cindex Error handlers
@cindex Output streams

UNU.RAN uses a logfile for writing all error messages, warnings,
and debugging information onto an output stream. This stream can
be set at runtime by the
@ifhtml
@ref{funct:unur_set_stream,@command{unur_set_stream}}
@end ifhtml
@ifnothtml
@command{unur_set_stream}
@end ifnothtml
call.
If no such stream is given by the user a default stream is used
by the library: all messages are written into the file
@file{unuran.log} in the current working directory. The name of
this logfile is defined by the macro @code{UNUR_LOG_FILE} in
@file{unuran_config.h}.
(If UNU.RAN fails to open this file for writing, @file{stderr}
is used instead.)

To destinguish between messages for different objects each of
these has its own identifier which is composed by the name of
the distribution obejct and generator type, resp., followed by a
dot and three digits.
(If there are more than 999 generators then the identifiers are
not unique.)

@emph{Remark:} Writting debugging information must be switched
on at compile time using the configure flag
@code{--enable-logging}, see @ref{Debug,,Debugging}.


@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_set_stream,unur_set_stream}
@item @ref{funct:unur_get_stream,unur_get_stream}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_set_stream}
@deftypefn Function {FILE*} unur_set_stream (FILE* @var{new_stream})
This function sets a new file handler for the output stream,
@var{new_stream}, for the UNU.RAN library routines. The previous
handler is returned (so that you can restore it later).
Note that the pointer to a user defined file handler is stored in a
static variable, so there can be only one output stream handler per
program. This function should be not be used in multi-threaded
programs except to set up a program-wide error handler from a
master thread.

The @code{NULL} pointer is not allowed.
(If you want to disable logging of debugging information use
unur_set_default_debug(UNUR_DEBUG_OFF) instead.
If you want to disable error messages at all use
@ifhtml
@ref{funct:unur_set_error_handler_off,@command{unur_set_error_handler_off}.}
@end ifhtml
@ifnothtml
@command{unur_set_error_handler_off}.
@end ifnothtml
)
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_set_stream}
@deftypefn {} {FILE*} unur_set_stream (FILE* @var{new_stream})
This function sets a new file handler for the output stream,
@var{new_stream}, for the UNU.RAN library routines. The previous
handler is returned (so that you can restore it later).
Note that the pointer to a user defined file handler is stored in a
static variable, so there can be only one output stream handler per
program. This function should be not be used in multi-threaded
programs except to set up a program-wide error handler from a
master thread.

The @code{NULL} pointer is not allowed.
(If you want to disable logging of debugging information use
unur_set_default_debug(UNUR_DEBUG_OFF) instead.
If you want to disable error messages at all use
@ifhtml
@ref{funct:unur_set_error_handler_off,@command{unur_set_error_handler_off}.}
@end ifhtml
@ifnothtml
@command{unur_set_error_handler_off}.
@end ifnothtml
)
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_get_stream}
@deftypefn Function {FILE*} unur_get_stream (void)
Get the file handle for the current output stream. It can be used to
allow applications to write additional information into the logfile.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_get_stream}
@deftypefn {} {FILE*} unur_get_stream (void)
Get the file handle for the current output stream. It can be used to
allow applications to write additional information into the logfile.
@end deftypefn
@end ifnotinfo




@c
@c end of stream.h
@c -------------------------------------
@c -------------------------------------
@c debug.h
@c

@node Debug
@section   Debugging


The UNU.RAN library has several debugging levels which
can be switched on/off by debugging flags. This debugging
feature must be enabled when building the library using the
@code{--enable-logging} configure flag.

The debugging levels range from print a short description of the
created generator object to a detailed description of hat
functions and tracing the sampling routines. The output is printed
onto the debugging output stream
(@pxref{Output_streams,,Output streams}).

The debugging flags can be set or changed by the respective calls
@ifhtml
@ref{funct:unur_set_debug,@command{unur_set_debug}}
@end ifhtml
@ifnothtml
@command{unur_set_debug}
@end ifnothtml
and
@ifhtml
@ref{funct:unur_chg_debug,@command{unur_chg_debug}}
@end ifhtml
@ifnothtml
@command{unur_chg_debug}
@end ifnothtml
independently for each
generator.

By default flag @code{UNUR_DEBUG_INIT} (see
below) is used. This default flags is set by the macro
@code{UNUR_DEBUGFLAG_DEFAULT} in @file{unuran_config.h} and can
be changed at runtime by a
@ifhtml
@ref{funct:unur_set_default_debug,@command{unur_set_default_debug}}
@end ifhtml
@ifnothtml
@command{unur_set_default_debug}
@end ifnothtml
call.

Off course these debugging flags
depend on the chosen method. Since most of these are merely for
debugging the library itself, a description of the flags are given
in the corresponding source files of the method.
Nevertheless, the following flags can be used with all methods.

Common debug flags:

@ftable @code
@item UNUR_DEBUG_OFF
@findex UNUR_DEBUG_OFF
switch off all debuging information
@item UNUR_DEBUG_ALL
@findex UNUR_DEBUG_ALL
all avaivable information
@item UNUR_DEBUG_INIT
@findex UNUR_DEBUG_INIT
parameters of generator object after initialization
@item UNUR_DEBUG_SETUP
@findex UNUR_DEBUG_SETUP
data created at setup
@item UNUR_DEBUG_ADAPT
@findex UNUR_DEBUG_ADAPT
data created during adaptive steps
@item UNUR_DEBUG_SAMPLE
@findex UNUR_DEBUG_SAMPLE
trace sampling
@end ftable

Notice that these are flags which could be combined using the
@code{|} operator.

Almost all routines check a given pointer before they read from or write
to the given address. This does not hold for time-critical routines
like all sampling routines. Thus you are responsible for checking a
pointer that is returned from a
@ifhtml
@ref{funct:unur_init,@command{unur_init}}
@end ifhtml
@ifnothtml
@command{unur_init}
@end ifnothtml
call.
However, it is possible to turn on checking for invalid @code{NULL} pointers
even in such time-critical routines by building the library
using the @code{--enable-check-struct} configure flag.

Another debugging tool used in the library are magic cookies that
validate a given pointer. It produces an error whenever a given
pointer points to an object that is invalid in the context.
The usage of magic cookies is also switched on by the
@code{--enable-check-struct} configure flag.


@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_set_debug,unur_set_debug}
@item @ref{funct:unur_chg_debug,unur_chg_debug}
@item @ref{funct:unur_set_default_debug,unur_set_default_debug}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_set_debug}
@deftypefn Function {int} unur_set_debug (UNUR_PAR* @var{parameters}, unsigned @var{debug})
Set debugging flags for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_set_debug}
@deftypefn {} {int} unur_set_debug (UNUR_PAR* @var{parameters}, unsigned @var{debug})
Set debugging flags for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_chg_debug}
@deftypefn Function {int} unur_chg_debug (UNUR_GEN* @var{generator}, unsigned @var{debug})
Change debugging flags for generator.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_chg_debug}
@deftypefn {} {int} unur_chg_debug (UNUR_GEN* @var{generator}, unsigned @var{debug})
Change debugging flags for generator.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_set_default_debug}
@deftypefn Function {int} unur_set_default_debug (unsigned @var{debug})
Change default debugging flag.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_set_default_debug}
@deftypefn {} {int} unur_set_default_debug (unsigned @var{debug})
Change default debugging flag.
@end deftypefn
@end ifnotinfo




@c
@c end of debug.h
@c -------------------------------------
@c -------------------------------------
@c error.h
@c

@node Error_reporting
@section   Error reporting


UNU.RAN routines report an error whenever they cannot perform the
requested task. For example, applying transformed density
rejection to a distribution that violates the T-concavity
condition, or trying to set a parameter that is out of range,
result in an error message.
It might also happen that the setup fails for transformed density
rejection for a T-concave distribution with some extreme density
function simply because of round-off errors that makes the
generation of a hat function numerically impossible.
Situations like this may happen when using black box algorithms and
you should check the return values of all routines.

All @command{..._set_...}, and @command{..._chg_...} calls
return @code{UNUR_SUCCESS} if they could be executed
successfully. Otherwise, some error codes are returned if it was
not possible to set or change the desired parameters,
e.g. because the given values are out of range, or simply
because the set call does not work for the chosen method.

All routines that return a pointer to the requested object will
return a @code{NULL} pointer in case of error.
(Thus you should always check the pointer to avoid possible
segmentation faults. Sampling routines usually do not check the
given pointer to the generator object.)

The library distinguishes between two major classes of error:

@table @emph

@item (fatal) errors:
The library was not able to construct the
requested object.

@item warnings:
Some problems encounters while constructing a generator
object. The routine has tried to solve the problem but the resulting
object might not be what you want. For example, chosing a special
variant of a method does not work and the initialization routine
might switch to another variant. Then the generator produces random
variates of the requested distribution but correlation induction
is not possible. However, it also might happen that
changing the domain of a distribution has failed. Then the generator
produced random variates with too large/too small range, i.e. their
distribution is not correct.
@end table

It is obvious from the example that this distinction between errors
and warning is rather crude and sometimes arbitrary.

UNU.RAN routines use the global variable @var{unur_errno} to
report errors, completely analogously to @var{errno} in the ANSI
C standard library.
(However this approach is not thread-safe. There can
be only one instance of a global variable per program. Different
threads of execution may overwrite @var{unur_errno}
simultaneously).
Thus when an error occurs the caller of the routine can examine the
error code in @var{unur_errno} to get more details about the
reason why a routine failed. You get a short
description of the error by a
@ifhtml
@ref{funct:unur_get_strerror,@command{unur_get_strerror}}
@end ifhtml
@ifnothtml
@command{unur_get_strerror}
@end ifnothtml
call.
All the error code numbers have prefix @code{UNUR_ERR_} and expand
to non-zero constant unsigned integer values.
Error codes are divided into six main groups,
see @ref{Errno,,Error codes}.

Alternatively, the variable @var{unur_errno} can also read by a
@ifhtml
@ref{funct:unur_get_errno,@command{unur_get_errno}}
@end ifhtml
@ifnothtml
@command{unur_get_errno}
@end ifnothtml
call and can be reset by the
@ifhtml
@ref{funct:unur_reset_errno,@command{unur_reset_errno}}
@end ifhtml
@ifnothtml
@command{unur_reset_errno}
@end ifnothtml
call (this is in particular required for the Windows version of the
library).

Additionally, there exists a error handler
(@pxref{Error_handlers,,Error handlers}) that is invoked in case
of an error.


In addition to reporting errors by setting error codes in
@var{unur_errno}, the library also has an error handler
function. This function is called by other library functions
when they report an error, just before they return to the
caller (@pxref{Error_handlers,,Error handlers}).
The default behavior of the error handler is to print a short
message:

@example
AROU.004: [error] arou.c:1500 - (generator) condition for method violated:
AROU.004: ..>  PDF not unimodal
@end example

The purpose of the error handler is to provide a function
where a breakpoint can be set that will catch library errors when
running under the debugger. It is not intended for use in production
programs, which should handle any errors using the return codes.


@subheading Function reference

@ifhtml
@itemize
@item @ref{var:unur_errno,unur_errno}
@item @ref{funct:unur_get_errno,unur_get_errno}
@item @ref{funct:unur_reset_errno,unur_reset_errno}
@item @ref{funct:unur_get_strerror,unur_get_strerror}
@end itemize
@end ifhtml


@ifinfo
@anchor{var:unur_errno}
@deftypevar {extern int} unur_errno
@findex unur_errno
Global variable for reporting diagnostics of error.
@end deftypevar
@end ifinfo
@ifnotinfo
@anchor{var:unur_errno}
@deftypevar {extern int} unur_errno
@findex unur_errno
Global variable for reporting diagnostics of error.
@end deftypevar
@end ifnotinfo

@ifinfo
@anchor{funct:unur_get_errno}
@deftypefn Function {int} unur_get_errno (void)
Get current value of global variable @var{unur_errno}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_get_errno}
@deftypefn {} {int} unur_get_errno (void)
Get current value of global variable @var{unur_errno}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_reset_errno}
@deftypefn Function {void} unur_reset_errno (void)
Reset global variable @var{unur_errno} to @code{UNUR_SUCCESS}
(i.e., no errors occured).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_reset_errno}
@deftypefn {} {void} unur_reset_errno (void)
Reset global variable @var{unur_errno} to @code{UNUR_SUCCESS}
(i.e., no errors occured).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_get_strerror}
@deftypefn Function {const char*} unur_get_strerror (const @var{int errnocode})
Get a short description for error code value.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_get_strerror}
@deftypefn {} {const char*} unur_get_strerror (const @var{int errnocode})
Get a short description for error code value.
@end deftypefn
@end ifnotinfo




@c
@c end of error.h
@c -------------------------------------
@c -------------------------------------
@c unur_errno.h
@c

@node Errno
@section   Error codes



@subsubheading List of error codes

@itemize @bullet
@item Procedure executed successfully (no error)
@ftable @code
@item UNUR_SUCCESS (0x0u)
success (no error)
@end ftable

@item Errors that occurred while handling distribution objects.
@ftable @code
@item UNUR_ERR_DISTR_SET
set failed (invalid parameter).
@item UNUR_ERR_DISTR_GET
get failed (parameter not set).
@item UNUR_ERR_DISTR_NPARAMS
invalid number of parameters.
@item UNUR_ERR_DISTR_DOMAIN
parameter(s) out of domain.
@item UNUR_ERR_DISTR_GEN
invalid variant for special generator.
@item UNUR_ERR_DISTR_REQUIRED
incomplete distribution object, entry missing.
@item UNUR_ERR_DISTR_UNKNOWN
unknown distribution, cannot handle.
@item UNUR_ERR_DISTR_INVALID
invalid distribution object.
@item UNUR_ERR_DISTR_DATA
data are missing.
@item UNUR_ERR_DISTR_PROP
desired property does not exist
@end ftable

@item Errors that occurred while handling parameter objects.
@ftable @code
@item UNUR_ERR_PAR_SET
set failed (invalid parameter)
@item UNUR_ERR_PAR_VARIANT
invalid variant -> using default
@item UNUR_ERR_PAR_INVALID
invalid parameter object
@end ftable

@item Errors that occurred while handling generator objects.
@ftable @code
@item UNUR_ERR_GEN
error with generator object.
@item UNUR_ERR_GEN_DATA
(possibly) invalid data.
@item UNUR_ERR_GEN_CONDITION
condition for method violated.
@item UNUR_ERR_GEN_INVALID
invalid generator object.
@item UNUR_ERR_GEN_SAMPLING
sampling error.
@item UNUR_ERR_NO_REINIT
reinit routine not implemented.
@item UNUR_ERR_NO_QUANTILE
quantile routine not implemented.
@end ftable

@item Errors that occurred while handling URNG objects.
@ftable @code
@item UNUR_ERR_URNG
generic error with URNG object.
@item UNUR_ERR_URNG_MISS
missing functionality.
@end ftable

@item Errors that occurred while parsing strings.
@ftable @code
@item UNUR_ERR_STR
error in string.
@item UNUR_ERR_STR_UNKNOWN
unknown keyword.
@item UNUR_ERR_STR_SYNTAX
syntax error.
@item UNUR_ERR_STR_INVALID
invalid parameter.
@item UNUR_ERR_FSTR_SYNTAX
syntax error in function string.
@item UNUR_ERR_FSTR_DERIV
cannot derivate function.
@end ftable

@item Other run time errors.
@ftable @code
@item UNUR_ERR_DOMAIN
argument out of domain.
@item UNUR_ERR_ROUNDOFF
(serious) round-off error.
@item UNUR_ERR_MALLOC
virtual memory exhausted.
@item UNUR_ERR_NULL
invalid @code{NULL} pointer.
@item UNUR_ERR_COOKIE
invalid cookie.
@item UNUR_ERR_GENERIC
generic error.
@item UNUR_ERR_SILENT
silent error (no error message).
@item UNUR_ERR_INF
infinity occured.
@item UNUR_ERR_NAN
NaN occured.
@item UNUR_ERR_COMPILE
Requested routine requires different compilation switches.
Recompilation of library necessary.
@item UNUR_ERR_SHOULD_NOT_HAPPEN
Internal error, that should not happen.
Please report this bug!
@end ftable

@end itemize


@c
@c end of unur_errno.h
@c -------------------------------------
@c -------------------------------------
@c error.h
@c

@node Error_handlers
@section   Error handlers


The default behavior of the UNU.RAN error handler is to print a
short message onto the output stream, usually a logfile
(@pxref{Output_streams,,Output streams}), e.g.,

@example
AROU.004: [error] arou.c:1500 - (generator) condition for method violated:
AROU.004: ..>  PDF not unimodal
@end example

This error handler can be switched off using the
@ifhtml
@ref{funct:unur_set_error_handler_off,@command{unur_set_error_handler_off}}
@end ifhtml
@ifnothtml
@command{unur_set_error_handler_off}
@end ifnothtml
call, or replace it by a new one.
Thus it allows to set a breakpoint that will catch library errors when
running under the debugger. It also can be used to redirect
error messages when UNU.RAN is included in general purpose
libraries or in interactive programming environments.

@deftp {Data Type} UNUR_ERROR_HANDLER

This is the type of UNU.RAN error handler functions. An error
handler will be passed six arguments which specify
the identifier of the object where the error occured (a string),
the name of the source file in which it occurred (also a string),
the line number in that file (an integer),
the type of error (a string: @code{"error"} or @code{"warning"}),
the error number (an integert), and
the reason for the error (a string).
The source file and line number are set at compile time
using the @code{__FILE__} and @code{__LINE__} directives in the
preprocessor.
The error number can be translated into a short description
using a
@ifhtml
@ref{funct:unur_get_strerror,@command{unur_get_strerror}}
@end ifhtml
@ifnothtml
@command{unur_get_strerror}
@end ifnothtml
call.
An error handler function returns type @code{void}.

Error handler functions should be defined like this,
@example
void my_handler(
@ @ @ @ @ @ @ @ @ @ @ const char *objid,
@ @ @ @ @ @ @ @ @ @ @ const char *file,
@ @ @ @ @ @ @ @ @ @ @ int line,
@ @ @ @ @ @ @ @ @ @ @ const char *errortype,
@ @ @ @ @ @ @ @ @ @ @ int unur_errno,
@ @ @ @ @ @ @ @ @ @ @ const char *reason )
@end example
@end deftp

To request the use of your own error handler you need the call
@ifhtml
@ref{funct:unur_set_error_handler,@command{unur_set_error_handler}.}
@end ifhtml
@ifnothtml
@command{unur_set_error_handler}.
@end ifnothtml

@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_set_error_handler,unur_set_error_handler}
@item @ref{funct:unur_set_error_handler_off,unur_set_error_handler_off}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_set_error_handler}
@deftypefn Function {UNUR_ERROR_HANDLER*} unur_set_error_handler (UNUR_ERROR_HANDLER* @var{new_handler})
This function sets a new error handler, @var{new_handler}, for the
UNU.RAN library routines. The previous handler is returned (so that you
can restore it later). Note that the pointer to a user defined
error handler function is stored in a static variable, so there
can be only one error handler per program. This function should
be not be used in multi-threaded programs except to set up a
program-wide error handler from a master thread.

To use the default behavior set the error handler to @code{NULL}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_set_error_handler}
@deftypefn {} {UNUR_ERROR_HANDLER*} unur_set_error_handler (UNUR_ERROR_HANDLER* @var{new_handler})
This function sets a new error handler, @var{new_handler}, for the
UNU.RAN library routines. The previous handler is returned (so that you
can restore it later). Note that the pointer to a user defined
error handler function is stored in a static variable, so there
can be only one error handler per program. This function should
be not be used in multi-threaded programs except to set up a
program-wide error handler from a master thread.

To use the default behavior set the error handler to @code{NULL}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_set_error_handler_off}
@deftypefn Function {UNUR_ERROR_HANDLER*} unur_set_error_handler_off (void)
This function turns off the error handler by defining an error
handler which does nothing (except of setting @var{unur_errno}.
The previous handler is returned (so that you can restore it later).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_set_error_handler_off}
@deftypefn {} {UNUR_ERROR_HANDLER*} unur_set_error_handler_off (void)
This function turns off the error handler by defining an error
handler which does nothing (except of setting @var{unur_errno}.
The previous handler is returned (so that you can restore it later).
@end deftypefn
@end ifnotinfo




@c
@c end of error.h
@c -------------------------------------
@c -------------------------------------
@c unuran_tests.h
@c

@node Testing
@chapter   Testing


The following routines can be used to test the performance of the
implemented generators and can be used to verify the implementions.
They are declared in @file{unuran_tests.h} which has to be included.


@subheading Function reference

@ifhtml
@itemize
@item @ref{funct:unur_run_tests,unur_run_tests}
@item @ref{funct:unur_test_printsample,unur_test_printsample}
@item @ref{funct:unur_test_timing,unur_test_timing}
@item @ref{funct:unur_test_timing_R,unur_test_timing_R}
@item @ref{funct:unur_test_timing_uniform,unur_test_timing_uniform}
@item @ref{funct:unur_test_timing_exponential,unur_test_timing_exponential}
@item @ref{funct:unur_test_timing_total,unur_test_timing_total}
@item @ref{funct:unur_test_count_urn,unur_test_count_urn}
@item @ref{funct:unur_test_count_pdf,unur_test_count_pdf}
@item @ref{funct:unur_test_par_count_pdf,unur_test_par_count_pdf}
@item @ref{funct:unur_test_chi2,unur_test_chi2}
@item @ref{funct:unur_test_moments,unur_test_moments}
@item @ref{funct:unur_test_correlation,unur_test_correlation}
@item @ref{funct:unur_test_quartiles,unur_test_quartiles}
@item @ref{funct:unur_test_u_error,unur_test_u_error}
@end itemize
@end ifhtml


@ifinfo
@anchor{funct:unur_run_tests}
@deftypefn Function {void} unur_run_tests (UNUR_PAR* @var{parameters}, unsigned @var{tests}, FILE* @var{out})
Run a battery of tests.
The following tests are available (use @code{|} to combine these
tests):
@table @code
@item UNUR_TEST_ALL
run all possible tests.
@item UNUR_TEST_TIME
estimate generation times.
@item UNUR_TEST_N_URNG
count number of uniform random numbers
@item UNUR_TEST_N_PDF
count number of PDF calls
@item UNUR_TEST_CHI2
run chi^2 test for goodness of fit
@item UNUR_TEST_SAMPLE
print a small sample.
@end table
All these tests can be started individually (see below).
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_run_tests}
@deftypefn {} {void} unur_run_tests (UNUR_PAR* @var{parameters}, unsigned @var{tests}, FILE* @var{out})
Run a battery of tests.
The following tests are available (use @code{|} to combine these
tests):
@table @code
@item UNUR_TEST_ALL
run all possible tests.
@item UNUR_TEST_TIME
estimate generation times.
@item UNUR_TEST_N_URNG
count number of uniform random numbers
@item UNUR_TEST_N_PDF
count number of PDF calls
@item UNUR_TEST_CHI2
run chi^2 test for goodness of fit
@item UNUR_TEST_SAMPLE
print a small sample.
@end table
All these tests can be started individually (see below).
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_test_printsample}
@deftypefn Function {void} unur_test_printsample (UNUR_GEN* @var{generator}, int @var{n_rows}, int @var{n_cols}, FILE* @var{out})
Print a small sample with @var{n_rows} rows and @var{n_cols} columns.
@var{out} is the output stream to which all results are written.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_test_printsample}
@deftypefn {} {void} unur_test_printsample (UNUR_GEN* @var{generator}, int @var{n_rows}, int @var{n_cols}, FILE* @var{out})
Print a small sample with @var{n_rows} rows and @var{n_cols} columns.
@var{out} is the output stream to which all results are written.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_test_timing}
@deftypefn Function {UNUR_GEN*} unur_test_timing (UNUR_PAR* @var{parameters}, int @var{log10_samplesize}, double* @var{time_setup}, double* @var{time_sample}, int @var{verbosity}, FILE* @var{out})
Timing. @var{parameters} is an parameter object for which setup
time and marginal generation times have to be measured. The results
are written into @var{time_setup} and @var{time_sample},
respectively. @var{log10_samplesize} is the common logarithm of the
sample size that is used for timing.

If @var{verbosity} is @code{TRUE} then a small table is printed to
output stream @var{out} with setup time, marginal generation time and
average generation times for generating 10, 100, @dots{} random
variates. All times are given in micro seconds and relative to
the generation times for the underlying uniform random number
(using the UNIF interface) and an exponential distributed
random variate using the inversion method.

The created generator object is returned.
If a generator object could not be created successfully, then @code{NULL}
is returned.

If @var{verbosity} is @code{TRUE} the result is written to the output
stream @var{out}.

Notice: All timing results are subject to heavy changes. Reruning
timings usually results in different results. Minor changes in
the source code can cause changes in such timings up to 25 percent.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_test_timing}
@deftypefn {} {UNUR_GEN*} unur_test_timing (UNUR_PAR* @var{parameters}, int @var{log10_samplesize}, double* @var{time_setup}, double* @var{time_sample}, int @var{verbosity}, FILE* @var{out})
Timing. @var{parameters} is an parameter object for which setup
time and marginal generation times have to be measured. The results
are written into @var{time_setup} and @var{time_sample},
respectively. @var{log10_samplesize} is the common logarithm of the
sample size that is used for timing.

If @var{verbosity} is @code{TRUE} then a small table is printed to
output stream @var{out} with setup time, marginal generation time and
average generation times for generating 10, 100, @dots{} random
variates. All times are given in micro seconds and relative to
the generation times for the underlying uniform random number
(using the UNIF interface) and an exponential distributed
random variate using the inversion method.

The created generator object is returned.
If a generator object could not be created successfully, then @code{NULL}
is returned.

If @var{verbosity} is @code{TRUE} the result is written to the output
stream @var{out}.

Notice: All timing results are subject to heavy changes. Reruning
timings usually results in different results. Minor changes in
the source code can cause changes in such timings up to 25 percent.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_test_timing_R}
@deftypefn Function {double} unur_test_timing_R (UNUR_PAR* @var{parameters}, const @var{char* distrstr}, const @var{char* methodstr}, double @var{log10_samplesize}, double* @var{time_setup}, double* @var{time_marginal})
Timing. @var{parameters} is an parameter object for which setup
time and marginal generation times have to be measured. The results
are written into @var{time_setup} and @var{time_marginal},
respectively. @var{log10_samplesize} is the common logarithm of the
sample size that is used for timing.

Alternatively, one could provide the "parameter object" using
strings @var{distrstr} and @var{methodstr} as used for
@ifhtml
@ref{funct:unur_makegen_ssu,@command{unur_makegen_ssu}.}
@end ifhtml
@ifnothtml
@command{unur_makegen_ssu}.
@end ifnothtml
The results are more accurate than those of function
@ifhtml
@ref{funct:unur_test_timing,@command{unur_test_timing}}
@end ifhtml
@ifnothtml
@command{unur_test_timing}
@end ifnothtml
as the timings are computed using linear
regression with several timings for sample size 1 and
10^@var{log10_samplesize}.
For each sample size total generation time (including setup) is
measured 10 times. Since the these timings can be influenced by
external effects (like disc sync or handling of interupts) the 2
fastest and the 3 slowest timings are discarded.
Intercept and slope for simple linear regression are than stored
and
@math{R^2}
is returned.

In case of an error @code{-100.} is returned.

Notice: All timing results are subject to heavy changes. Reruning
timings usually results in different results. Minor changes in
the source code can cause changes in such timings up to 25 percent.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_test_timing_R}
@deftypefn {} {double} unur_test_timing_R (UNUR_PAR* @var{parameters}, const @var{char* distrstr}, const @var{char* methodstr}, double @var{log10_samplesize}, double* @var{time_setup}, double* @var{time_marginal})
Timing. @var{parameters} is an parameter object for which setup
time and marginal generation times have to be measured. The results
are written into @var{time_setup} and @var{time_marginal},
respectively. @var{log10_samplesize} is the common logarithm of the
sample size that is used for timing.

Alternatively, one could provide the "parameter object" using
strings @var{distrstr} and @var{methodstr} as used for
@ifhtml
@ref{funct:unur_makegen_ssu,@command{unur_makegen_ssu}.}
@end ifhtml
@ifnothtml
@command{unur_makegen_ssu}.
@end ifnothtml
The results are more accurate than those of function
@ifhtml
@ref{funct:unur_test_timing,@command{unur_test_timing}}
@end ifhtml
@ifnothtml
@command{unur_test_timing}
@end ifnothtml
as the timings are computed using linear
regression with several timings for sample size 1 and
10^@var{log10_samplesize}.
For each sample size total generation time (including setup) is
measured 10 times. Since the these timings can be influenced by
external effects (like disc sync or handling of interupts) the 2
fastest and the 3 slowest timings are discarded.
Intercept and slope for simple linear regression are than stored
and
@iftex
@math{R^2}
@end iftex
@ifhtml
@html
<I>R</I><SUP>2</SUP>
@end html
@end ifhtml
is returned.

In case of an error @code{-100.} is returned.

Notice: All timing results are subject to heavy changes. Reruning
timings usually results in different results. Minor changes in
the source code can cause changes in such timings up to 25 percent.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_test_timing_uniform}
@anchor{funct:unur_test_timing_exponential}
@deftypefn Function {double} unur_test_timing_uniform (const @var{UNUR_PAR* parameters}, int @var{log10_samplesize})
@deftypefnx Function {double} unur_test_timing_exponential (const @var{UNUR_PAR* parameters}, int @var{log10_samplesize})
Marginal generation times for the underlying uniform random number
(using the UNIF interface) and an exponential distributed
random variate using the inversion method. These times are used in
@ifhtml
@ref{funct:unur_test_timing,@command{unur_test_timing}}
@end ifhtml
@ifnothtml
@command{unur_test_timing}
@end ifnothtml
to compute the relative timings results.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_test_timing_uniform}
@anchor{funct:unur_test_timing_exponential}
@deftypefn {} {double} unur_test_timing_uniform (const @var{UNUR_PAR* parameters}, int @var{log10_samplesize})
@deftypefnx {} {double} unur_test_timing_exponential (const @var{UNUR_PAR* parameters}, int @var{log10_samplesize})
Marginal generation times for the underlying uniform random number
(using the UNIF interface) and an exponential distributed
random variate using the inversion method. These times are used in
@ifhtml
@ref{funct:unur_test_timing,@command{unur_test_timing}}
@end ifhtml
@ifnothtml
@command{unur_test_timing}
@end ifnothtml
to compute the relative timings results.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_test_timing_total}
@deftypefn Function {double} unur_test_timing_total (const @var{UNUR_PAR* parameters}, int @var{samplesize}, double @var{avg_duration})
Timing. @var{parameters} is an parameter object for which average
times a sample of size @var{samplesize} (including setup) are
estimated. Thus sampling is repeated and the median of these timings
is returned (in micro seconds). The number of iterations is computed
automatically such that the total amount of time necessary for the
test ist approximately @var{avg_duration} (given in seconds).
However, for very slow generator with expensive setup time the time
necessary for this test may be (much) larger.

If an error occurs then @code{-1} is returned.

Notice: All timing results are subject to heavy changes. Reruning
timings usually results in different results. Minor changes in
the source code can cause changes in such timings up to 25 percent.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_test_timing_total}
@deftypefn {} {double} unur_test_timing_total (const @var{UNUR_PAR* parameters}, int @var{samplesize}, double @var{avg_duration})
Timing. @var{parameters} is an parameter object for which average
times a sample of size @var{samplesize} (including setup) are
estimated. Thus sampling is repeated and the median of these timings
is returned (in micro seconds). The number of iterations is computed
automatically such that the total amount of time necessary for the
test ist approximately @var{avg_duration} (given in seconds).
However, for very slow generator with expensive setup time the time
necessary for this test may be (much) larger.

If an error occurs then @code{-1} is returned.

Notice: All timing results are subject to heavy changes. Reruning
timings usually results in different results. Minor changes in
the source code can cause changes in such timings up to 25 percent.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_test_count_urn}
@deftypefn Function {int} unur_test_count_urn (UNUR_GEN* @var{generator}, int @var{samplesize}, int @var{verbosity}, FILE* @var{out})
Count used uniform random numbers. It returns the total number of
uniform random numbers required for a sample of non-uniform random
variates of size @var{samplesize}. In case of an error @code{-1}
is returned.

If @var{verbosity} is @code{TRUE} the result is written to the output
stream @var{out}.

@emph{Notice:} This test uses global variables to store
counters. Thus it is not thread save.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_test_count_urn}
@deftypefn {} {int} unur_test_count_urn (UNUR_GEN* @var{generator}, int @var{samplesize}, int @var{verbosity}, FILE* @var{out})
Count used uniform random numbers. It returns the total number of
uniform random numbers required for a sample of non-uniform random
variates of size @var{samplesize}. In case of an error @code{-1}
is returned.

If @var{verbosity} is @code{TRUE} the result is written to the output
stream @var{out}.

@emph{Notice:} This test uses global variables to store
counters. Thus it is not thread save.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_test_count_pdf}
@deftypefn Function {int} unur_test_count_pdf (UNUR_GEN* @var{generator}, int @var{samplesize}, int @var{verbosity}, FILE* @var{out})
Count evaluations of PDF and similar functions. It returns the
total number of evaluations of all such functions required for a
sample of non-uniform random variates of size @var{samplesize}.
If @var{verbosity} is @code{TRUE} then a more detailed report is printed
to the output stream @var{out}.
In case of an error @code{-1} is returned.
This test is run on a copy of the given generator object.

@emph{Notice:} The printed numbers of evaluation should be interpreted
with care. For example, methods either use the PDF or the logPDF;
if only the logPDF is given, but a method needs the PDF then both
the logPDF and the PDF (a wrapper around the logPDF) are called and
thus one call to the PDF is counted twice.

@emph{Notice:} This test uses global variables to store function
pointers and counters. Thus it is not thread save.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_test_count_pdf}
@deftypefn {} {int} unur_test_count_pdf (UNUR_GEN* @var{generator}, int @var{samplesize}, int @var{verbosity}, FILE* @var{out})
Count evaluations of PDF and similar functions. It returns the
total number of evaluations of all such functions required for a
sample of non-uniform random variates of size @var{samplesize}.
If @var{verbosity} is @code{TRUE} then a more detailed report is printed
to the output stream @var{out}.
In case of an error @code{-1} is returned.
This test is run on a copy of the given generator object.

@emph{Notice:} The printed numbers of evaluation should be interpreted
with care. For example, methods either use the PDF or the logPDF;
if only the logPDF is given, but a method needs the PDF then both
the logPDF and the PDF (a wrapper around the logPDF) are called and
thus one call to the PDF is counted twice.

@emph{Notice:} This test uses global variables to store function
pointers and counters. Thus it is not thread save.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_test_par_count_pdf}
@deftypefn Function {int} unur_test_par_count_pdf (UNUR_PAR* @var{parameters}, int @var{samplesize}, int @var{verbosity}, FILE* @var{out})
Same as
@ifhtml
@ref{funct:unur_test_count_pdf,@command{unur_test_count_pdf}}
@end ifhtml
@ifnothtml
@command{unur_test_count_pdf}
@end ifnothtml
except that it is run on a parameter
object. Thus it also prints the number of function evaluations for
the setup. The temporary created generator object is destroyed
before the results are returned.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_test_par_count_pdf}
@deftypefn {} {int} unur_test_par_count_pdf (UNUR_PAR* @var{parameters}, int @var{samplesize}, int @var{verbosity}, FILE* @var{out})
Same as
@ifhtml
@ref{funct:unur_test_count_pdf,@command{unur_test_count_pdf}}
@end ifhtml
@ifnothtml
@command{unur_test_count_pdf}
@end ifnothtml
except that it is run on a parameter
object. Thus it also prints the number of function evaluations for
the setup. The temporary created generator object is destroyed
before the results are returned.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_test_chi2}
@deftypefn Function {double} unur_test_chi2 (UNUR_GEN* @var{generator}, int @var{intervals}, int @var{samplesize}, int @var{classmin}, int @var{verbosity}, FILE* @var{out})
Run a Chi^2 test with the @var{generator}.
The resulting p-value is returned.

It works with discrete und continuous univariate distributions.
For the latter the CDF of the distribution is required.

@var{intervals} is the number of intervals that is used for
continuous univariate distributions. @var{samplesize} is the size
of the sample that is used for testing. If it is set to @code{0}
then a sample of size @var{intervals}^2 is used (bounded to some
upper bound).

@var{classmin} is the minimum number of expected entries per
class. If a class has to few entries then some classes are joined.

@var{verbosity} controls the output of the routine. If it is set
to @code{1} then the result is written to the output stream
@var{out}. If it is set to @code{2} additionally the list of
expected and observed data is printed.
If it is set to @code{3} then all generated numbers are printed.
There is no output when it is set to @code{0}.

@emph{Notice:} For multivariate distributions the generated points
are transformed by the inverse of the Cholesky factor of the
covariance matrix and the mean vectors (if given for the underlying
distribution). The marginal distributions of the transformed
vectors are then tested against the marginal distribution given by
a
@ifhtml
@ref{funct:unur_distr_cvec_set_marginals,@command{unur_distr_cvec_set_marginals}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_marginals}
@end ifnothtml
or
@ifhtml
@ref{funct:unur_distr_cvec_set_marginal_array,@command{unur_distr_cvec_set_marginal_array}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_marginal_array}
@end ifnothtml
call.
(Notice that these marginal distributions are never set by default
for any of the distributions provided by UNU.RAN.)
Then the Bonferroni corrected p-value of all these tests is returned.
However, the test may not be performed correctly if the domain of the
underlying distribution is truncated by a
@ifhtml
@ref{funct:unur_distr_cvec_set_domain_rect,@command{unur_distr_cvec_set_domain_rect}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_domain_rect}
@end ifnothtml
call and the components of the
distribution are correlated (i.e.
@ifhtml
@ref{funct:unur_distr_cvec_set_covar,@command{unur_distr_cvec_set_covar}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_covar}
@end ifnothtml
is
called with the non-NULL argument). Then it almost surely will fail.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_test_chi2}
@deftypefn {} {double} unur_test_chi2 (UNUR_GEN* @var{generator}, int @var{intervals}, int @var{samplesize}, int @var{classmin}, int @var{verbosity}, FILE* @var{out})
Run a Chi^2 test with the @var{generator}.
The resulting p-value is returned.

It works with discrete und continuous univariate distributions.
For the latter the CDF of the distribution is required.

@var{intervals} is the number of intervals that is used for
continuous univariate distributions. @var{samplesize} is the size
of the sample that is used for testing. If it is set to @code{0}
then a sample of size @var{intervals}^2 is used (bounded to some
upper bound).

@var{classmin} is the minimum number of expected entries per
class. If a class has to few entries then some classes are joined.

@var{verbosity} controls the output of the routine. If it is set
to @code{1} then the result is written to the output stream
@var{out}. If it is set to @code{2} additionally the list of
expected and observed data is printed.
If it is set to @code{3} then all generated numbers are printed.
There is no output when it is set to @code{0}.

@emph{Notice:} For multivariate distributions the generated points
are transformed by the inverse of the Cholesky factor of the
covariance matrix and the mean vectors (if given for the underlying
distribution). The marginal distributions of the transformed
vectors are then tested against the marginal distribution given by
a
@ifhtml
@ref{funct:unur_distr_cvec_set_marginals,@command{unur_distr_cvec_set_marginals}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_marginals}
@end ifnothtml
or
@ifhtml
@ref{funct:unur_distr_cvec_set_marginal_array,@command{unur_distr_cvec_set_marginal_array}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_marginal_array}
@end ifnothtml
call.
(Notice that these marginal distributions are never set by default
for any of the distributions provided by UNU.RAN.)
Then the Bonferroni corrected p-value of all these tests is returned.
However, the test may not be performed correctly if the domain of the
underlying distribution is truncated by a
@ifhtml
@ref{funct:unur_distr_cvec_set_domain_rect,@command{unur_distr_cvec_set_domain_rect}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_domain_rect}
@end ifnothtml
call and the components of the
distribution are correlated (i.e.
@ifhtml
@ref{funct:unur_distr_cvec_set_covar,@command{unur_distr_cvec_set_covar}}
@end ifhtml
@ifnothtml
@command{unur_distr_cvec_set_covar}
@end ifnothtml
is
called with the non-NULL argument). Then it almost surely will fail.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_test_moments}
@deftypefn Function {int} unur_test_moments (UNUR_GEN* @var{generator}, double* @var{moments}, int @var{n_moments}, int @var{samplesize}, int @var{verbosity}, FILE* @var{out})
Computes the first @var{n_moments} central moments for a sample of
size @var{samplesize}. The result is stored into the array
@var{moments}.
@var{n_moments} must be an integer between @code{1} and @code{4}.
For multivariate distributions the moments are stored consecutively
for each dimension and the provided @var{moments}-array must have
a length of at least (@var{n_moments}+1) * @var{dim}, where @var{dim}
is the dimension of the multivariate distribution.
The @var{m}'th moment for the @var{d}'th dimension (0<=@var{d}<@var{dim})
is thus stored in the array element
@var{moments}[@var{d}*@var{n_moments}+@var{m}]

If @var{verbosity} is @code{TRUE} the result is written to the output
stream @var{out}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_test_moments}
@deftypefn {} {int} unur_test_moments (UNUR_GEN* @var{generator}, double* @var{moments}, int @var{n_moments}, int @var{samplesize}, int @var{verbosity}, FILE* @var{out})
Computes the first @var{n_moments} central moments for a sample of
size @var{samplesize}. The result is stored into the array
@var{moments}.
@var{n_moments} must be an integer between @code{1} and @code{4}.
For multivariate distributions the moments are stored consecutively
for each dimension and the provided @var{moments}-array must have
a length of at least (@var{n_moments}+1) * @var{dim}, where @var{dim}
is the dimension of the multivariate distribution.
The @var{m}'th moment for the @var{d}'th dimension (0<=@var{d}<@var{dim})
is thus stored in the array element
@var{moments}[@var{d}*@var{n_moments}+@var{m}]

If @var{verbosity} is @code{TRUE} the result is written to the output
stream @var{out}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_test_correlation}
@deftypefn Function {double} unur_test_correlation (UNUR_GEN* @var{generator1}, UNUR_GEN* @var{generator2}, int @var{samplesize}, int @var{verbosity}, FILE* @var{out})
Compute the correlation coefficient between streams from
@var{generator1} and @var{generator2} for two samples of size
@var{samplesize}.
The resultung correlation is returned.

If @var{verbosity} is @code{TRUE} the result is written to the output
stream @var{out}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_test_correlation}
@deftypefn {} {double} unur_test_correlation (UNUR_GEN* @var{generator1}, UNUR_GEN* @var{generator2}, int @var{samplesize}, int @var{verbosity}, FILE* @var{out})
Compute the correlation coefficient between streams from
@var{generator1} and @var{generator2} for two samples of size
@var{samplesize}.
The resultung correlation is returned.

If @var{verbosity} is @code{TRUE} the result is written to the output
stream @var{out}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_test_quartiles}
@deftypefn Function {int} unur_test_quartiles (UNUR_GEN* @var{generator}, double* @var{q0}, double* @var{q1}, double* @var{q2}, double* @var{q3}, double* @var{q4}, int @var{samplesize}, int @var{verbosity}, FILE* @var{out})
Estimate quartiles of sample of size @var{samplesize}.
The resulting quantiles are stored in the variables @var{q}:
@table @var
@item q0
minimum
@item q1
25%
@item q2
median (50%)
@item q3
75%
@item q4
maximum
@end table

If @var{verbosity} is @code{TRUE} the result is written to the output
stream @var{out}.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_test_quartiles}
@deftypefn {} {int} unur_test_quartiles (UNUR_GEN* @var{generator}, double* @var{q0}, double* @var{q1}, double* @var{q2}, double* @var{q3}, double* @var{q4}, int @var{samplesize}, int @var{verbosity}, FILE* @var{out})
Estimate quartiles of sample of size @var{samplesize}.
The resulting quantiles are stored in the variables @var{q}:
@table @var
@item q0
minimum
@item q1
25%
@item q2
median (50%)
@item q3
75%
@item q4
maximum
@end table

If @var{verbosity} is @code{TRUE} the result is written to the output
stream @var{out}.
@end deftypefn
@end ifnotinfo

@ifinfo
@anchor{funct:unur_test_u_error}
@deftypefn Function {double} unur_test_u_error (const @var{UNUR_GEN* generator}, double* @var{max_error}, double* @var{MAE}, double @var{threshold}, int @var{samplesize}, int @var{randomized}, int @var{testtails}, int @var{verbosity}, FILE* @var{out})
Estimate U-error of an inversion method, i.e.
@math{error = | CDF^(-1)(U) - U |}
, by means of a simple Monte
Carlo method.
Maximum and mean absolute errors are stored in @var{max_error} and
@var{MAE}, respectively.
The particular computed U-errors should not exceed the given
@var{threshold}. However, approximization and round-off errors
might occasionally trigger such an event.
Thus the function returns a penalty score. It is @code{0.} when the
U-error never exceed the @var{threshold} value. It roughly gives the
portion of particular test points where the U-error is too larger.
However, each such event is weighted with
@math{1 + 10 x(uerror - threshold) / threshold}
.

If @var{randomized} is @code{TRUE} a pseudo-random sequence is used for
the estimation.

If @var{randomized} is @code{FALSE} then the U-values are choosen
equidistributed.
If in addition @var{randomized} is set to @code{TRUE} then the tails of
the distributions are tested with a more dense set of points.

If @var{verbosity} is @code{TRUE} the result is written to the output
stream @var{out}.

When the domain of the distribution is truncated then the u-error
might be larger due to rescaling of floating point numbers. Thus
the observed u-errors are corrected by the corresponding rescaling
factor.

The test also works for discrete distributions albeit with some
restrictions:
It does not work correctly with truncated distributions and the
@var{testtails} flag is ignored.
Moreover, the value stored in @var{MAE} is rather useless.

In case of an error a negative value is returned.
@end deftypefn
@end ifinfo
@ifnotinfo
@anchor{funct:unur_test_u_error}
@deftypefn {} {double} unur_test_u_error (const @var{UNUR_GEN* generator}, double* @var{max_error}, double* @var{MAE}, double @var{threshold}, int @var{samplesize}, int @var{randomized}, int @var{testtails}, int @var{verbosity}, FILE* @var{out})
Estimate U-error of an inversion method, i.e.
@iftex
@math{error = | CDF^{-1}(U) - U |}
@end iftex
@ifhtml
@html
<I>error</I> = | <I>CDF</I><SUP>-1</SUP>(<I>U</I>) - <I>U</I> |
@end html
@end ifhtml
, by means of a simple Monte
Carlo method.
Maximum and mean absolute errors are stored in @var{max_error} and
@var{MAE}, respectively.
The particular computed U-errors should not exceed the given
@var{threshold}. However, approximization and round-off errors
might occasionally trigger such an event.
Thus the function returns a penalty score. It is @code{0.} when the
U-error never exceed the @var{threshold} value. It roughly gives the
portion of particular test points where the U-error is too larger.
However, each such event is weighted with
@iftex
@math{1 + 10 \times (uerror - threshold) / threshold}
@end iftex
@ifhtml
@html
1 + 10 x(<I>uerror</I> - <I>threshold</I>) / <I>threshold</I>
@end html
@end ifhtml
.

If @var{randomized} is @code{TRUE} a pseudo-random sequence is used for
the estimation.

If @var{randomized} is @code{FALSE} then the U-values are choosen
equidistributed.
If in addition @var{randomized} is set to @code{TRUE} then the tails of
the distributions are tested with a more dense set of points.

If @var{verbosity} is @code{TRUE} the result is written to the output
stream @var{out}.

When the domain of the distribution is truncated then the u-error
might be larger due to rescaling of floating point numbers. Thus
the observed u-errors are corrected by the corresponding rescaling
factor.

The test also works for discrete distributions albeit with some
restrictions:
It does not work correctly with truncated distributions and the
@var{testtails} flag is ignored.
Moreover, the value stored in @var{MAE} is rather useless.

In case of an error a negative value is returned.
@end deftypefn
@end ifnotinfo




@c
@c end of unuran_tests.h
@c -------------------------------------
@c -------------------------------------
@c misc.dh
@c

@node Misc
@chapter   Miscelleanous

@menu
* Math:: Mathematics
@end menu


@c
@c end of misc.dh
@c -------------------------------------
@c -------------------------------------
@c umath.h
@c

@node Math
@section   Mathematics


The following macros have been defined

@ftable @code
@item UNUR_INFINITY
indicates infinity for floating point numbers (of type @code{double}).
Internally @code{HUGE_VAL} is used.

@item INT_MAX
@itemx INT_MIN
indicate infinity and minus infinity, resp., for integers
(defined by ISO C standard).

@item  @code{TRUE}
@itemx @code{FALSE}
bolean expression for return values of @code{set} functions.
@end ftable


@c
@c end of umath.h
@c -------------------------------------
@c -------------------------------------
@c arvag.dh
@c

@node RVG
@appendix   A Short Introduction to Random Variate Generation

@menu
* Inversion:: The Inversion Method
* Rejection:: The Rejection Method
* Composition:: The Composition Method
* Ratio-of-Uniforms:: The Ratio-of-Uniforms Method
* DiscreteInversion:: Inversion for Discrete Distributions
* IndexedSearch:: Indexed Search (Guide Table Method)
@end menu



Random variate generation is the small field of research that deals
with algorithms to generate random variates from various
distributions. It is common to assume that a uniform random number
generator is available. This is a program that produces a sequence
of independent and identically  distributed continuous
@iftex
@math{U(0,1)}
@end iftex
@ifhtml
@html
<I>U</I>(0,1)
@end html
@end ifhtml
@ifinfo
@math{U(0,1)}
@end ifinfo
random variates (i.e. uniform random variates
on the interval
@iftex
@math{(0,1)}
@end iftex
@ifhtml
@html
(0,1)
@end html
@end ifhtml
@ifinfo
@math{(0,1)}
@end ifinfo
). Of course real world computers can
never generate ideal random numbers and they cannot produce numbers
of arbitrary precision but state-of-the-art uniform random number
generators come close to this aim. Thus random variate generation
deals with the problem of transforming such a sequence of
@iftex
@math{U(0,1)}
@end iftex
@ifhtml
@html
<I>U</I>(0,1)
@end html
@end ifhtml
@ifinfo
@math{U(0,1)}
@end ifinfo
random numbers into non-uniform random variates.

Here we shortly explain the basic ideas of the @emph{inversion},
@emph{rejection}, and the @emph{ratio of uniforms} method. How
these ideas can be used to design a particular automatic random
variate generation algorithms that can be applied to large classes
of distributions is shortly explained in the description of the
different methods included in this manual.

For a deeper treatment of the ideas presented here, for other
basic methods and for automatic generators we refer the interested
reader to our book [HLD04].



@c
@c end of arvag.dh
@c -------------------------------------
@c -------------------------------------
@c arvag.dh
@c

@node Inversion
@section   The Inversion Method



When the inverse
@iftex
@math{F^{-1}}
@end iftex
@ifhtml
@html
<I>F</I><SUP>-1</SUP>
@end html
@end ifhtml
@ifinfo
@math{F^(-1)}
@end ifinfo
of the cumulative distribution
function is known, then random variate generation is easy.
We just generate a uniformly
@iftex
@math{U(0,1)}
@end iftex
@ifhtml
@html
<I>U</I>(0,1)
@end html
@end ifhtml
@ifinfo
@math{U(0,1)}
@end ifinfo
distributed random
number
@iftex
@math{U}
@end iftex
@ifhtml
@html
<I>U</I>
@end html
@end ifhtml
@ifinfo
@math{U}
@end ifinfo
and return
@iftex

@quotation
@math{X=F^{-1}(U).}
@end quotation

@end iftex
@ifhtml
@quotation
@html
<I>X</I>=<I>F</I><SUP>-1</SUP>(<I>U</I>).
@end html
@end quotation
@end ifhtml
@ifinfo
@quotation
@math{X=F^(-1)(U).}
@end quotation
@end ifinfo

@noindent
The following figure shows how the inversion method works for
the exponential distribution.


@image{figures/inversion}



This algorithm is so simple that inversion is certainly the method
of choice if the inverse CDF is available in closed form. This is
the case e.g. for the exponential and the Cauchy distribution.

The inversion method also has other special advantages that make it
even more attractive for simulation purposes.
It preserves the structural properties of the underlying uniform
pseudo-random number generator.
Consequently it can be used, e.g., for variance reduction techniques,
it is easy to sample from truncated distributions, from marginal
distributions, and from order statistics.
Moreover, the quality of the generated random variables depends only
on the underlying uniform (pseudo-) random number generator.
Another important advantage of the inversion method is that we can
easily characterize its performance. To generate one random variate
we always need exactly one uniform variate and one evaluation of
the inverse CDF. So its speed mainly depends on the costs for
evaluating the inverse CDF. Hence inversion is often considered as
the method of choice in the simulation literature.

Unfortunately computing the inverse CDF is, for many important
standard distributions (e.g. for normal, student, gamma, and
beta-distributions), comparatively difficult and slow. Often no
such routines are available in standard programming libraries.
Then numerical methods for inverting the CDF are necessary, e.g.
Newton's method or (polynomial or rational) approximations of the
inverse CDF. Such procedures, however, have the disadvantage that
they are not exact and/or slow.
UNU.RAN implements several methods:
NINV (@pxref{NINV}), HINV (@pxref{HINV}) and PINV (@pxref{PINV}).

For such approximate inversion methods the approximation error is
important for the quality of the generated point set.
Let
@iftex
@math{X=G^{-1}(U)}
@end iftex
@ifhtml
@html
<I>X</I>=<I>G</I><SUP>-1</SUP>(<I>U</I>)
@end html
@end ifhtml
@ifinfo
@math{X=G^(-1)(U)}
@end ifinfo
denote the approximate inverse CDF,
and let
@iftex
@math{F}
@end iftex
@ifhtml
@html
<I>F</I>
@end html
@end ifhtml
@ifinfo
@math{F}
@end ifinfo
and
@iftex
@math{F^{-1}}
@end iftex
@ifhtml
@html
<I>F</I><SUP>-1</SUP>
@end html
@end ifhtml
@ifinfo
@math{F^(-1)}
@end ifinfo
be the exact CDF and
inverse CDF of the distribution, resp.
There are three measures for the approximation error:

@table @emph
@item u-error
is given by
@iftex

@quotation
@math{uerror = |U-F(G^{-1}(U))|}
@end quotation

@end iftex
@ifhtml
@quotation
@html
<I>uerror</I> = |<I>U</I>-<I>F</I>(<I>G</I><SUP>-1</SUP>(<I>U</I>))|
@end html
@end quotation
@end ifhtml
@ifinfo
@quotation
@math{uerror = |U-F(G^(-1)(U))|}
@end quotation
@end ifinfo

@noindent
Goodness-of-fit tests like the Kolmogorov-Smirnov test or the
chi-squared test look at this type of error.
We are also convinced that it is the most suitable error measure for
Monte Carlo simulations as pseudo-random numbers and points of low
discrepancy sets are located on a grid of restricted resolution.

@item x-error
is given by
@iftex

@quotation
@math{absolute xerror = |F^{-1}(U)-G^{-1}(U)|}
@end quotation

@end iftex
@ifhtml
@quotation
@html
<I>absolute</I> <I>xerror</I> = |<I>F</I><SUP>-1</SUP>(<I>U</I>)-<I>G</I><SUP>-1</SUP>(<I>U</I>)|
@end html
@end quotation
@end ifhtml
@ifinfo
@quotation
@math{absolute xerror = |F^(-1)(U)-G^(-1)(U)|}
@end quotation
@end ifinfo

@noindent
@iftex

@quotation
@math{relative xerror = |F^{-1}(U)-G^{-1}(U)|\cdot |F^{-1}(U)|}
@end quotation

@end iftex
@ifhtml
@quotation
@html
<I>relative</I> <I>xerror</I> = |<I>F</I><SUP>-1</SUP>(<I>U</I>)-<I>G</I><SUP>-1</SUP>(<I>U</I>)| * |<I>F</I><SUP>-1</SUP>(<I>U</I>)|
@end html
@end quotation
@end ifhtml
@ifinfo
@quotation
@math{relative xerror = |F^(-1)(U)-G^(-1)(U)| * |F^(-1)(U)|}
@end quotation
@end ifinfo

@noindent
The x-error measure the deviation of
@iftex
@math{G^{-1}(U)}
@end iftex
@ifhtml
@html
<I>G</I><SUP>-1</SUP>(<I>U</I>)
@end html
@end ifhtml
@ifinfo
@math{G^(-1)(U)}
@end ifinfo
from the exact result. This measure is suitable when the inverse
CDF is used as a quantile function in some computations.
The main problem with the x-error is that we have to use the
@emph{absolute x-error} for
@iftex
@math{X=F^{-1}(U)}
@end iftex
@ifhtml
@html
<I>X</I>=<I>F</I><SUP>-1</SUP>(<I>U</I>)
@end html
@end ifhtml
@ifinfo
@math{X=F^(-1)(U)}
@end ifinfo
close to zero
and the @emph{relative x-error} in the tails.

@end table

We use the terms @emph{u-resolution} and @emph{x-resolution} as the
maximal tolerated u-error and x-error, resp.

UNU.RAN allows to set u-resolution and x-resolution
independently. Both requirements must be fulfilled.
We use the following strategy for checking whether the
precision goal is reached:

@table @emph
@item checking u-error:
The u-error must be slightly smaller than the given u-resolution:
@iftex

@quotation
@math{|U-F(G^{-1}(U))| < 0.9\cdot uresolution.}
@end quotation

@end iftex
@ifhtml
@quotation
@html
|<I>U</I>-<I>F</I>(<I>G</I><SUP>-1</SUP>(<I>U</I>))| < 0.9 * <I>uresolution</I>.
@end html
@end quotation
@end ifhtml
@ifinfo
@quotation
@math{|U-F(G^(-1)(U))| < 0.9 * uresolution.}
@end quotation
@end ifinfo

@noindent
There is no necessity to consinder the relative u-error as we have
@iftex
@math{0 < U < 1.}
@end iftex
@ifhtml
@html
0 < <I>U</I> < 1.
@end html
@end ifhtml
@ifinfo
@math{0 < U < 1.}
@end ifinfo

@item checking x-error:
We combine absoute and relative x-error and use the criterion
@iftex

@quotation
@math{|F^{-1}(U)-G^{-1}(U)| < xresolution \cdot (|G^{-1}(U)| + xresolution).}
@end quotation

@end iftex
@ifhtml
@quotation
@html
|<I>F</I><SUP>-1</SUP>(<I>U</I>)-<I>G</I><SUP>-1</SUP>(<I>U</I>)| < <I>xresolution</I> * (|<I>G</I><SUP>-1</SUP>(<I>U</I>)| + <I>xresolution</I>).
@end html
@end quotation
@end ifhtml
@ifinfo
@quotation
@math{|F^(-1)(U)-G^(-1)(U)| < xresolution * (|G^(-1)(U)| + xresolution).}
@end quotation
@end ifinfo

@noindent
@end table

@strong{Remark:}
It should be noted here that the criterion based on the u-error is
too stringent whereever the CDF is extremely steep (and thus the
PDF has a pole or a high and narrow peak). This is in particular a
problem for distributions with a pole (e.g., the gamma distribution
with shape parameter less than 0.5).
On the other hand using a criterion based on the x-error causes
problems whereever the CDF is extremly flat. This is in particular
the case in the (far) tails of heavy-tailed distributions (e.g.,
for the Cauchy distribution).



@c
@c end of arvag.dh
@c -------------------------------------
@c -------------------------------------
@c arvag.dh
@c

@node Rejection
@section   The Rejection Method



The rejection method, often called @emph{acceptance-rejection
method}, has been suggested by John von Neumann in 1951.
Since then it has proven to be the most flexible and most efficient
method to generate variates from continuous distributions.

We explain the rejection principle first for the density
@iftex
@math{f(x) = sin(x)/2}
@end iftex
@ifhtml
@html
<I>f</I>(<I>x</I>) = <I>sin</I>(<I>x</I>)/2
@end html
@end ifhtml
@ifinfo
@math{f(x) = sin(x)/2}
@end ifinfo
on the interval
@iftex
@math{(0,\pi).}
@end iftex
@ifhtml
@html
(0, pi).
@end html
@end ifhtml
@ifinfo
@math{(0, pi).}
@end ifinfo
To generate random variates from this distribution we also can
sample random points that are uniformly distributed in the region
between the graph of
@iftex
@math{f(x)}
@end iftex
@ifhtml
@html
<I>f</I>(<I>x</I>)
@end html
@end ifhtml
@ifinfo
@math{f(x)}
@end ifinfo
and the @i{x}-axis,
i.e., the shaded region in the below figure.


@image{figures/rejection_from_constant_hat}



In general this is not a trivial task but in this example we can
easily use the rejection trick:
Sample a random point
@iftex
@math{(X,Y)}
@end iftex
@ifhtml
@html
(<I>X</I>,<I>Y</I>)
@end html
@end ifhtml
@ifinfo
@math{(X,Y)}
@end ifinfo
uniformly in the
bounding rectangle
@iftex
@math{(0,\pi)\times(0,0.5).}
@end iftex
@ifhtml
@html
(0, pi)x(0,0.5).
@end html
@end ifhtml
@ifinfo
@math{(0, pi)x(0,0.5).}
@end ifinfo
This is easy since
each coordinate can be sampled independently from the respective
uniform distributions
@iftex
@math{U(0,\pi)}
@end iftex
@ifhtml
@html
<I>U</I>(0, pi)
@end html
@end ifhtml
@ifinfo
@math{U(0, pi)}
@end ifinfo
and
@iftex
@math{U(0,0.5).}
@end iftex
@ifhtml
@html
<I>U</I>(0,0.5).
@end html
@end ifhtml
@ifinfo
@math{U(0,0.5).}
@end ifinfo
Whenever the point falls into the shaded region below the graph
(indicated by dots in the figure), i.e., when
@iftex
@math{Y < sin(X)/2,}
@end iftex
@ifhtml
@html
<I>Y</I> < <I>sin</I>(<I>X</I>)/2,
@end html
@end ifhtml
@ifinfo
@math{Y < sin(X)/2,}
@end ifinfo
we accept it and return
@iftex
@math{X}
@end iftex
@ifhtml
@html
<I>X</I>
@end html
@end ifhtml
@ifinfo
@math{X}
@end ifinfo
as a random variate
from the distribution with density
@iftex
@math{f(x).}
@end iftex
@ifhtml
@html
<I>f</I>(<I>x</I>).
@end html
@end ifhtml
@ifinfo
@math{f(x).}
@end ifinfo
Otherwise we have to reject the point (indicated by small circles
in the figure), and try again.

It is quite clear that this idea works for every distribution with
a bounded density on a bounded domain. Moreover, we can use this
procedure with any multiple of the density, i.e., with any positive
bounded function with bounded integral and it is not necessary to
know the integral of this function. So we use the term density in
the sequel for any positive function with bounded integral.

From the figure we can conclude that the performance of a rejection
algorithm depends heavily on the area of the enveloping
rectangle. Moreover, the method does not work if the target
distribution has infinite tails (or is unbounded). Hence
non-rectangular shaped regions for the envelopes are important and
we have to solve the problem of sampling points uniformly from such
domains. Looking again at the example above we notice that the
@i{x}-coordinate of the random point
@iftex
@math{(X,Y)}
@end iftex
@ifhtml
@html
(<I>X</I>,<I>Y</I>)
@end html
@end ifhtml
@ifinfo
@math{(X,Y)}
@end ifinfo
was
sampled by inversion from the uniform distribution on the domain of
the given density. This motivates us to replace the density of the
uniform distribution by the (multiple of a) density
@iftex
@math{h(x)}
@end iftex
@ifhtml
@html
<I>h</I>(<I>x</I>)
@end html
@end ifhtml
@ifinfo
@math{h(x)}
@end ifinfo
of some other appropriate distribution. We only have to take care
that it is chosen such that it is always an upper bound, i.e.,
@iftex
@math{h(x)\geq f(x)}
@end iftex
@ifhtml
@html
<I>h</I>(<I>x</I>) >= <I>f</I>(<I>x</I>)
@end html
@end ifhtml
@ifinfo
@math{h(x) >= f(x)}
@end ifinfo
for all
@iftex
@math{x}
@end iftex
@ifhtml
@html
<I>x</I>
@end html
@end ifhtml
@ifinfo
@math{x}
@end ifinfo
in the domain of the
distribution. To generate the pair
@iftex
@math{(X,Y)}
@end iftex
@ifhtml
@html
(<I>X</I>,<I>Y</I>)
@end html
@end ifhtml
@ifinfo
@math{(X,Y)}
@end ifinfo
we generate
@iftex
@math{X}
@end iftex
@ifhtml
@html
<I>X</I>
@end html
@end ifhtml
@ifinfo
@math{X}
@end ifinfo
from the distribution with density proportional to
@iftex
@math{h(x)}
@end iftex
@ifhtml
@html
<I>h</I>(<I>x</I>)
@end html
@end ifhtml
@ifinfo
@math{h(x)}
@end ifinfo
and
@iftex
@math{Y}
@end iftex
@ifhtml
@html
<I>Y</I>
@end html
@end ifhtml
@ifinfo
@math{Y}
@end ifinfo
uniformly between
@iftex
@math{0}
@end iftex
@ifhtml
@html
0
@end html
@end ifhtml
@ifinfo
@math{0}
@end ifinfo
and
@iftex
@math{h(X).}
@end iftex
@ifhtml
@html
<I>h</I>(<I>X</I>).
@end html
@end ifhtml
@ifinfo
@math{h(X).}
@end ifinfo
The first step (generate
@iftex
@math{X}
@end iftex
@ifhtml
@html
<I>X</I>
@end html
@end ifhtml
@ifinfo
@math{X}
@end ifinfo
) is usually
done by inversion (@pxref{Inversion}).

Thus the general rejection algorithm for a hat
@iftex
@math{h(x)}
@end iftex
@ifhtml
@html
<I>h</I>(<I>x</I>)
@end html
@end ifhtml
@ifinfo
@math{h(x)}
@end ifinfo
with
inverse CDF
@iftex
@math{H^{-1}}
@end iftex
@ifhtml
@html
<I>H</I><SUP>-1</SUP>
@end html
@end ifhtml
@ifinfo
@math{H^(-1)}
@end ifinfo
consists of the following steps:
@enumerate
@item
Generate a
@iftex
@math{U(0,1)}
@end iftex
@ifhtml
@html
<I>U</I>(0,1)
@end html
@end ifhtml
@ifinfo
@math{U(0,1)}
@end ifinfo
random number
@iftex
@math{U.}
@end iftex
@ifhtml
@html
<I>U</I>.
@end html
@end ifhtml
@ifinfo
@math{U.}
@end ifinfo
@item
Set
@iftex
@math{X}
@end iftex
@ifhtml
@html
<I>X</I>
@end html
@end ifhtml
@ifinfo
@math{X}
@end ifinfo
to
@iftex
@math{H^{-1}(U).}
@end iftex
@ifhtml
@html
<I>H</I><SUP>-1</SUP>(<I>U</I>).
@end html
@end ifhtml
@ifinfo
@math{H^(-1)(U).}
@end ifinfo
@item
Generate a
@iftex
@math{U(0,1)}
@end iftex
@ifhtml
@html
<I>U</I>(0,1)
@end html
@end ifhtml
@ifinfo
@math{U(0,1)}
@end ifinfo
random number
@iftex
@math{V.}
@end iftex
@ifhtml
@html
<I>V</I>.
@end html
@end ifhtml
@ifinfo
@math{V.}
@end ifinfo
@item
Set
@iftex
@math{Y}
@end iftex
@ifhtml
@html
<I>Y</I>
@end html
@end ifhtml
@ifinfo
@math{Y}
@end ifinfo
to
@iftex
@math{V h(X).}
@end iftex
@ifhtml
@html
<I>V</I> <I>h</I>(<I>X</I>).
@end html
@end ifhtml
@ifinfo
@math{V h(X).}
@end ifinfo
@item
If
@iftex
@math{Y\leq f(X)}
@end iftex
@ifhtml
@html
<I>Y</I> <= <I>f</I>(<I>X</I>)
@end html
@end ifhtml
@ifinfo
@math{Y <= f(X)}
@end ifinfo
accept
@iftex
@math{X}
@end iftex
@ifhtml
@html
<I>X</I>
@end html
@end ifhtml
@ifinfo
@math{X}
@end ifinfo
as the random variate.
@item
Else try again.
@end enumerate

If the evaluation of the density
@iftex
@math{f(x)}
@end iftex
@ifhtml
@html
<I>f</I>(<I>x</I>)
@end html
@end ifhtml
@ifinfo
@math{f(x)}
@end ifinfo
is expensive
(i.e., time consuming) it is possible to use a simple lower bound
of the density as so called @emph{squeeze function}
@iftex
@math{s(x)}
@end iftex
@ifhtml
@html
<I>s</I>(<I>x</I>)
@end html
@end ifhtml
@ifinfo
@math{s(x)}
@end ifinfo
(the triangular shaped function in the above
figure is an example for such a squeeze). We can then accept
@iftex
@math{X}
@end iftex
@ifhtml
@html
<I>X</I>
@end html
@end ifhtml
@ifinfo
@math{X}
@end ifinfo
when
@iftex
@math{Y\leq s(X)}
@end iftex
@ifhtml
@html
<I>Y</I> <= <I>s</I>(<I>X</I>)
@end html
@end ifhtml
@ifinfo
@math{Y <= s(X)}
@end ifinfo
and can thus often save the
evaluation of the density.

We have seen so far that the rejection principle leads to
short and simple generation algorithms. The main practical problem
to apply the rejection algorithm is the search for a good fitting
hat function and for squeezes. We do not discuss these topics here
as they are the heart of the different automatic algorithms
implemented in UNU.RAN. Information about the construction of hat
and squeeze can therefore be found in the descriptions of the
methods.

The performance characteristics of rejection algorithms mainly
depend on the fit of the hat and the squeeze. It is not difficult
to prove that:
@itemize @bullet
@item
The expected number of trials to generate one variate is the ratio
between the area below the hat and the area below the density.
@item
The expected number of evaluations of the density necessary to
generate one variate is equal to the ratio between the area below
the hat and the area below the density, when no squeeze is used.
Otherwise, when a squeeze is given it is equal to the ratio
between the area between hat and squeeze and the area below the hat.
@item
The @code{sqhratio} (i.e., the ratio between the area below the
squeeze and the area below the hat) used in some of the UNU.RAN
methods is easy to compute. It is useful as its reciprocal is an
upper bound for the expected number of trials of the rejection
algoritm. The expected number of evaluations of the density is
bounded by
@iftex
@math{(1/sqhratio)-1.}
@end iftex
@ifhtml
@html
(1/<I>sqhratio</I>)-1.
@end html
@end ifhtml
@ifinfo
@math{(1/sqhratio)-1.}
@end ifinfo
@end itemize



@c
@c end of arvag.dh
@c -------------------------------------
@c -------------------------------------
@c arvag.dh
@c

@node Composition
@section   The Composition Method



The composition method is an important principle to facilitate and
speed up random variate generation. The basic idea is simple.
To generate random variates with a given density we first split the
domain of the density into subintervals. Then we select one of
these randomly with probabilities given by the area below the
density in the respective subintervals. Finally we generate a
random variate from the density of the selected part by inversion
and return it as random variate of the full distribution.

Composition can be combined with rejection. Thus it is possible to
decompose the domain of the distribution into subintervals and to
construct hat and squeeze functions seperatly in every
subinterval. The area below the hat must be determined in every
subinterval. Then the Composition rejection algorithm contains the
following steps:

@enumerate
@item
Generate the index
@iftex
@math{J}
@end iftex
@ifhtml
@html
<I>J</I>
@end html
@end ifhtml
@ifinfo
@math{J}
@end ifinfo
of the subinterval as the
realisation of a discrete random variate with probabilities
proportional to the area below the hat.
@item
Generate a random variate
@iftex
@math{X}
@end iftex
@ifhtml
@html
<I>X</I>
@end html
@end ifhtml
@ifinfo
@math{X}
@end ifinfo
proportional to the hat in
interval
@iftex
@math{J.}
@end iftex
@ifhtml
@html
<I>J</I>.
@end html
@end ifhtml
@ifinfo
@math{J.}
@end ifinfo
@item
Generate the
@iftex
@math{U(0,f(X))}
@end iftex
@ifhtml
@html
<I>U</I>(0,<I>f</I>(<I>X</I>))
@end html
@end ifhtml
@ifinfo
@math{U(0,f(X))}
@end ifinfo
random number
@iftex
@math{Y.}
@end iftex
@ifhtml
@html
<I>Y</I>.
@end html
@end ifhtml
@ifinfo
@math{Y.}
@end ifinfo
@item
If
@iftex
@math{Y\leq f(X)}
@end iftex
@ifhtml
@html
<I>Y</I> <= <I>f</I>(<I>X</I>)
@end html
@end ifhtml
@ifinfo
@math{Y <= f(X)}
@end ifinfo
accept
@iftex
@math{X}
@end iftex
@ifhtml
@html
<I>X</I>
@end html
@end ifhtml
@ifinfo
@math{X}
@end ifinfo
as random variate.
@item
Else start again with generating the index
@iftex
@math{J.}
@end iftex
@ifhtml
@html
<I>J</I>.
@end html
@end ifhtml
@ifinfo
@math{J.}
@end ifinfo
@end enumerate

The first step can be done in constant time (i.e., independent of
the number of chosen subintervals) by means of the indexed search
method (@pxref{IndexedSearch}).

It is possible to reduce the number of uniform random numbers
required in the above algorithm by recycling the random numbers
used in Step 1 and additionally by applying the principle of
@emph{immediate acceptance}.
For details see
@ifhtml
@ref{bib:HLD04,, [HLD04: Sect. 3.1]}
@end ifhtml
@ifnothtml
[HLD04: Sect. 3.1]
@end ifnothtml
.



@c
@c end of arvag.dh
@c -------------------------------------
@c -------------------------------------
@c arvag.dh
@c

@node Ratio-of-Uniforms
@section   The Ratio-of-Uniforms Method



The construction of an appropriate hat function for the given
density is the crucial step for constructing rejection algorithms.
Equivalently we can try to find an appropriate envelope for the region
between the graph of the density and the @i{x}-axis, such
that we can easily sample uniformly distributed random points.
This task could become easier if we can find transformations that map
the region between the density and the axis into a region of more
suitable shape (for example into a bounded region).

As a first example we consider the following simple algorithm for
the Cauchy distribution.
@enumerate
@item
Generate a
@iftex
@math{U(-1,1)}
@end iftex
@ifhtml
@html
<I>U</I>(-1,1)
@end html
@end ifhtml
@ifinfo
@math{U(-1,1)}
@end ifinfo
random number
@iftex
@math{U}
@end iftex
@ifhtml
@html
<I>U</I>
@end html
@end ifhtml
@ifinfo
@math{U}
@end ifinfo
and a
@iftex
@math{U(0,1)}
@end iftex
@ifhtml
@html
<I>U</I>(0,1)
@end html
@end ifhtml
@ifinfo
@math{U(0,1)}
@end ifinfo
random number
@iftex
@math{V.}
@end iftex
@ifhtml
@html
<I>V</I>.
@end html
@end ifhtml
@ifinfo
@math{V.}
@end ifinfo
@item
If
@iftex
@math{U^2 + V^2\leq 1}
@end iftex
@ifhtml
@html
<I>U</I><SUP>2</SUP> + <I>V</I><SUP>2</SUP> <= 1
@end html
@end ifhtml
@ifinfo
@math{U^2 + V^2 <= 1}
@end ifinfo
accept
@iftex
@math{X=U/V}
@end iftex
@ifhtml
@html
<I>X</I>=<I>U</I>/<I>V</I>
@end html
@end ifhtml
@ifinfo
@math{X=U/V}
@end ifinfo
as a Cauchy
random variate.
@item
Else try again.
@end enumerate

It is possible to prove that the above algorithm indeed  generates
Cauchy random variates. The fundamental principle behind this
algorithm is the fact that the region below the density is mapped
by the transformation
@iftex

@quotation
@math{(X,Y)\mapsto(U,V)=(2\,X\sqrt{Y},2\,\sqrt{Y})}
@end quotation

@end iftex
@ifhtml
@quotation
@html
(<I>X</I>,<I>Y</I>) -> (<I>U</I>,<I>V</I>)=(2 <I>X</I>sqrt(<I>Y</I>),2 sqrt(<I>Y</I>))
@end html
@end quotation
@end ifhtml
@ifinfo
@quotation
@math{(X,Y) -> (U,V)=(2 Xsqrt(Y),2 sqrt(Y))}
@end quotation
@end ifinfo

@noindent
into a half-disc in such a way that the ratio between the area of
the image to the area of the preimage is constant. This is due to
the fact that that the Jacobian of this transformation is constant.


@image{figures/rou-cauchy}



The above example is a special case of a more general principle,
called the @emph{Ratio-of-uniforms (RoU) method}. It is based on
the fact that for a random variable
@iftex
@math{X}
@end iftex
@ifhtml
@html
<I>X</I>
@end html
@end ifhtml
@ifinfo
@math{X}
@end ifinfo
with density
@iftex
@math{f(x)}
@end iftex
@ifhtml
@html
<I>f</I>(<I>x</I>)
@end html
@end ifhtml
@ifinfo
@math{f(x)}
@end ifinfo
and some constant
@iftex
@math{\mu}
@end iftex
@ifhtml
@html
mu
@end html
@end ifhtml
@ifinfo
@math{mu}
@end ifinfo
we can generate
@iftex
@math{X}
@end iftex
@ifhtml
@html
<I>X</I>
@end html
@end ifhtml
@ifinfo
@math{X}
@end ifinfo
from the desired density by calculating
@iftex
@math{X=U/V+\mu}
@end iftex
@ifhtml
@html
<I>X</I>=<I>U</I>/<I>V</I>+ mu
@end html
@end ifhtml
@ifinfo
@math{X=U/V+ mu}
@end ifinfo
for a pair
@iftex
@math{(U,V)}
@end iftex
@ifhtml
@html
(<I>U</I>,<I>V</I>)
@end html
@end ifhtml
@ifinfo
@math{(U,V)}
@end ifinfo
uniformly
distributed in the set
@iftex

@quotation
@math{A_f=\lbrace (u,v)\colon 0 < v \leq \sqrt{f(u/v+\mu)}\rbrace .}
@end quotation

@end iftex
@ifhtml
@quotation
@html
<I>A</I>_<I>f</I>= @{ (<I>u</I>,<I>v</I>) : 0 < <I>v</I> <= sqrt(<I>f</I>(<I>u</I>/<I>v</I>+ mu)) @} .
@end html
@end quotation
@end ifhtml
@ifinfo
@quotation
@math{A_f= @{ (u,v) : 0 < v <= sqrt(f(u/v+ mu)) @} .}
@end quotation
@end ifinfo

@noindent
For most distributions it is best to set the constant
@iftex
@math{\mu}
@end iftex
@ifhtml
@html
mu
@end html
@end ifhtml
@ifinfo
@math{mu}
@end ifinfo
equal to the mode of the distribution. For sampling
random points uniformly distributed in
@iftex
@math{A_f}
@end iftex
@ifhtml
@html
<I>A</I>_<I>f</I>
@end html
@end ifhtml
@ifinfo
@math{A_f}
@end ifinfo
rejection
from a convenient enveloping region is used, usually the minimal
bounding rectangle, i.e., the smallest possible rectangle that
contains
@iftex
@math{A_f}
@end iftex
@ifhtml
@html
<I>A</I>_<I>f</I>
@end html
@end ifhtml
@ifinfo
@math{A_f}
@end ifinfo
(see the above figure).
It is given by
@iftex
@math{(u^-,u^+)\times (0,v^+)}
@end iftex
@ifhtml
@html
(<I>u</I><SUP>-</SUP>,<I>u</I><SUP>+</SUP>)x(0,<I>v</I><SUP>+</SUP>)
@end html
@end ifhtml
@ifinfo
@math{(u^-,u^+)x(0,v^+)}
@end ifinfo
where
@iftex

@quotation
@math{ v^+ = \sup\limits_{b_l<x<b_r} \sqrt{f(x)}, \hfil\break u^- = \inf\limits_{b_l<x<b_r} (x-\mu) \sqrt{f(x)}, \hfil\break u^+ = \sup\limits_{b_l<x<b_r} (x-\mu) \sqrt{f(x)}.}
@end quotation

@end iftex
@ifhtml
@quotation
@html
<I>v</I><SUP>+</SUP> = sup_<I>b</I>_<I>l</I><<I>x</I><<I>b</I>_<I>r</I> sqrt(<I>f</I>(<I>x</I>)), @*<I>u</I><SUP>-</SUP> = inf_<I>b</I>_<I>l</I><<I>x</I><<I>b</I>_<I>r</I> (<I>x</I>- mu) sqrt(<I>f</I>(<I>x</I>)), @*<I>u</I><SUP>+</SUP> = sup_<I>b</I>_<I>l</I><<I>x</I><<I>b</I>_<I>r</I> (<I>x</I>- mu) sqrt(<I>f</I>(<I>x</I>)).
@end html
@end quotation
@end ifhtml
@ifinfo
@quotation
@math{v^+ = sup_(b_l<x<b_r) sqrt(f(x)), @*u^- = inf_(b_l<x<b_r) (x- mu) sqrt(f(x)), @*u^+ = sup_(b_l<x<b_r) (x- mu) sqrt(f(x)).}
@end quotation
@end ifinfo

@noindent
Then the ratio-of-uniforms method consists of the following simple
steps:
@enumerate
@item
Generate a
@iftex
@math{U(u^-,u^+)}
@end iftex
@ifhtml
@html
<I>U</I>(<I>u</I><SUP>-</SUP>,<I>u</I><SUP>+</SUP>)
@end html
@end ifhtml
@ifinfo
@math{U(u^-,u^+)}
@end ifinfo
random number
@iftex
@math{U}
@end iftex
@ifhtml
@html
<I>U</I>
@end html
@end ifhtml
@ifinfo
@math{U}
@end ifinfo
and a
@iftex
@math{U(0,v^+)}
@end iftex
@ifhtml
@html
<I>U</I>(0,<I>v</I><SUP>+</SUP>)
@end html
@end ifhtml
@ifinfo
@math{U(0,v^+)}
@end ifinfo
random number
@iftex
@math{V.}
@end iftex
@ifhtml
@html
<I>V</I>.
@end html
@end ifhtml
@ifinfo
@math{V.}
@end ifinfo
@item
Set
@iftex
@math{X}
@end iftex
@ifhtml
@html
<I>X</I>
@end html
@end ifhtml
@ifinfo
@math{X}
@end ifinfo
to
@iftex
@math{U/V+\mu.}
@end iftex
@ifhtml
@html
<I>U</I>/<I>V</I>+ mu.
@end html
@end ifhtml
@ifinfo
@math{U/V+ mu.}
@end ifinfo
@item
If
@iftex
@math{V^2 \leq f(X)}
@end iftex
@ifhtml
@html
<I>V</I><SUP>2</SUP> <= <I>f</I>(<I>X</I>)
@end html
@end ifhtml
@ifinfo
@math{V^2 <= f(X)}
@end ifinfo
accept
@iftex
@math{X}
@end iftex
@ifhtml
@html
<I>X</I>
@end html
@end ifhtml
@ifinfo
@math{X}
@end ifinfo
as the random
variate.
@item
Else try again.
@end enumerate

To apply the ratio-of-uniforms algorithm to a certain density
we have to solve the simple optimization problems in the
definitions above to obtain the design constants
@iftex
@math{u^-,}
@end iftex
@ifhtml
@html
<I>u</I><SUP>-</SUP>,
@end html
@end ifhtml
@ifinfo
@math{u^-,}
@end ifinfo
@iftex
@math{u^+,}
@end iftex
@ifhtml
@html
<I>u</I><SUP>+</SUP>,
@end html
@end ifhtml
@ifinfo
@math{u^+,}
@end ifinfo
and
@iftex
@math{v^+.}
@end iftex
@ifhtml
@html
<I>v</I><SUP>+</SUP>.
@end html
@end ifhtml
@ifinfo
@math{v^+.}
@end ifinfo
This simple algorithm works for all distributions
with bounded densities that have subquadratic tails (i.e.,
tails like
@iftex
@math{1/x^2}
@end iftex
@ifhtml
@html
1/<I>x</I><SUP>2</SUP>
@end html
@end ifhtml
@ifinfo
@math{1/x^2}
@end ifinfo
or lower). For most standard
distributions it has quite good rejection constants.
(E.g. 1.3688 for the normal and 1.4715 for the exponential
distribution.)

Nevertheless, we use more sophisticated method that construct
better fitting envelopes, like method AROU (@pxref{AROU}), or even
avoid the computation of these design constants and thus have
almost no setup, like method SROU (@pxref{SROU}).

@subheading The Generalized Ratio-of-Uniforms Method

The Ratio-of-Uniforms method can be generalized: If a point
@iftex
@math{(U,V)}
@end iftex
@ifhtml
@html
(<I>U</I>,<I>V</I>)
@end html
@end ifhtml
@ifinfo
@math{(U,V)}
@end ifinfo
is uniformly distributed in the set
@iftex

@quotation
@math{A_f=\lbrace (u,v)\colon 0 < v \leq (f(u/v^r+\mu))^{1/(r+1)}\rbrace }
@end quotation

@end iftex
@ifhtml
@quotation
@html
<I>A</I>_<I>f</I>= @{ (<I>u</I>,<I>v</I>) : 0 < <I>v</I> <= (<I>f</I>(<I>u</I>/<I>v</I><SUP><I>r</I></SUP>+ mu))<SUP>1/(<I>r</I>+1)</SUP> @}
@end html
@end quotation
@end ifhtml
@ifinfo
@quotation
@math{A_f= @{ (u,v) : 0 < v <= (f(u/v^r+ mu))^(1/(r+1)) @}}
@end quotation
@end ifinfo

@noindent
then
@iftex
@math{X=U/V^r+\mu}
@end iftex
@ifhtml
@html
<I>X</I>=<I>U</I>/<I>V</I><SUP><I>r</I></SUP>+ mu
@end html
@end ifhtml
@ifinfo
@math{X=U/V^r+ mu}
@end ifinfo
has the denity
@iftex
@math{f(x).}
@end iftex
@ifhtml
@html
<I>f</I>(<I>x</I>).
@end html
@end ifhtml
@ifinfo
@math{f(x).}
@end ifinfo
The minimal bounding rectangle of this region is given by
@iftex
@math{(u^-,u^+)\times (0,v^+)}
@end iftex
@ifhtml
@html
(<I>u</I><SUP>-</SUP>,<I>u</I><SUP>+</SUP>)x(0,<I>v</I><SUP>+</SUP>)
@end html
@end ifhtml
@ifinfo
@math{(u^-,u^+)x(0,v^+)}
@end ifinfo
where
@iftex

@quotation
@math{ v^+ = \sup\limits_{b_l<x<b_r} (f(x))^{1/(r+1)}, \hfil\break u^- = \inf\limits_{b_l<x<b_r} (x-\mu) (f(x))^{r/(r+1)}, \hfil\break u^+ = \sup\limits_{b_l<x<b_r} (x-\mu) (f(x))^{r/(r+1)}. }
@end quotation

@end iftex
@ifhtml
@quotation
@html
<I>v</I><SUP>+</SUP> = sup_<I>b</I>_<I>l</I><<I>x</I><<I>b</I>_<I>r</I> (<I>f</I>(<I>x</I>))<SUP>1/(<I>r</I>+1)</SUP>, @*<I>u</I><SUP>-</SUP> = inf_<I>b</I>_<I>l</I><<I>x</I><<I>b</I>_<I>r</I> (<I>x</I>- mu) (<I>f</I>(<I>x</I>))<SUP><I>r</I>/(<I>r</I>+1)</SUP>, @*<I>u</I><SUP>+</SUP> = sup_<I>b</I>_<I>l</I><<I>x</I><<I>b</I>_<I>r</I> (<I>x</I>- mu) (<I>f</I>(<I>x</I>))<SUP><I>r</I>/(<I>r</I>+1)</SUP>.
@end html
@end quotation
@end ifhtml
@ifinfo
@quotation
@math{v^+ = sup_(b_l<x<b_r) (f(x))^(1/(r+1)), @*u^- = inf_(b_l<x<b_r) (x- mu) (f(x))^(r/(r+1)), @*u^+ = sup_(b_l<x<b_r) (x- mu) (f(x))^(r/(r+1)).}
@end quotation
@end ifinfo

@noindent
The above algorithm has then to be adjusted accordingly.
Notice that the original Ratio-of-Uniforms method is the special
case with
@iftex
@math{r=1.}
@end iftex
@ifhtml
@html
<I>r</I>=1.
@end html
@end ifhtml
@ifinfo
@math{r=1.}
@end ifinfo



@c
@c end of arvag.dh
@c -------------------------------------
@c -------------------------------------
@c arvag.dh
@c

@node DiscreteInversion
@section   Inversion for Discrete Distributions



We have already presented the idea of the inversion method to
generate from continuous random variables (@pxref{Inversion}). For
a discrete random variable
@iftex
@math{X}
@end iftex
@ifhtml
@html
<I>X</I>
@end html
@end ifhtml
@ifinfo
@math{X}
@end ifinfo
we can write it
mathematically in the same way:
@iftex

@quotation
@math{X=F^{-1}(U),}
@end quotation

@end iftex
@ifhtml
@quotation
@html
<I>X</I>=<I>F</I><SUP>-1</SUP>(<I>U</I>),
@end html
@end quotation
@end ifhtml
@ifinfo
@quotation
@math{X=F^(-1)(U),}
@end quotation
@end ifinfo

@noindent
where
@iftex
@math{F}
@end iftex
@ifhtml
@html
<I>F</I>
@end html
@end ifhtml
@ifinfo
@math{F}
@end ifinfo
is the CDF of the desired distribution and
@iftex
@math{U}
@end iftex
@ifhtml
@html
<I>U</I>
@end html
@end ifhtml
@ifinfo
@math{U}
@end ifinfo
is a uniform
@iftex
@math{U(0,1)}
@end iftex
@ifhtml
@html
<I>U</I>(0,1)
@end html
@end ifhtml
@ifinfo
@math{U(0,1)}
@end ifinfo
random number. The
difference compared to the continuous case is that
@iftex
@math{F}
@end iftex
@ifhtml
@html
<I>F</I>
@end html
@end ifhtml
@ifinfo
@math{F}
@end ifinfo
is
now a step-function. The following figure illustrates the idea of
discrete inversion for a simple distribution.


@image{figures/discrete_inversion}



To realize this idea on a computer we have to use a search
algorithm. For the simplest version called @emph{Sequential Search}
the CDF is computed on-the-fly as sum of the probabilities
@iftex
@math{p(k),}
@end iftex
@ifhtml
@html
<I>p</I>(<I>k</I>),
@end html
@end ifhtml
@ifinfo
@math{p(k),}
@end ifinfo
since this is usually much cheaper than computing
the CDF directly. It is obvious that the basic form of the search
algorithm only works for discrete random variables with probability
mass functions
@iftex
@math{p(k)}
@end iftex
@ifhtml
@html
<I>p</I>(<I>k</I>)
@end html
@end ifhtml
@ifinfo
@math{p(k)}
@end ifinfo
for nonnegative
@iftex
@math{k.}
@end iftex
@ifhtml
@html
<I>k</I>.
@end html
@end ifhtml
@ifinfo
@math{k.}
@end ifinfo
The
sequential search algorithm consists of the following basic steps:

@enumerate
@item
Generate a
@iftex
@math{U(0,1)}
@end iftex
@ifhtml
@html
<I>U</I>(0,1)
@end html
@end ifhtml
@ifinfo
@math{U(0,1)}
@end ifinfo
random number
@iftex
@math{U.}
@end iftex
@ifhtml
@html
<I>U</I>.
@end html
@end ifhtml
@ifinfo
@math{U.}
@end ifinfo
@item
Set
@iftex
@math{X}
@end iftex
@ifhtml
@html
<I>X</I>
@end html
@end ifhtml
@ifinfo
@math{X}
@end ifinfo
to
@iftex
@math{0}
@end iftex
@ifhtml
@html
0
@end html
@end ifhtml
@ifinfo
@math{0}
@end ifinfo
and
@iftex
@math{P}
@end iftex
@ifhtml
@html
<I>P</I>
@end html
@end ifhtml
@ifinfo
@math{P}
@end ifinfo
to
@iftex
@math{p(0).}
@end iftex
@ifhtml
@html
<I>p</I>(0).
@end html
@end ifhtml
@ifinfo
@math{p(0).}
@end ifinfo
@item
Do while
@iftex
@math{U > P}
@end iftex
@ifhtml
@html
<I>U</I> > <I>P</I>
@end html
@end ifhtml
@ifinfo
@math{U > P}
@end ifinfo
@item
@w{ } @w{ } @w{ } Set
@iftex
@math{X}
@end iftex
@ifhtml
@html
<I>X</I>
@end html
@end ifhtml
@ifinfo
@math{X}
@end ifinfo
to
@iftex
@math{X+1}
@end iftex
@ifhtml
@html
<I>X</I>+1
@end html
@end ifhtml
@ifinfo
@math{X+1}
@end ifinfo
and
@iftex
@math{P}
@end iftex
@ifhtml
@html
<I>P</I>
@end html
@end ifhtml
@ifinfo
@math{P}
@end ifinfo
to
@iftex
@math{P+p(X).}
@end iftex
@ifhtml
@html
<I>P</I>+<I>p</I>(<I>X</I>).
@end html
@end ifhtml
@ifinfo
@math{P+p(X).}
@end ifinfo
@item
Return
@iftex
@math{X.}
@end iftex
@ifhtml
@html
<I>X</I>.
@end html
@end ifhtml
@ifinfo
@math{X.}
@end ifinfo
@end enumerate

With the exception of some very simple discrete distributions,
sequential search algorithms become very slow as the while-loop has
to be repeated very often. The expected number of iterations,
i.e., the number of comparisons in the while condition, is equal to
the expectation of the distribution plus
@iftex
@math{1.}
@end iftex
@ifhtml
@html
1.
@end html
@end ifhtml
@ifinfo
@math{1.}
@end ifinfo
It can therefore become arbitrary large or even infinity if the tail
of the distribution is very heavy. Another serious problem can be
critical round-off errors due to summing up many probabilities
@iftex
@math{p(k).}
@end iftex
@ifhtml
@html
<I>p</I>(<I>k</I>).
@end html
@end ifhtml
@ifinfo
@math{p(k).}
@end ifinfo
To speed up the search procedure it is best to use
indexed search.



@c
@c end of arvag.dh
@c -------------------------------------
@c -------------------------------------
@c arvag.dh
@c

@node IndexedSearch
@section   Indexed Search (Guide Table Method)



The idea to speed up the sequential search algorithm is easy to
understand. Instead of starting always at
@iftex
@math{0}
@end iftex
@ifhtml
@html
0
@end html
@end ifhtml
@ifinfo
@math{0}
@end ifinfo
we store a
table of size
@iftex
@math{C}
@end iftex
@ifhtml
@html
<I>C</I>
@end html
@end ifhtml
@ifinfo
@math{C}
@end ifinfo
with starting points for our search. For
this table we compute
@iftex
@math{F^{-1}(U)}
@end iftex
@ifhtml
@html
<I>F</I><SUP>-1</SUP>(<I>U</I>)
@end html
@end ifhtml
@ifinfo
@math{F^(-1)(U)}
@end ifinfo
for
@iftex
@math{C}
@end iftex
@ifhtml
@html
<I>C</I>
@end html
@end ifhtml
@ifinfo
@math{C}
@end ifinfo
equidistributed values of
@iftex
@math{U,}
@end iftex
@ifhtml
@html
<I>U</I>,
@end html
@end ifhtml
@ifinfo
@math{U,}
@end ifinfo
i.e.,
for
@iftex
@math{u_i = i/C,}
@end iftex
@ifhtml
@html
<I>u</I>_<I>i</I> = <I>i</I>/<I>C</I>,
@end html
@end ifhtml
@ifinfo
@math{u_i = i/C,}
@end ifinfo
@iftex
@math{i=0,...,C-1.}
@end iftex
@ifhtml
@html
<I>i</I>=0,...,<I>C</I>-1.
@end html
@end ifhtml
@ifinfo
@math{i=0,...,C-1.}
@end ifinfo
Such a table is
called @emph{guide table} or @emph{hash table}.
Then it is easy to prove that for every
@iftex
@math{U}
@end iftex
@ifhtml
@html
<I>U</I>
@end html
@end ifhtml
@ifinfo
@math{U}
@end ifinfo
in
@iftex
@math{(0,1)}
@end iftex
@ifhtml
@html
(0,1)
@end html
@end ifhtml
@ifinfo
@math{(0,1)}
@end ifinfo
the guide table entry for
@iftex
@math{k=floor(UC)}
@end iftex
@ifhtml
@html
<I>k</I>=<I>floor</I>(<I>UC</I>)
@end html
@end ifhtml
@ifinfo
@math{k=floor(UC)}
@end ifinfo
is bounded by
@iftex
@math{F^{-1}(U).}
@end iftex
@ifhtml
@html
<I>F</I><SUP>-1</SUP>(<I>U</I>).
@end html
@end ifhtml
@ifinfo
@math{F^(-1)(U).}
@end ifinfo
This shows that we can really
start our sequential search procedure from the table entry for
@iftex
@math{k}
@end iftex
@ifhtml
@html
<I>k</I>
@end html
@end ifhtml
@ifinfo
@math{k}
@end ifinfo
and the index
@iftex
@math{k}
@end iftex
@ifhtml
@html
<I>k</I>
@end html
@end ifhtml
@ifinfo
@math{k}
@end ifinfo
of the correct table entry
can be found rapidly by means of the truncation operation.

The two main differences between @emph{indexed search} and
@emph{sequential search} are that we start searching at the number
determined by the guide table, and that we have to compute and
store the cumulative probabilities in the setup as we have to know
the cumulative probability for the starting point of the search
algorithm. The rounding problems that can occur in the sequential
search algorithm can occur here as well.
Compared to sequential search we have now the obvious drawback
of a slow setup. The computation of the cumulative probabilities
grows linear with the size of the domain of the distribution
@iftex
@math{L.}
@end iftex
@ifhtml
@html
<I>L</I>.
@end html
@end ifhtml
@ifinfo
@math{L.}
@end ifinfo
What we gain is really high speed as the marginal
execution time of the sampling algorithm becomes very small. The
expected number of comparisons is bounded by
@iftex
@math{1+L/C.}
@end iftex
@ifhtml
@html
1+<I>L</I>/<I>C</I>.
@end html
@end ifhtml
@ifinfo
@math{1+L/C.}
@end ifinfo
This shows that there is a trade-off between speed and
the size of the guide table. Cache-effects in modern computers will
however slow down the speed-up for really large table sizes.
Thus we recommend to use a guide table that is about two times
larger than the probability vector to obtain optimal speed.



@c
@c end of arvag.dh
@c -------------------------------------
@c -------------------------------------
@c glossary.dh
@c

@node Glossary
@appendix   Glossary



@table @strong

@item CDF
cumulative distribution function.

@item HR
hazard rate (or failure rate).

@item inverse local concavity
local concavity of inverse PDF
@iftex
@math{f^{-1}(y)}
@end iftex
@ifhtml
@html
<I>f</I><SUP>-1</SUP>(<I>y</I>)
@end html
@end ifhtml
@ifinfo
@math{f^(-1)(y)}
@end ifinfo
expressed in term of
@iftex
@math{x = f^{-1}(y).}
@end iftex
@ifhtml
@html
<I>x</I> = <I>f</I><SUP>-1</SUP>(<I>y</I>).
@end html
@end ifhtml
@ifinfo
@math{x = f^(-1)(y).}
@end ifinfo
Is is given by
@iftex
@math{ilc_f(x) = 1 + x\,f''(x) / f'(x)}
@end iftex
@ifhtml
@html
<I>ilc</I>_<I>f</I>(<I>x</I>) = 1 + <I>x</I> <I>f</I>''(<I>x</I>) / <I>f</I>'(<I>x</I>)
@end html
@end ifhtml
@ifinfo
@math{ilc_f(x) = 1 + x f''(x) / f'(x)}
@end ifinfo

@item local concavity
maximum value of @i{c} such that PDF @i{f(x)} is
@iftex
@math{T_c.}
@end iftex
@ifhtml
@html
<I>T</I>_<I>c</I>.
@end html
@end ifhtml
@ifinfo
@math{T_c.}
@end ifinfo
Is is given by
@iftex
@math{lc_f(x) = 1 - f''(x)\,f(x) / f'(x)^2}
@end iftex
@ifhtml
@html
<I>lc</I>_<I>f</I>(<I>x</I>) = 1 - <I>f</I>''(<I>x</I>) <I>f</I>(<I>x</I>) / <I>f</I>'(<I>x</I>)<SUP>2</SUP>
@end html
@end ifhtml
@ifinfo
@math{lc_f(x) = 1 - f''(x) f(x) / f'(x)^2}
@end ifinfo

@item PDF
probability density function.

@item dPDF
derivative (gradient) of probability density function.

@item PMF
probability mass function.

@item PV
(finite) probability vector.

@item URNG
uniform random number generator.

@item @math{U(a,b)}
continuous uniform distribution on the interval
@iftex
@math{(a,b).}
@end iftex
@ifhtml
@html
(<I>a</I>,<I>b</I>).
@end html
@end ifhtml
@ifinfo
@math{(a,b).}
@end ifinfo

@item T-concave
a function @i{f(x)} is called @i{T}-convace if the transformed function
@i{T(f(x))} is concave.
We only deal with transformations
@iftex
@math{T_c,}
@end iftex
@ifhtml
@html
<I>T</I>_<I>c</I>,
@end html
@end ifhtml
@ifinfo
@math{T_c,}
@end ifinfo
where
@table @code
@item @i{c} = 0
@iftex
@math{T(x) = \log(x)}
@end iftex
@ifhtml
@html
<I>T</I>(<I>x</I>) = log(<I>x</I>)
@end html
@end ifhtml
@ifinfo
@math{T(x) = log(x)}
@end ifinfo
@item @i{c} = @math{-0.5}
@iftex
@math{T(x) = -1/\sqrt{x}}
@end iftex
@ifhtml
@html
<I>T</I>(<I>x</I>) = -1/sqrt(<I>x</I>)
@end html
@end ifhtml
@ifinfo
@math{T(x) = -1/sqrt(x)}
@end ifinfo
@item @i{c} != 0
@iftex
@math{T(x) = sign(x) \cdot x^c}
@end iftex
@ifhtml
@html
<I>T</I>(<I>x</I>) = <I>sign</I>(<I>x</I>) * <I>x</I><SUP><I>c</I></SUP>
@end html
@end ifhtml
@ifinfo
@math{T(x) = sign(x) * x^c}
@end ifinfo
@end table

@item u-error
for a given approximate inverse CDF
@iftex
@math{X=G^{-1}(U)}
@end iftex
@ifhtml
@html
<I>X</I>=<I>G</I><SUP>-1</SUP>(<I>U</I>)
@end html
@end ifhtml
@ifinfo
@math{X=G^(-1)(U)}
@end ifinfo
the u-error is given as
@iftex

@quotation
@math{uerror = |U-F(G^{-1}(U))|}
@end quotation

@end iftex
@ifhtml
@quotation
@html
<I>uerror</I> = |<I>U</I>-<I>F</I>(<I>G</I><SUP>-1</SUP>(<I>U</I>))|
@end html
@end quotation
@end ifhtml
@ifinfo
@quotation
@math{uerror = |U-F(G^(-1)(U))|}
@end quotation
@end ifinfo

@noindent
where
@iftex
@math{F}
@end iftex
@ifhtml
@html
<I>F</I>
@end html
@end ifhtml
@ifinfo
@math{F}
@end ifinfo
denotes the exact CDF.
Goodness-of-fit tests like the Kolmogorov-Smirnov test or the
chi-squared test look at this type of error.
See @ref{Inversion} for more details.

@item u-resolution
the maximal tolerated u-error for an approximate inverse CDF.

@item x-error
for a given approximate inverse CDF
@iftex
@math{X=G^{-1}(U)}
@end iftex
@ifhtml
@html
<I>X</I>=<I>G</I><SUP>-1</SUP>(<I>U</I>)
@end html
@end ifhtml
@ifinfo
@math{X=G^(-1)(U)}
@end ifinfo
the x-error is given as
@iftex

@quotation
@math{xerror = |F^{-1}(U)-G^{-1}(U)|}
@end quotation

@end iftex
@ifhtml
@quotation
@html
<I>xerror</I> = |<I>F</I><SUP>-1</SUP>(<I>U</I>)-<I>G</I><SUP>-1</SUP>(<I>U</I>)|
@end html
@end quotation
@end ifhtml
@ifinfo
@quotation
@math{xerror = |F^(-1)(U)-G^(-1)(U)|}
@end quotation
@end ifinfo

@noindent
where
@iftex
@math{F^{-1}}
@end iftex
@ifhtml
@html
<I>F</I><SUP>-1</SUP>
@end html
@end ifhtml
@ifinfo
@math{F^(-1)}
@end ifinfo
denotes the exact inverse CDF.
The x-error measure the deviation of
@iftex
@math{G^{-1}(U)}
@end iftex
@ifhtml
@html
<I>G</I><SUP>-1</SUP>(<I>U</I>)
@end html
@end ifhtml
@ifinfo
@math{G^(-1)(U)}
@end ifinfo
from the exact result.
Notice that we have to distinguish between @emph{absolute} and
@emph{relative} x-error. In UNU.RAN we use the absolute x-error near 0
and the relative x-error otherwise.
See @ref{Inversion} for more details.

@item x-resolution
the maximal tolerated x-error for an approximate inverse CDF.

@end table



@c
@c end of glossary.dh
@c -------------------------------------
@c -------------------------------------
@c references.dh
@c

@node Bibliography
@appendix   Bibliography



@subheading Standard Distributions

@table @t

@anchor{bib:JKKa92}
@item [JKKa92]
@sc{N.L. Johnson, S. Kotz, and A.W. Kemp} (1992).
@i{Univariate Discrete Distributions},
2nd edition,
John Wiley & Sons, Inc., New York.

@anchor{bib:JKBb94}
@item [JKBb94]
@sc{N.L. Johnson, S. Kotz, and N. Balakrishnan} (1994).
@i{Continuous Univariate Distributions},
Volume 1,
2nd edition,
John Wiley & Sons, Inc., New York.

@anchor{bib:JKBc95}
@item [JKBc95]
@sc{N.L. Johnson, S. Kotz, and N. Balakrishnan} (1995).
@i{Continuous Univariate Distributions},
Volume 2,
2nd edition,
John Wiley & Sons, Inc., New York.

@anchor{bib:JKBd97}
@item [JKBd97]
@sc{N.L. Johnson, S. Kotz, and N. Balakrishnan} (1997).
@i{Discrete Multivariate Distributions},
John Wiley & Sons, Inc., New York.

@anchor{bib:KBJe00}
@item [KBJe00]
@sc{S. Kotz, N. Balakrishnan, and N.L. Johnson} (2000).
@i{Continuous Multivariate Distributions},
Volume 1: Models and Applications,
John Wiley & Sons, Inc., New York.

@end table

@c -------------------------------------------------------

@subheading Universal Methods -- Surveys

@table @t

@anchor{bib:HLD04}
@item [HLD04]
@sc{W. H@"ormann, J. Leydold, and G. Derflinger} (2004).
@i{Automatic Nonuniform Random Variate Generation},
Springer, Berlin.

@end table

@c -------------------------------------------------------

@subheading Universal Methods

@table @t

@anchor{bib:AJa93}
@item [AJa93]
@sc{J.H. Ahrens} (1993).
@i{Sampling from general distributions by suboptimal division of domains},
Grazer Math. Berichte 319, 30pp.

@anchor{bib:AJa95}
@item [AJa95]
@sc{J.H. Ahrens} (1995).
@i{An one-table method for sampling from continuous and discrete distributions},
Computing 54(2), pp. 127-146.

@anchor{bib:CAa74}
@item [CAa74]
@sc{H.C. Chen and Y. Asau} (1974).
@i{On generating random variates from an empirical distribution},
AIIE Trans. 6, pp. 163-166.

@anchor{bib:DHLa08}
@item [DHLa08]
@sc{G. Derflinger, W. H@"ormann, and J. Leydold} (2008).
@i{Numerical inversion when only the density function is known},
Research Report Series of the Department of Statistics and Mathematics 78,
WU Wien, Augasse 2--6, A-1090 Wien, Austria,
@uref{http://epub.wu.ac.at/english/}.

@anchor{bib:DLa86}
@item [DLa86]
@sc{L. Devroye} (1986).
@i{Non-Uniform Random Variate Generation},
Springer Verlag, New York.

@anchor{bib:GWa92}
@item [GWa92]
@sc{W.R. Gilks and P. Wild} (1992).
@i{Adaptive rejection sampling for Gibbs sampling},
Applied Statistics 41, pp. 337-348.

@anchor{bib:HWa95}
@item [HWa95]
@sc{W. H@"ormann} (1995).
@i{A rejection technique for sampling from T-concave distributions},
ACM Trans. Math. Software 21(2), pp. 182-193.

@anchor{bib:HDa96}
@item [HDa96]
@sc{W. H@"ormann and G. Derflinger} (1996).
@i{Rejection-inversion to generate variates from monotone discrete distributions},
ACM TOMACS 6(3), 169-184.

@anchor{bib:HLa00}
@item [HLa00]
@sc{W. H@"ormann and J. Leydold} (2000).
@i{Automatic random variate generation for simulation input.}
In: J.A. Joines, R. Barton, P. Fishwick, K. Kang (eds.),
Proceedings of the 2000 Winter Simulation Conference, pp. 675-682.

@anchor{bib:HLa03}
@item [HLa03]
@sc{W. H@"ormann and J. Leydold} (2003).
@i{Continuous Random Variate Generation by Fast Numerical Inversion},
ACM TOMACS 13(4), 347-362.

@anchor{bib:HLDa07}
@item [HLDa07]
@sc{W. H@"ormann, J. Leydold, and G. Derflinger} (2007).
@i{Automatic Random Variate Generation for Unbounded Densities},
ACM Trans. Model. Comput. Simul. 17(4), pp.18.

@anchor{bib:KLPa05}
@item [KLPa05]
@sc{R. Karawatzki, J. Leydold, and K. P@"otzelberger} (2005).
@i{Automatic Markov chain Monte Carlo procedures for sampling from multivariate distributions},
Research Report Series of the Department of Statistics and Mathematics 27,
WU Wien, Augasse 2--6, A-1090 Wien, Austria,
@uref{http://epub.wu.ac.at/english/}.

@anchor{bib:LJa98}
@item [LJa98]
@sc{J. Leydold} (1998).
@i{A Rejection Technique for Sampling from Log-Concave Multivariate Distributions},
ACM TOMACS 8(3), pp. 254-280.

@anchor{bib:LJa00}
@item [LJa00]
@sc{J. Leydold} (2000).
@i{Automatic Sampling with the Ratio-of-Uniforms Method},
ACM Trans. Math. Software 26(1), pp. 78-98.

@anchor{bib:LJa01}
@item [LJa01]
@sc{J. Leydold} (2001).
@i{A simple universal generator for continuous and discrete
univariate T-concave distributions},
ACM Trans. Math. Software 27(1), pp. 66-82.

@anchor{bib:LJa02}
@item [LJa02]
@sc{J. Leydold} (2003).
@i{Short universal generators via generalized ratio-of-uniforms method},
Math. Comp. 72(243), pp. 1453-1471.

@anchor{bib:WGS91}
@item [WGS91]
@sc{J.C. Wakefield, A.E. Gelfand, and A.F.M. Smith} (1992).
@i{Efficient generation of random variates via the ratio-of-uniforms method},
Statist. Comput. 1(2), pp. 129-133.

@anchor{bib:WAa77}
@item [WAa77]
@sc{A.J. Walker} (1977).
@i{An efficient method for generating discrete random variables with general distributions},
ACM Trans. Math. Software 3, pp. 253-256.

@end table

@c -------------------------------------------------------

@subheading Special Generators

@table @t

@anchor{bib:ADa74}
@item [ADa74]
@sc{J.H. Ahrens, U. Dieter} (1974).
@i{Computer methods for sampling from gamma, beta, Poisson
and binomial distributions},
Computing 12, 223-246.

@anchor{bib:ADa82}
@item [ADa82]
@sc{J.H. Ahrens, U. Dieter} (1982).
@i{Generating gamma variates by a modified rejection technique},
Communications of the ACM 25, 47-54.

@anchor{bib:ADb82}
@item [ADb82]
@sc{J.H. Ahrens, U. Dieter} (1982).
@i{Computer generation of Poisson deviates from modified normal distributions},
ACM Trans. Math. Software 8, 163-179.

@anchor{bib:BMa58}
@item [BMa58]
@sc{G.E.P. Box and M.E. Muller} (1958).
@i{A note on the generation of random normal deviates},
Annals Math. Statist. 29, 610-611.

@anchor{bib:CHa77}
@item [CHa77]
@sc{R.C.H. Cheng} (1977).
@i{The Generation of Gamma Variables with Non-Integral Shape Parameter},
Appl. Statist. 26(1), 71-75.

@anchor{bib:Dag89}
@item [Dag89]
@sc{J.S. Dagpunar} (1989).
@i{An Easily Implemented Generalised Inverse Gaussian Generator},
Commun. Statist. Simul. 18(2), 703-710.

@anchor{bib:HDa90}
@item [HDa90]
@sc{W. H@"ormann and G. Derflinger} (1990).
@i{The ACR Method for generating normal random variables},
OR Spektrum 12, 181-185.

@anchor{bib:KAa81}
@item [KAa81]
@sc{A.W. Kemp} (1981).
@i{Efficient generation of logarithmically distributed
pseudo-random variables},
Appl. Statist. 30, 249-253.

@anchor{bib:KRa76}
@item [KRa76]
@sc{A.J. Kinderman and J.G. Ramage} (1976).
@i{Computer Generation of Normal Random Variables},
J. Am. Stat. Assoc. 71(356), 893 - 898.

@anchor{bib:MJa87}
@item [MJa87]
@sc{J.F. Monahan} (1987).
@i{An algorithm for generating chi random variables},
ACM Trans. Math. Software 13, 168-172.

@anchor{bib:MGa62}
@item [MGa62]
@sc{G. Marsaglia} (1962).
@i{Improving the Polar Method for Generating a Pair of Random Variables},
Boeing Sci. Res. Lab., Seattle, Washington.

@anchor{bib:MOa84}
@item [MOa84]
@sc{G. Marsaglia and I. Olkin} (1984).
@i{Generating Correlation Matrices},
SIAM J. Sci. Stat. Comput 5, 470-475.

@anchor{bib:STa89}
@item [STa89]
@sc{E. Stadlober} (1989).
@i{Sampling from Poisson, binomial and hypergeometric distributions:
ratio of uniforms as a simple and fast alternative},
Bericht 303, Math. Stat. Sektion,
Forschungsgesellschaft Joanneum, Graz.

@anchor{bib:ZHa94}
@item [ZHa94]
@sc{H. Zechner} (1994).
@i{Efficient sampling from continuous and discrete unimodal distributions},
Pd.D. Thesis, 156 pp., Technical University Graz, Austria.

@end table

@c -------------------------------------------------------

@subheading Other references

@table @t

@anchor{bib:CPa76}
@item [CPa76]
@sc{R. Cranley and T.N.L. Patterson} (1976).
@i{Randomization of number theoretic methods for multiple integration},
SIAM J. Num. Anal., Vol. 13, pp. 904-914.

@anchor{bib:HJa61}
@item [HJa61]
@sc{R. Hooke and T.A. Jeeves} (1961).
@i{Direct Search Solution of Numerical and Statistical Problems},
Journal of the ACM, Vol. 8, April 1961, pp. 212-229.

@end table

@c -------------------------------------------------------



@c
@c end of references.dh
@c -------------------------------------
@c -------------------------------------
@c index.dh
@c

@node FIndex
@appendix   Function Index


@printindex fn



@c
@c end of index.dh
@c -------------------------------------
