#ifndef KERNEL_SMOOTHING_H
#define KERNEL_SMOOTHING_H

#include <math.h>
#include "Learner.h"   // классы-оболочки

// =====================================================================
// ЯДРА -- ЧИСТЫЙ ИЗУМРУД!
// =====================================================================

// Сглаживающее ядро - чётная нормированная (интеграл по всей оси равен 1) функция
typedef double (*FSoothingKernel) (double r);

// Прямоугольное ядро (самое фиговое)
double KSimple (double r);

// Гауссовское ядро (носитель не финитный => нельзя сэкономить на просмотре только ближайших)
double KGauss (double r);

// Ядро Епанечникова (якобы оптимальное, но кусочно-дифференцируемое)
double KEpanechnikov (double r);

// Квадратическое ядро (рекомендация лучших маститых ядерщиков)
double KQuadratic (double r);

// =====================================================================
// Ядерное сглаживание с вычислением евклидовой метрики
// =====================================================================
class CKernelSmoothing : public CLearner {
public:
	CKernelSmoothing ();
	~CKernelSmoothing ();

	double h;  // ширина окна сглаживания
	FSoothingKernel Kernel;  // сглаживающее ядро
	
	// Метод обучения
	int Train (
		CmaMatrix &Features, // матрица Объекты * Признаки
		CmaMatrix &Weight,   // матрица Объекты * {ВесаОбъектов}
		CmaMatrix &Target    // матрица Объекты * {ЦелевойПризнак}
	);
	
	// Метод применения
	int Test (
		CmaMatrix &Features, // матрица Объекты * Признаки
		CmaMatrix &Result    // матрица Объекты * {ЦелевойПризнак}
	);

private:
	// копия обучающих данных
	CmaMatrix TrainFeatures;
	CmaMatrix TrainWeight;
	CmaMatrix TrainTarget;
};

// =====================================================================
// Классификация на M>=2 классов методом локального восстановления 
// плотности классов по Парзену-Розенблатту
// =====================================================================

#endif
