src/mapping.rs

Sat, 22 Oct 2022 22:28:04 +0300

author
Tuomo Valkonen <tuomov@iki.fi>
date
Sat, 22 Oct 2022 22:28:04 +0300
changeset 2
ac84e995e119
parent 0
9f27689eb130
child 5
59dc4c5883f4
permissions
-rw-r--r--

Convert iteration utilities to GATs

/// Traits for (mathematical) functions.

use std::marker::PhantomData;
use crate::types::{Float};
use serde::Serialize;
use crate::loc::Loc;

pub trait Mapping<Domain> {
    type Codomain;

    fn value(&self, x : Domain) -> Self::Codomain;
}

pub trait RealRefMapping<F : Float, const N : usize>
: for<'a> Mapping<&'a Loc<F, N>, Codomain=F> {}

impl<F : Float, T, const N : usize> RealRefMapping<F, N> for T
where T : for<'a> Mapping<&'a Loc<F, N>, Codomain=F> {}

pub trait DifferentiableMapping<Domain> : Mapping<Domain> {
    type Differential;

    fn differential(&self, x : Domain) -> Self::Differential;
}

pub trait RealMapping<Domain> : Mapping<Domain> where Self::Codomain : Float {
    fn minimise(&self, tolerance : Self::Codomain) -> (Domain, Self::Codomain);
    fn maximise(&self, tolerance : Self::Codomain) -> (Domain, Self::Codomain);
}

//
// Sum
//

#[derive(Serialize, Debug, Clone)]
pub struct Sum<Domain, M : Mapping<Domain>> {
    components : Vec<M>,
    _domain : PhantomData<Domain>,
}

impl<Domain, M> Mapping<Domain> for Sum<Domain,M>
where M : Mapping<Domain>,
      M :: Codomain : std::iter::Sum,
      Domain : Copy {

    type Codomain = M::Codomain;

    fn value(&self, x : Domain) -> Self::Codomain {
        self.components.iter().map(|c| c.value(x)).sum()
    }
}

impl<Domain, M> DifferentiableMapping<Domain> for Sum<Domain,M>
where M : DifferentiableMapping<Domain>,
      M :: Codomain : std::iter::Sum,
      M :: Differential : std::iter::Sum,
      Domain : Copy {

    type Differential = M::Differential;

    fn differential(&self, x : Domain) -> Self::Differential {
        self.components.iter().map(|c| c.differential(x)).sum()
    }
}

mercurial