/******************************************************** * ██████╗ ██████╗████████╗██╗ * ██╔════╝ ██╔════╝╚══██╔══╝██║ * ██║ ███╗██║ ██║ ██║ * ██║ ██║██║ ██║ ██║ * ╚██████╔╝╚██████╗ ██║ ███████╗ * ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝ * Geophysical Computational Tools & Library (GCTL) * * Copyright (c) 2023 Yi Zhang (yizhang-geo@zju.edu.cn) * * GCTL is distributed under a dual licensing scheme. You can redistribute * it and/or modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, either version 2 * of the License, or (at your option) any later version. You should have * received a copy of the GNU Lesser General Public License along with this * program. If not, see . * * If the terms and conditions of the LGPL v.2. would prevent you from using * the GCTL, please consider the option to obtain a commercial license for a * fee. These licenses are offered by the GCTL's original author. As a rule, * licenses are provided "as-is", unlimited in time for a one time fee. Please * send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget * to include some description of your company and the realm of its activities. * Also add information on how to contact you by electronic and paper mail. ******************************************************/ #ifndef _GCTL_KERNEL_DENSITY_ESTIMATION_H #define _GCTL_KERNEL_DENSITY_ESTIMATION_H #include "../core.h" #include "../maths.h" #include "../io.h" namespace gctl { enum kde_kernel_e { KDE_Gaussian, KDE_Epanechnikov, KDE_Rectangular, KDE_Triangular, }; enum kde_norm_e { KDE_MAX2ONE, KDE_SUM2ONE, KDE_CUMSTOM, }; class kde { public: kde(); virtual ~kde(); /** * @brief Construct a new kde object * * @param h 核函数的带宽 * @param s 核密度估计的采样点序列 */ kde(double h, const array &s); /** * @brief 初始化核密度估计对象 * * @param h 核函数的带宽 * @param x 核密度估计的采样点序列 */ void init(double h, const array &s); /** * @brief 计算集合的概率密度分布 * * @param m 待计算的数据集合 * @param d 采样点处的概率分布 * @param k_type 核函数类型 */ void get_distribution(const array &m, array &d, kde_kernel_e k_type = KDE_Gaussian); /** * @brief 计算集合的概率密度分布相对于集合元素的偏导数 * * @param m_id 待计算集合元素的索引 * @param m 待计算的数据集合 * @param dm 概率分布相对于集合元素m_id的偏导数 * @param k_type 核函数类型 */ void get_gradient_at(size_t m_id, const array &m, array &dm, kde_kernel_e k_type = KDE_Gaussian); private: size_t xs_; double h_; array x_; double gaussian_kernel(double x); double epanechnikov_kernel(double x, bool gradient = false); double rectangular_kernel(double x, bool gradient = false); double triangular_kernel(double x, bool gradient = false); }; class kde2d { public: kde2d(); virtual ~kde2d(); /** * @brief Construct a new kde2d object * * @param hx * @param hy * @param x * @param y */ kde2d(double hx, double hy, const array &x, const array &y); /** * @brief * * @param hx * @param hy * @param x * @param y */ void init(double hx, double hy, const array &x, const array &y); /** * @brief Get the distribution object * * @param mx * @param my * @param dxy * @param k_type */ void get_distribution(const array &mx, const array &my, array &dxy, kde_kernel_e k_type = KDE_Gaussian); /** * @brief Get the gradient at object * * @param m_id * @param mx * @param my * @param dmx * @param k_type */ void get_gradient_x_at(size_t m_id, const array &mx, const array &my, array &dmx, kde_kernel_e k_type = KDE_Gaussian); /** * @brief Get the gradient y at object * * @param m_id * @param mx * @param my * @param dmy * @param k_type */ void get_gradient_y_at(size_t m_id, const array &mx, const array &my, array &dmy, kde_kernel_e k_type = KDE_Gaussian); private: size_t xs_, ys_; double hx_, hy_; array x_, y_; double gaussian_kernel(double x, double y); }; } #endif // _GCTL_KERNEL_DENSITY_ESTIMATION_H