1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use super::Vector;
/// Returns the maximum component of a vector scaled by the components of a reference vector
///
/// ```text
/// ⎛ |vᵢ| ⎞
/// res = max_i ⎜ ——————————— ⎟
/// ⎝ one + |v0ᵢ| ⎠
/// ```
///
/// # Panics
///
/// This function will panic of v.dim() != v0.dim()
///
/// # Examples
///
/// ```
/// use russell_lab::*;
///
/// let v = Vector::from(&[-9.0, 0.0, 2.0]);
/// let v0 = Vector::from(&[-2.0, -1.0, -1.0]);
/// // Scaled values: 9/(1+2)=3, 0/(1+1)=0, 2/(1+1)=1 → max = 3
/// let res = vec_max_scaled(&v, &v0, 1.0);
/// assert_eq!(res, 3.0);
/// ```
pub fn vec_max_scaled(v: &Vector, v0: &Vector, one: f64) -> f64 {
let m = v.dim();
assert!(v0.dim() == m);
if m == 0 {
return 0.0;
}
let mut res = f64::MIN;
for i in 0..m {
res = f64::max(res, f64::abs(v[i]) / (one + f64::abs(v0[i])));
}
res
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[cfg(test)]
mod tests {
use super::{vec_max_scaled, Vector};
#[test]
fn vec_max_scaled_works() {
let empty = Vector::new(0);
assert_eq!(vec_max_scaled(&empty, &empty, 1.0), 0.0);
let v = Vector::from(&[-2.0, 0.0, 2.0]);
let v0 = Vector::from(&[-1.0, -1.0, -1.0]);
let res = vec_max_scaled(&v, &v0, 1.0);
assert_eq!(res, 1.0);
let v = Vector::from(&[-9.0, 0.0, 2.0]);
let v0 = Vector::from(&[-2.0, -1.0, -1.0]);
let res = vec_max_scaled(&v, &v0, 1.0);
assert_eq!(res, 3.0);
let v = Vector::from(&[-1.0, 0.0, 12.0]);
let v0 = Vector::from(&[-2.0, -1.0, 0.0]);
let res = vec_max_scaled(&v, &v0, 1.0);
assert_eq!(res, 12.0);
let v = Vector::from(&[0.01, -0.01]);
let v0 = Vector::from(&[0.0, 0.0]);
let res = vec_max_scaled(&v, &v0, 1.0);
assert_eq!(res, 0.01);
}
}