///|
pub fn order_barycenter(
g : Graph,
movable? : Array[String] = [],
) -> Array[OrderBarycenterEntry] {
let out = []
for v in movable {
let in_v = g.in_edges(v)
if in_v.is_empty() {
out.push({ v, barycenter: None, weight: None })
} else {
let mut sum = 0.0
let mut weight = 0.0
for e in in_v {
let edge_weight = order_barycenter_edge_weight(g.edge_obj(e))
let node_u = g.node(e.v)
let u_order = node_u.get_int_or("order", 0).to_double()
sum = sum + edge_weight * u_order
weight = weight + edge_weight
}
out.push({ v, barycenter: Some(sum / weight), weight: Some(weight) })
}
}
out
}
///|
fn order_barycenter_edge_weight(label : Value?) -> Double {
if value_as_attrs(label) is Some(attrs) {
attrs.get_float_or("weight", 1.0)
} else if value_as_int(label) is Some(v) {
v.to_double()
} else if value_as_float(label) is Some(v) {
v
} else {
1.0
}
}