// Copyright (C) 2018 EDF
// All Rights Reserved
// This code is published under the GNU Lesser General Public License (GNU LGPL)
#ifndef _NDDOMINANCEKERNEL_H
#define _NDDOMINANCEKERNEL_H
#include <vector>
#include <memory>
#include <Eigen/Dense>


/** \file  nDDominanceKernel.h
 * \brief  Permits to calculate different components involved in kernel regression
 *    for Laplacian type kernels
 *    As an example
 *   \f$
 *   k(x) = \frac{1}{2^d h^d}   e^{ -\sum_{i=1}^d \frac{|x_i|}{h}}
 *   \f$
 *   And
 *   \f$
 *   K(x) = \frac{1}{M}  \sum_{j=1}^M  k(x-x^j)
 *   \f$
*   In 2D :
 *   \f{eqnarray*}{
 *    K(x)=  & \frac{1}{4 N h^2}  \left(  e^{\frac{x_1}{h}} e^{\frac{x_2}{h}}
 *        \sum_{j=1}^N e^{ - \frac{ x_1^j}{h}} e^{ - \frac{ x_2^j}{h}}   1_{(x_1 \le x_1^j) \wedge (x_2 \le x_2^j)} +
 *        e^{\frac{-x_1}{h}} e^{\frac{x_2}{h}}  \sum_{j=1}^N e^{  \frac{ x_1^j}{h}} e^{ - \frac{ x_2^j}{h}}   1_{(x_1 > x_1^j) \wedge (x_2 < x_2^j)} + \right. \\
 *        &  \left. e^{\frac{-x_1}{h}} e^{\frac{-x_2}{h}}  \sum_{j=1}^N e^{  \frac{ x_1^j}{h}} e^{  \frac{ x_2^j}{h}}   1_{(x_1 > x_1^j) \wedge (x_2 > x_2^j)} +
 *        e^{\frac{x_1}{h}} e^{-\frac{x_2}{h}}  \sum_{j=1}^N e^{  -\frac{ x_1^j}{h}} e^{  \frac{ x_2^j}{h}}   1_{(x_1 < x_1^j) \wedge (x_2 > x_2^j)}  \right)
 *     }
 *  This algorithm permits to compute all terms with summations
 * \author Xavier Warin
 */



namespace StOpt
{
/// \brief  Dominance for kernel
/// \param  p_pt        arrays of point coordinates  (d, nbSimul)
/// \param  p_valToAdd  terms to add  (exponentall in summation above) : vector of \f$2^d \f  kinds of terms  of size ( P, nbSimul)
/// \param  p_fDomin    result of summation  \f$2^d \f terms of size  ( P, nbSimul)
void nDDominanceKernel(const Eigen::ArrayXXd &p_pt,
                       const std::vector< std::shared_ptr<Eigen::ArrayXXd > >   &p_valToAdd,
                       std::vector< std::shared_ptr<Eigen::ArrayXXd > > &p_fDomin);

}

#endif
