Skip to content

Commit bf1f5c7

Browse files
safe math
1 parent 39ab428 commit bf1f5c7

File tree

1 file changed

+35
-24
lines changed

1 file changed

+35
-24
lines changed

pallets/subtensor/src/epoch/math.rs

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,29 +1027,28 @@ pub fn weighted_median_col_sparse(
10271027
// ratio=0: Result = A
10281028
// ratio=1: Result = B
10291029
#[allow(dead_code)]
1030-
pub fn interpolate(
1031-
mat1: &Vec<Vec<I32F32>>,
1032-
mat2: &Vec<Vec<I32F32>>,
1033-
ratio: I32F32,
1034-
) -> Vec<Vec<I32F32>> {
1030+
pub fn interpolate(mat1: &[Vec<I32F32>], mat2: &[Vec<I32F32>], ratio: I32F32) -> Vec<Vec<I32F32>> {
10351031
if ratio == I32F32::from_num(0) {
1036-
return mat1.clone();
1032+
return mat1.to_owned();
10371033
}
10381034
if ratio == I32F32::from_num(1) {
1039-
return mat2.clone();
1035+
return mat2.to_owned();
10401036
}
10411037
assert!(mat1.len() == mat2.len());
1042-
if mat1.len() == 0 {
1038+
if mat1.is_empty() {
10431039
return vec![vec![]; 1];
10441040
}
1045-
if mat1[0].len() == 0 {
1041+
if mat1.first().unwrap_or(&vec![]).is_empty() {
10461042
return vec![vec![]; 1];
10471043
}
1048-
let mut result: Vec<Vec<I32F32>> = vec![vec![I32F32::from_num(0); mat1[0].len()]; mat1.len()];
1049-
for i in 0..mat1.len() {
1050-
assert!(mat1[i].len() == mat2[i].len());
1051-
for j in 0..mat1[i].len() {
1052-
result[i][j] = mat1[i][j] + ratio * (mat2[i][j] - mat1[i][j]);
1044+
let mut result: Vec<Vec<I32F32>> =
1045+
vec![vec![I32F32::from_num(0); mat1.first().unwrap_or(&vec![]).len()]; mat1.len()];
1046+
for (i, (row1, row2)) in mat1.iter().zip(mat2.iter()).enumerate() {
1047+
assert!(row1.len() == row2.len());
1048+
for (j, (&v1, &v2)) in row1.iter().zip(row2.iter()).enumerate() {
1049+
if let Some(res) = result.get_mut(i).unwrap_or(&mut vec![]).get_mut(j) {
1050+
*res = v1.saturating_add(ratio.saturating_mul(v2.saturating_sub(v1)));
1051+
}
10531052
}
10541053
}
10551054
result
@@ -1061,34 +1060,46 @@ pub fn interpolate(
10611060
// ratio=1: Result = B
10621061
#[allow(dead_code)]
10631062
pub fn interpolate_sparse(
1064-
mat1: &Vec<Vec<(u16, I32F32)>>,
1065-
mat2: &Vec<Vec<(u16, I32F32)>>,
1063+
mat1: &[Vec<(u16, I32F32)>],
1064+
mat2: &[Vec<(u16, I32F32)>],
10661065
columns: u16,
10671066
ratio: I32F32,
10681067
) -> Vec<Vec<(u16, I32F32)>> {
10691068
if ratio == I32F32::from_num(0) {
1070-
return mat1.clone();
1069+
return mat1.to_owned();
10711070
}
10721071
if ratio == I32F32::from_num(1) {
1073-
return mat2.clone();
1072+
return mat2.to_owned();
10741073
}
10751074
assert!(mat1.len() == mat2.len());
10761075
let rows = mat1.len();
10771076
let zero: I32F32 = I32F32::from_num(0);
10781077
let mut result: Vec<Vec<(u16, I32F32)>> = vec![vec![]; rows];
10791078
for i in 0..rows {
10801079
let mut row1: Vec<I32F32> = vec![zero; columns as usize];
1081-
for (j, value) in mat1[i].iter() {
1082-
row1[*j as usize] = *value;
1080+
if let Some(row) = mat1.get(i) {
1081+
for (j, value) in row {
1082+
if let Some(entry) = row1.get_mut(*j as usize) {
1083+
*entry = *value;
1084+
}
1085+
}
10831086
}
10841087
let mut row2: Vec<I32F32> = vec![zero; columns as usize];
1085-
for (j, value) in mat2[i].iter() {
1086-
row2[*j as usize] = *value;
1088+
if let Some(row) = mat2.get(i) {
1089+
for (j, value) in row {
1090+
if let Some(entry) = row2.get_mut(*j as usize) {
1091+
*entry = *value;
1092+
}
1093+
}
10871094
}
10881095
for j in 0..columns as usize {
1089-
let interp: I32F32 = row1[j] + ratio * (row2[j] - row1[j]);
1096+
let v1 = row1.get(j).unwrap_or(&zero);
1097+
let v2 = row2.get(j).unwrap_or(&zero);
1098+
let interp = v1.saturating_add(ratio.saturating_mul(v2.saturating_sub(*v1)));
10901099
if zero < interp {
1091-
result[i].push((j as u16, interp))
1100+
if let Some(res) = result.get_mut(i) {
1101+
res.push((j as u16, interp));
1102+
}
10921103
}
10931104
}
10941105
}

0 commit comments

Comments
 (0)