I need the user of my library crate be able to specify which activation function a struct Node will use, but also provide a default. It is also needed that the user-specified function be passed through a building factory. My current solution is abbreviated here:
lib.rs:
pub struct Configuration {
activation_function: Box<dyn Fn(f64) -> f64>,
}
impl Configuration {
pub fn new_default() -> Configuration {
Configuration {
activation_function: Box::new(|x| 1.0 / (1.0 + f64::exp(x))),
}
}
pub fn activation_function(mut self, val: Box<dyn Fn(f64) -> f64>) -> Configuration {
self.activation_function = val;
self
}
}
pub struct Node {
pub net: f64,
pub activation: f64,
}
impl Node {
pub fn activate(&mut self, config: &Configuration) {
self.activation = (*config.activation_function)(self.net);
}
}
main.rs:
use sandbox::{Configuration, Node};
fn main() {
let config = Configuration::new_default()
.activation_function(Box::new(|x| f64::max(0.2 * x, x)));
let mut node = Node { net: 1.23, activation: 0.0};
node.activate(&config);
println!("{}", node.activation);
}
My problem with this aproach is that the activation function cannot be inlined. As it may be the one of the most frequently called function in the project, speed is of the essence. In profiling this method was significantly slower than using an inline-able function.
I wonder whether the Configuration and Node structs can be made generic over a Fn(f64) -> f64, or alternatively a fn(f64) -> f64, so that the compiler is able to inline this function whenever it is needed within Node.
I tried using a generic const, but apparently those can only be of primitive type. I tried also using the following struct definition, but couldn't get the default_new function to work.
pub struct Configuration<F: Fn(f64) -> f64> {
activation_function: F,
}
Is it even possible in Rust to have a generic parameter of type Fn or fn so that the function is inlined?