%feature("docstring") OT::ANCOVA
"ANalysis of COVAriance method (ANCOVA).

Available constructor:
    ANCOVA(*functionalChaosResult, correlatedInput*)

Parameters
----------
functionalChaosResult : :class:`~openturns.FunctionalChaosResult`
    Functional chaos result approximating the model response with
    uncorrelated inputs.
correlatedInput : 2-d sequence of float
    Correlated inputs used to compute the real values of the output.
    Its dimension must be equal to the number of inputs of the model.

Notes
-----
ANCOVA, a variance-based method described in [Caniou2012]_, is a generalization
of the ANOVA (ANalysis Of VAriance) decomposition for models with correlated
input parameters.

Let us consider a model :math:`Y = h(\vect{X})` without making any hypothesis
on the dependence structure of :math:`\vect{X} = \{X^1, \ldots, X^{n_X} \}`, a
n_X-dimensional random vector. The covariance decomposition requires a functional
decomposition of the model. Thus the model response :math:`Y` is expanded as a
sum of functions of increasing dimension as follows:

.. math::
    :label: model

    h(\vect{X}) = h_0 + \sum_{u\subseteq\{1,\dots,n_X\}} h_u(X_u)

:math:`h_0` is the mean of :math:`Y`. Each function :math:`h_u` represents,
for any non empty set :math:`u\subseteq\{1, \dots, n_X\}`, the combined
contribution of the variables :math:`X_u` to :math:`Y`.

Using the properties of the covariance, the variance of :math:`Y` can be
decomposed into a variance part and a covariance part as follows:

.. math::

    Var[Y]&= Cov\left[h_0 + \sum_{u\subseteq\{1,\dots,n_X\}} h_u(X_u), h_0 + \sum_{u\subseteq\{1,\dots,n_X\}} h_u(X_u)\right] \\
          &= \sum_{u\subseteq\{1,\dots,n_X\}} \left[Var[h_u(X_u)] + Cov[h_u(X_u), \sum_{v\subseteq\{1,\dots,n_X\}, v\cap u=\varnothing} h_v(X_v)]\right]

This variance formula enables to define each total part of variance of
:math:`Y` due to :math:`X_u`, :math:`S_u`, as the sum of a *physical*
(or *uncorrelated*) part and a *correlated* part such as:

.. math::

    S_u = \frac{Cov[Y, h_u(X_u)]} {Var[Y]} = S_u^U + S_u^C

where :math:`S_u^U` is the uncorrelated part of variance of Y due to :math:`X_u`:

.. math::

    S_u^U = \frac{Var[h_u(X_u)]} {Var[Y]}

and :math:`S_u^C` is the contribution of the correlation of :math:`X_u` with the
other parameters:

.. math::

    S_u^C = \frac{Cov\left[h_u(X_u), \displaystyle \sum_{v\subseteq\{1,\dots,n_X\}, v\cap u=\varnothing} h_v(X_v)\right]}
                 {Var[Y]}

As the computational cost of the indices with the numerical model :math:`h`
can be very high, [Caniou2012]_ suggests to approximate the model response with
a polynomial chaos expansion:

.. math::

    Y \simeq \hat{h} = \sum_{j=0}^{P-1} \alpha_j \Psi_j(x)

However, for the sake of computational simplicity, the latter is constructed
considering *independent* components :math:`\{X^1,\dots,X^{n_X}\}`. Thus the
chaos basis is not orthogonal with respect to the correlated inputs under
consideration, and it is only used as a metamodel to generate approximated
evaluations of the model response and its summands :eq:`model`.

The next step consists in identifying the component functions. For instance, for
:math:`u = \{1\}`:

.. math::

    h_1(X_1) = \sum_{\alpha | \alpha_1 \neq 0, \alpha_{i \neq 1} = 0} y_{\alpha} \Psi_{\alpha}(\vect{X})

where :math:`\alpha` is a set of degrees associated to the :math:`n_X` univariate
polynomial :math:`\psi_i^{\alpha_i}(X_i)`.

Then the model response :math:`Y` is evaluated using a sample
:math:`X=\{x_k, k=1,\dots,N\}` of the correlated joint distribution. Finally,
the several indices are computed using the model response and its component
functions that have been identified on the polynomial chaos.

Examples
--------
>>> import openturns as ot
>>> ot.RandomGenerator.SetSeed(0)
>>> # Model and distribution definition
>>> model = ot.SymbolicFunction(['X1','X2'], ['4.*X1 + 5.*X2'])
>>> distribution = ot.ComposedDistribution([ot.Normal()] * 2)
>>> S = ot.CorrelationMatrix(2)
>>> S[1, 0] = 0.3
>>> R = ot.NormalCopula().GetCorrelationFromSpearmanCorrelation(S)
>>> CorrelatedInputDistribution = ot.ComposedDistribution([ot.Normal()] * 2, ot.NormalCopula(R))
>>> sample = CorrelatedInputDistribution.getSample(200)
>>> # Functional chaos computation
>>> productBasis = ot.OrthogonalProductPolynomialFactory([ot.HermiteFactory()] * 2, ot.EnumerateFunction(2))
>>> adaptiveStrategy = ot.FixedStrategy(productBasis, 15)
>>> projectionStrategy = ot.LeastSquaresStrategy(ot.MonteCarloExperiment(100))
>>> algo = ot.FunctionalChaosAlgorithm(model, distribution, adaptiveStrategy, projectionStrategy)
>>> algo.run()
>>> ancovaResult = ot.ANCOVA(algo.getResult(), sample)
>>> indices = ancovaResult.getIndices()
>>> print(indices)
[0.408398,0.591602]
>>> uncorrelatedIndices = ancovaResult.getUncorrelatedIndices()
>>> print(uncorrelatedIndices)
[0.284905,0.468108]
>>> # Get indices measuring the correlated effects
>>> print(indices - uncorrelatedIndices)
[0.123494,0.123494]"

// ---------------------------------------------------------------------

%feature("docstring") OT::ANCOVA::getUncorrelatedIndices
"Accessor to the ANCOVA indices measuring uncorrelated effects.

Parameters
----------
marginalIndex : int, :math:`0 \leq i < n`, optional
    Index of the model's marginal used to estimate the indices.
    By default, marginalIndex is equal to 0.

Returns
-------
indices : :class:`~openturns.Point`
    List of the ANCOVA indices measuring uncorrelated effects of the inputs.
    The effects of the correlation are represented by the indices resulting
    from the subtraction of the :meth:`getIndices` and
    :meth:`getUncorrelatedIndices` lists."

// ---------------------------------------------------------------------

%feature("docstring") OT::ANCOVA::getIndices
"Accessor to the ANCOVA indices.

Parameters
----------
marginalIndex : int, :math:`0 \leq i < n`, optional
    Index of the model's marginal used to estimate the indices.
    By default, marginalIndex is equal to 0.

Returns
-------
indices : :class:`~openturns.Point`
    List of the ANCOVA indices measuring the contribution of the
    input variables to the variance of the model. These indices are made up
    of a *physical* part and a *correlated* part. The first one is obtained
    thanks to :meth:`getUncorrelatedIndices`.
    The effects of the correlation are represented by the indices resulting
    from the subtraction of the :meth:`getIndices` and
    :meth:`getUncorrelatedIndices` lists."
