use crate::ad::AD;
use crate::op::id::NUMBER_OP;
use crate::IndexT;
use crate::tape::sealed::ThisThreadTape;
use crate::atom::sealed::AtomEvalVec;
#[cfg(doc)]
use crate::{
doc_generic_v,
doc_generic_e,
};
#[cfg(doc)]
pub fn doc_common_arguments() {}
pub type ForwardZero<V, E> = fn(
_var_zero : &mut Vec<E> ,
_con : &Vec<V> ,
_flag : &Vec<bool> ,
_arg : &[IndexT] ,
_res : usize ,
);
pub fn panic_zero<V, E> (
_var_zero : &mut Vec<E> ,
_con : &Vec<V> ,
_flag : &Vec<bool> ,
_arg : &[IndexT] ,
_res : usize ,
) { panic!(); }
pub type ForwardOne<V, E> = fn(
_var_zero : &Vec<E> ,
_var_one : &mut Vec<E> ,
_con : &Vec<V> ,
_flag : &Vec<bool> ,
_arg : &[IndexT] ,
_res : usize ,
);
pub type ReverseOne<V, E> = fn(
_var_zero : &Vec<E> ,
_var_one : &mut Vec<E> ,
_con : &Vec<V> ,
_flag : &Vec<bool> ,
_arg : &[IndexT] ,
_res : usize ,
);
pub fn panic_one<V, E> (
_var_zero : &Vec<E> ,
_var_one : &mut Vec<E> ,
_con : &Vec<V> ,
_flag : &Vec<bool> ,
_arg : &[IndexT] ,
_res : usize ,
) { panic!(); }
pub type ArgVarIndex = fn(
_arg_var_index : &mut Vec<IndexT> ,
_flag : &Vec<bool> ,
_arg : &[IndexT] ,
);
fn panic_arg_var_index(
_arg_var_index : &mut Vec<IndexT> ,
_flag : &Vec<bool> ,
_arg : &[IndexT] ,
) { panic!() }
pub type RustSrc = fn(
_n_domain : usize ,
_flag : &Vec<bool> ,
_arg : &[IndexT] ,
_res : usize ,
) -> String;
pub fn panic_rust_src(
_n_domain : usize ,
_flag : &Vec<bool> ,
_arg : &[IndexT] ,
_op_index : usize ,
) -> String
{ panic!() }
#[derive(Clone)]
pub struct OpInfo<V> {
pub name : &'static str,
pub forward_0_value : ForwardZero<V, V>,
pub forward_0_ad : ForwardZero<V, AD<V> >,
pub forward_1_value : ForwardOne<V, V>,
pub forward_1_ad : ForwardOne<V, AD<V> >,
pub reverse_1_value : ReverseOne<V, V>,
pub reverse_1_ad : ReverseOne<V, AD<V> >,
pub arg_var_index : ArgVarIndex,
pub rust_src : RustSrc,
}
pub fn op_info_vec<V>() -> Vec< OpInfo<V> >
where
for<'a> V : std::ops::AddAssign<&'a V> ,
for<'a> &'a V : std::ops::Add<&'a AD<V>, Output = AD<V> > ,
for<'a> &'a V : std::ops::Add<&'a V, Output = V> ,
for<'a> &'a V : std::ops::Sub<&'a AD<V>, Output = AD<V> > ,
for<'a> &'a V : std::ops::Sub<&'a V, Output = V> ,
for<'a> &'a V : std::ops::Mul<&'a AD<V>, Output = AD<V> > ,
for<'a> &'a V : std::ops::Mul<&'a V, Output = V> ,
for<'a> &'a V : std::ops::Div<&'a AD<V>, Output = AD<V> > ,
for<'a> &'a V : std::ops::Div<&'a V, Output = V> ,
V : Clone + From<f32> + ThisThreadTape + AtomEvalVec
{
let empty = OpInfo {
name : &"panic",
forward_0_value : panic_zero::<V, V>,
forward_0_ad : panic_zero::<V, AD<V>>,
forward_1_value : panic_one::<V, V>,
forward_1_ad : panic_one::<V, AD<V>>,
reverse_1_value : panic_one::<V, V>,
reverse_1_ad : panic_one::<V, AD<V>>,
arg_var_index : panic_arg_var_index,
rust_src : panic_rust_src,
};
let mut result : Vec< OpInfo<V> > = vec![empty ; NUMBER_OP as usize];
crate::op::add::set_op_info::<V>(&mut result);
crate::op::sub::set_op_info::<V>(&mut result);
crate::op::mul::set_op_info::<V>(&mut result);
crate::op::div::set_op_info::<V>(&mut result);
crate::op::call::set_op_info::<V>(&mut result);
result
}
pub trait GlobalOpInfoVec
where
Self : Sized + 'static,
{
fn get() -> &'static std::sync::LazyLock< Vec< OpInfo<Self> > >;
}
macro_rules! impl_global_op_info_vec{ ($V:ty) => {
#[doc = concat!(
"Operator information used when evaluating `",
stringify!($V), "`, and `AD<", stringify!($V), ">` operations"
) ]
impl crate::op::info::GlobalOpInfoVec for $V {
fn get() -> &'static LazyLock<
Vec< crate::op::info::OpInfo<$V> >
> {
pub static OP_INFO_VEC :
LazyLock< Vec< crate::op::info::OpInfo<$V> > > =
LazyLock::new(
|| crate::op::info::op_info_vec::<$V>()
);
&OP_INFO_VEC
}
}
} }
pub(crate) use impl_global_op_info_vec;