/*
	File                 : nsl_sf_kernel.c
	Project              : LabPlot
	Description          : NSL special kernel functions
	--------------------------------------------------------------------
	SPDX-FileCopyrightText: 2016 Stefan Gerlach <stefan.gerlach@uni.kn>
	SPDX-License-Identifier: GPL-2.0-or-later
*/

#include "nsl_sf_kernel.h"
#include <gsl/gsl_math.h>
#include <gsl/gsl_randist.h> /* Gaussian and Cauchy */
#include <math.h>
#include <stdlib.h>

/* kernel on [-1,1] */

double nsl_sf_kernel_uniform(double u) {
	if (fabs(u) <= 1.0)
		return 0.5;
	return 0.0;
}

double nsl_sf_kernel_triangular(double u) {
	if (fabs(u) <= 1.0)
		return 1.0 - fabs(u);
	return 0.0;
}

double nsl_sf_kernel_parabolic(double u) {
	if (fabs(u) <= 1.0)
		return 3. / 4. * (1.0 - gsl_pow_2(u));
	return 0.0;
}

double nsl_sf_kernel_quartic(double u) {
	if (fabs(u) <= 1.0)
		return 15. / 16. * gsl_pow_2(1.0 - gsl_pow_2(u));
	return 0.0;
}

double nsl_sf_kernel_triweight(double u) {
	if (fabs(u) <= 1.0)
		return 35. / 32. * gsl_pow_3(1.0 - gsl_pow_2(u));
	return 0.0;
}

double nsl_sf_kernel_tricube(double u) {
	if (fabs(u) <= 1.0)
		return 70. / 81. * gsl_pow_3(1.0 - gsl_pow_3(fabs(u)));
	return 0.0;
}

double nsl_sf_kernel_cosine(double u) {
	if (fabs(u) <= 1.0)
		return M_PI_4 * cos(M_PI_2 * u);
	return 0.0;
}

double nsl_sf_kernel_semicircle(double u) {
	if (fabs(u) < 1.0)
		return M_2_PI * sqrt(1 - gsl_pow_2(u));
	return 0.0;
}

/* kernel on (-inf,inf) */
double nsl_sf_kernel_gaussian(double u) {
	return gsl_ran_gaussian_pdf(u, 1.0);
}

double nsl_sf_kernel_cauchy(double u) {
	return gsl_ran_cauchy_pdf(u, 1.0);
}

double nsl_sf_kernel_logistic(double u) {
	return gsl_ran_logistic_pdf(u, 1.0);
}

double nsl_sf_kernel_picard(double u) {
	return 0.5 * exp(-fabs(u));
}

double nsl_sf_kernel_sigmoid(double u) {
	return M_1_PI / cosh(u);
}

double nsl_sf_kernel_silverman(double u) {
	return 1.0 / 2.0 * exp(-fabs(u) / M_SQRT2) * sin(fabs(u) / M_SQRT2 + M_PI_4);
}
