1use crate::tree::Tree;
8use float_cmp::{ApproxEq, F64Margin};
9
10pub fn attribute(item: usize) -> usize {
12 item / 2
13}
14
15pub fn item_type(item: usize) -> usize {
17 item % 2
18}
19
20pub fn item(attribute: usize, item_type: usize) -> usize {
22 attribute * 2 + item_type
23}
24
25pub fn float_is_null(value: f64) -> bool {
27 value.approx_eq(
28 0.0,
29 F64Margin {
30 ulps: 2,
31 epsilon: 0.0,
32 },
33 )
34}
35
36pub fn compute_entropy(classes_support: &[usize]) -> f64 {
38 let support = classes_support.iter().sum::<usize>();
39 let mut entropy = 0f64;
40 for class_support in classes_support {
41 let p = match support {
42 0 => 0f64,
43 _ => *class_support as f64 / support as f64,
44 };
45
46 let mut log_val = 0f64;
47 if p > 0. {
48 log_val = p.log2();
49 }
50 entropy += -p * log_val;
51 }
52 entropy
53}
54
55pub fn get_tree_root_gain(tree: &Tree) -> f64 {
57 tree.get_node(tree.get_root_index())
58 .map_or(0.0, |node| node.value.metric.unwrap_or(0.0))
59}
60
61pub fn get_tree_root_error(tree: &Tree) -> f64 {
63 tree.get_node(tree.get_root_index())
64 .map_or(<f64>::INFINITY, |node| node.value.error)
65}