use num_traits::Float;
use std::marker::PhantomData;
pub trait Kernel<T>
where
T: Float,
{
fn f(&self, x: T) -> T;
fn df(&self, x: T) -> T;
fn ddf(&self, x: T) -> T;
fn dddf(&self, x: T) -> T;
fn ddddf(&self, x: T) -> T;
fn df_l(&self, x: T) -> T;
fn g(&self, x: T) -> T;
fn g_l(&self, x: T) -> T;
fn h(&self, x: T, a: T) -> T;
}
pub trait LocalKernel<T>
where
T: Float,
{
fn new(r: T) -> Self;
}
pub trait GlobalKernel {
fn new() -> Self;
}
#[derive(Copy, Clone)]
pub struct Pow2<T>(PhantomData<T>);
impl<T: Float> GlobalKernel for Pow2<T> {
fn new() -> Self {
Pow2(PhantomData)
}
}
impl<T: Float> Default for Pow2<T> {
fn default() -> Self {
Pow2(PhantomData)
}
}
impl<T: Float> Kernel<T> for Pow2<T> {
fn f(&self, x: T) -> T {
x * x
}
fn df(&self, x: T) -> T {
T::from(2.0).unwrap() * x
}
fn ddf(&self, _: T) -> T {
T::from(2.0).unwrap()
}
fn dddf(&self, _: T) -> T {
T::zero()
}
fn ddddf(&self, _: T) -> T {
T::zero()
}
fn df_l(&self, _: T) -> T {
T::from(2.0).unwrap()
}
fn g(&self, _: T) -> T {
T::zero()
}
fn g_l(&self, _: T) -> T {
T::zero()
}
fn h(&self, _: T, _: T) -> T {
T::zero()
}
}
#[derive(Copy, Clone)]
pub struct Pow3<T>(::std::marker::PhantomData<T>);
impl<T: Float> GlobalKernel for Pow3<T> {
fn new() -> Self {
Pow3(PhantomData)
}
}
impl<T: Float> Default for Pow3<T> {
fn default() -> Self {
Pow3(PhantomData)
}
}
impl<T: Float> Kernel<T> for Pow3<T> {
fn f(&self, x: T) -> T {
x * x * x
}
fn df(&self, x: T) -> T {
T::from(3.0).unwrap() * x * x
}
fn ddf(&self, x: T) -> T {
T::from(6.0).unwrap() * x
}
fn dddf(&self, _: T) -> T {
T::from(6.0).unwrap()
}
fn ddddf(&self, _: T) -> T {
T::zero()
}
fn df_l(&self, x: T) -> T {
T::from(3.0).unwrap() * x
}
fn g(&self, _: T) -> T {
T::from(3.0).unwrap()
}
fn g_l(&self, x: T) -> T {
T::from(3.0).unwrap() / x
}
fn h(&self, x: T, a: T) -> T {
T::from(3.0).unwrap() * (T::from(2.0).unwrap() - a) / x
}
}
#[derive(Copy, Clone)]
pub struct Pow4<T>(::std::marker::PhantomData<T>);
impl<T: Float> GlobalKernel for Pow4<T> {
fn new() -> Self {
Pow4(PhantomData)
}
}
impl<T: Float> Default for Pow4<T> {
fn default() -> Self {
Pow4(PhantomData)
}
}
impl<T: Float> Kernel<T> for Pow4<T> {
fn f(&self, x: T) -> T {
x * x * x * x
}
fn df(&self, x: T) -> T {
T::from(4.0).unwrap() * x * x * x
}
fn ddf(&self, x: T) -> T {
T::from(12.0).unwrap() * x * x
}
fn dddf(&self, x: T) -> T {
T::from(24.0).unwrap() * x
}
fn ddddf(&self, _: T) -> T {
T::from(24.0).unwrap()
}
fn df_l(&self, x: T) -> T {
T::from(4.0).unwrap() * x * x
}
fn g(&self, x: T) -> T {
T::from(8.0).unwrap() * x
}
fn g_l(&self, _: T) -> T {
T::from(8.0).unwrap()
}
fn h(&self, _: T, a: T) -> T {
T::from(24.0).unwrap() - a * T::from(8.0).unwrap()
}
}
#[derive(Copy, Clone)]
pub struct Pow5<T>(::std::marker::PhantomData<T>);
impl<T: Float> GlobalKernel for Pow5<T> {
fn new() -> Self {
Pow5(PhantomData)
}
}
impl<T: Float> Default for Pow5<T> {
fn default() -> Self {
Pow5(PhantomData)
}
}
impl<T: Float> Kernel<T> for Pow5<T> {
fn f(&self, x: T) -> T {
x * x * x * x * x
}
fn df(&self, x: T) -> T {
T::from(5.0).unwrap() * x * x * x * x
}
fn ddf(&self, x: T) -> T {
T::from(20.0).unwrap() * x * x * x
}
fn dddf(&self, x: T) -> T {
T::from(60.0).unwrap() * x * x
}
fn ddddf(&self, x: T) -> T {
T::from(120.0).unwrap() * x
}
fn df_l(&self, x: T) -> T {
T::from(5.0).unwrap() * x * x * x
}
fn g(&self, x: T) -> T {
T::from(15.0).unwrap() * x * x
}
fn g_l(&self, x: T) -> T {
T::from(15.0).unwrap() * x
}
fn h(&self, x: T, a: T) -> T {
(T::from(60.0).unwrap() - a * T::from(15.0).unwrap()) * x
}
}
#[derive(Copy, Clone)]
pub struct Gauss<T> {
r: T,
}
impl<T: Float> LocalKernel<T> for Gauss<T> {
fn new(r: T) -> Self {
Gauss { r }
}
}
impl<T: Float> Default for Gauss<T> {
fn default() -> Self {
Gauss { r: T::one() }
}
}
impl<T: Float> Kernel<T> for Gauss<T> {
fn f(&self, x: T) -> T {
T::exp(-x * x / self.r)
}
fn df(&self, x: T) -> T {
-(T::from(2.0).unwrap() / self.r) * x * self.f(x)
}
fn ddf(&self, x: T) -> T {
let _2 = T::from(2.0).unwrap();
_2 * self.f(x) * (_2 * x * x - self.r) / (self.r * self.r)
}
fn dddf(&self, x: T) -> T {
let r3 = self.r * self.r * self.r;
let _4 = T::from(4.0).unwrap();
let _3 = T::from(3.0).unwrap();
let _2 = T::from(2.0).unwrap();
_4 * x * self.f(x) * (_3 * self.r - _2 * x * x) / r3
}
fn ddddf(&self, x: T) -> T {
let r2 = self.r * self.r;
let r4 = r2 * r2;
let x2 = x * x;
let x4 = x2 * x2;
let _4 = T::from(4.0).unwrap();
let _12 = T::from(12.0).unwrap();
let _3 = T::from(3.0).unwrap();
_4 * (_3 * r2 - _12 * self.r * x2 + _4 * x4) * self.f(x) / r4
}
fn df_l(&self, x: T) -> T {
-(T::from(2.0).unwrap() / self.r) * self.f(x)
}
fn g(&self, x: T) -> T {
T::from(4.0).unwrap() * x * self.f(x) / (self.r * self.r)
}
fn g_l(&self, x: T) -> T {
T::from(4.0).unwrap() * self.f(x) / (self.r * self.r)
}
fn h(&self, x: T, a: T) -> T {
let _4 = T::from(4.0).unwrap();
let _3 = T::from(3.0).unwrap();
let _2 = T::from(2.0).unwrap();
_4 * self.f(x) * ((_3 - a) * self.r - _2 * x * x) / (self.r * self.r * self.r)
}
}
#[derive(Copy, Clone)]
pub struct Csrbf31<T> {
r: T,
}
impl<T: Float> LocalKernel<T> for Csrbf31<T> {
fn new(r: T) -> Self {
Csrbf31 { r }
}
}
impl<T: Float> Default for Csrbf31<T> {
fn default() -> Self {
Csrbf31 { r: T::one() }
}
}
impl<T: Float> Kernel<T> for Csrbf31<T> {
fn f(&self, x: T) -> T {
let _1 = T::one();
let x = x / self.r;
if x > _1 {
T::zero()
} else {
let _4 = T::from(4.0).unwrap();
let t = _1 - x;
let t4 = t * t * t * t;
t4 * (_4 * x + _1)
}
}
fn df(&self, x: T) -> T {
let _1 = T::one();
let x = x / self.r;
if x > _1 {
T::zero()
} else {
let t = x - _1;
let t3 = t * t * t;
T::from(20).unwrap() * t3 * x / self.r
}
}
fn ddf(&self, x: T) -> T {
let _1 = T::one();
let x = x / self.r;
if x > _1 {
T::zero()
} else {
let t = _1 - x;
T::from(20).unwrap() * t * t * (T::from(4).unwrap() * x - _1) / (self.r * self.r)
}
}
fn dddf(&self, x: T) -> T {
let _1 = T::one();
let x = x / self.r;
if x > _1 {
T::zero()
} else {
let _2 = T::from(2).unwrap();
T::from(120).unwrap() * (x - _1) * (_2 * x - _1) / (self.r * self.r * self.r)
}
}
fn ddddf(&self, x: T) -> T {
let _1 = T::one();
let x = x / self.r;
if x > _1 {
T::zero()
} else {
T::from(120).unwrap() * (T::from(4).unwrap() * x - T::from(3).unwrap())
/ (self.r * self.r * self.r * self.r)
}
}
fn df_l(&self, x: T) -> T {
let _1 = T::one();
let x = x / self.r;
if x > _1 {
T::zero()
} else {
let t = x - _1;
let t3 = t * t * t;
T::from(20).unwrap() * t3 / (self.r * self.r)
}
}
fn g(&self, x: T) -> T {
let _1 = T::one();
let x = x / self.r;
if x > _1 {
T::zero()
} else {
let t = _1 - x;
T::from(60).unwrap() * t * t / (self.r * self.r * self.r)
}
}
fn g_l(&self, x: T) -> T {
let _1 = T::one();
let x = x / self.r;
if x > _1 {
T::zero()
} else {
let t = _1 - x;
T::from(60).unwrap() * t * t / (x * self.r * self.r * self.r * self.r)
}
}
fn h(&self, x: T, a: T) -> T {
let _1 = T::one();
let x = x / self.r;
if x > _1 {
T::zero()
} else {
let t = _1 - x;
let _2 = T::from(2).unwrap();
let _4 = T::from(4).unwrap();
T::from(60).unwrap() * t * (_2 - _4 * x - a * t)
/ (x * self.r * self.r * self.r * self.r)
}
}
}
#[derive(Copy, Clone)]
pub struct Csrbf42<T> {
r: T,
}
impl<T: Float> LocalKernel<T> for Csrbf42<T> {
fn new(r: T) -> Self {
Csrbf42 { r }
}
}
impl<T: Float> Default for Csrbf42<T> {
fn default() -> Self {
Csrbf42 { r: T::one() }
}
}
impl<T: Float> Kernel<T> for Csrbf42<T> {
fn f(&self, x: T) -> T {
let _1 = T::one();
let x = x / self.r;
if x > _1 {
T::zero()
} else {
let _3 = T::from(3.0).unwrap();
let _18 = T::from(18.0).unwrap();
let _35 = T::from(35.0).unwrap();
let t = _1 - x;
let t3 = t * t * t;
t3 * t3 * (_35 * x * x + _18 * x + _3)
}
}
fn df(&self, x: T) -> T {
let _1 = T::one();
let x = x / self.r;
if x > _1 {
T::zero()
} else {
let t = x - _1;
let t5 = t * t * t * t * t;
T::from(56.0).unwrap() * t5 * (T::from(5.0).unwrap() * x + _1) * x / self.r
}
}
fn ddf(&self, x: T) -> T {
let _1 = T::one();
let x = x / self.r;
if x > _1 {
T::zero()
} else {
let _35 = T::from(35.0).unwrap();
let _4 = T::from(4.0).unwrap();
let t = _1 - x;
let t2 = t * t;
T::from(56.0).unwrap() * t2 * t2 * (_35 * x * x - _4 * x - _1) / (self.r * self.r)
}
}
fn dddf(&self, x: T) -> T {
let _1 = T::one();
let x = x / self.r;
if x > _1 {
T::zero()
} else {
let _7 = T::from(7.0).unwrap();
let _3 = T::from(3.0).unwrap();
let t = x - _1;
T::from(1680).unwrap() * t * t * t * (_7 * x - _3) * x / (self.r * self.r * self.r)
}
}
fn ddddf(&self, x: T) -> T {
let _1 = T::one();
let x = x / self.r;
if x > _1 {
T::zero()
} else {
let _7 = T::from(7.0).unwrap();
let _3 = T::from(3.0).unwrap();
let _5 = T::from(5.0).unwrap();
let t = x - _1;
T::from(1680).unwrap() * t * t * (_5 * x - _3) * (_7 * x - _1)
/ (self.r * self.r * self.r * self.r)
}
}
fn df_l(&self, x: T) -> T {
let _1 = T::one();
let x = x / self.r;
if x > _1 {
T::zero()
} else {
let _5 = T::from(5.0).unwrap();
let t = x - _1;
T::from(56).unwrap() * t * t * t * t * t * (_5 * x + _1) / (self.r * self.r)
}
}
fn g(&self, x: T) -> T {
let _1 = T::one();
let x = x / self.r;
if x > _1 {
T::zero()
} else {
let t = x - _1;
T::from(1680).unwrap() * x * t * t * t * t / (self.r * self.r * self.r)
}
}
fn g_l(&self, x: T) -> T {
let _1 = T::one();
let x = x / self.r;
if x > _1 {
T::zero()
} else {
let tr = (x - _1) / self.r;
T::from(1680).unwrap() * tr * tr * tr * tr
}
}
fn h(&self, x: T, a: T) -> T {
let _1 = T::one();
let x = x / self.r;
if x > _1 {
T::zero()
} else {
let t = _1 - x;
let _3 = T::from(3).unwrap();
let _7 = T::from(7).unwrap();
T::from(1680).unwrap() * t * t * t * (_3 - _7 * x - a * t)
/ (self.r * self.r * self.r * self.r)
}
}
}