Skip to content

Commit

Permalink
feat: added misc module
Browse files Browse the repository at this point in the history
  • Loading branch information
ariostas committed Apr 21, 2024
1 parent 1340719 commit 47956e7
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod factorial;
pub mod misc;
pub mod polynomial;
pub mod pool;
pub mod semigroup;
Expand Down
81 changes: 81 additions & 0 deletions src/misc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//! Miscellaneous
//!
//! This module contains miscellaneous functions needed for some computations.
pub mod error;

use error::MiscError;
use nalgebra::DMatrix;
use std::collections::{HashMap, HashSet};

/// Process the input intersection numbers and find the relevant pairs of indices.
/// For threefolds, the relevant pair of indices are simply all distinct (sorted) pairs.
/// Othersize, the relevant pairs are the indices in the second and third columns,
/// since indices in the first column correspond to reference surfaces.
#[allow(clippy::type_complexity)]
pub fn process_int_nums(
intnums: DMatrix<i32>,
is_threefold: bool,
) -> Result<(HashMap<(usize, usize, usize), i32>, HashSet<(usize, usize)>), MiscError> {
if intnums.ncols() == 0 {
return Err(MiscError::EmptyIntNums);
} else if intnums.nrows() != 4 {
return Err(MiscError::WrongDimIntNums);
}

let mut intnum_dict = HashMap::new();
let mut intnum_idxpairs = HashSet::new();

for col in intnums.column_iter() {
if col[3] == 0 {
continue;
}
let mut tmp_vec: Vec<_> = col.iter().take(3).cloned().collect();
if is_threefold {
tmp_vec.sort_unstable();
intnum_idxpairs.insert((tmp_vec[0] as usize, tmp_vec[1] as usize));
intnum_idxpairs.insert((tmp_vec[0] as usize, tmp_vec[2] as usize));
} else {
tmp_vec[1..=2].sort_unstable();
}
intnum_idxpairs.insert((tmp_vec[1] as usize, tmp_vec[2] as usize));
if *tmp_vec.iter().min().unwrap() < 0 {
return Err(MiscError::NegativeIndex);
}
let tmp_tup = (
tmp_vec[0] as usize,
tmp_vec[1] as usize,
tmp_vec[2] as usize,
);
if intnum_dict.insert(tmp_tup, col[3]).is_some() {
return Err(MiscError::RepeatedIdxIntNums);
}
}

Ok((intnum_dict, intnum_idxpairs))
}

#[cfg(test)]
mod tests {
use super::*;
use nalgebra::dmatrix;

#[test]
fn test_int_nums() {
let intnums = dmatrix![ 0, 0, 0;
1, 1, 2;
1, 2, 3;
-1, 3, 2;];
let result = process_int_nums(intnums.clone(), true);
assert!(result.is_ok());
let (intnum_dict, intnum_idxpairs) = result.unwrap();
assert_eq!(intnum_dict.len(), 3);
assert_eq!(intnum_idxpairs.len(), 6);

let result = process_int_nums(intnums.clone(), false);
assert!(result.is_ok());
let (intnum_dict, intnum_idxpairs) = result.unwrap();
assert_eq!(intnum_dict.len(), 3);
assert_eq!(intnum_idxpairs.len(), 3);
}
}
33 changes: 33 additions & 0 deletions src/misc/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//! A module for errors that can happen in miscellaneous computations.
use core::fmt;

/// An error enum for miscellaneous errors.
#[derive(Debug, Clone)]
pub enum MiscError {
EmptyIntNums,
WrongDimIntNums,
NegativeIndex,
RepeatedIdxIntNums,
}

/// Implement Display trait for PolynomialError.
impl fmt::Display for MiscError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let message = match self {
MiscError::EmptyIntNums => {
"there must be at least one nonzero intersection number"
}
MiscError::WrongDimIntNums => {
"the intersection number must be given as a triplet of indices followed by the intersection number"
}
MiscError::NegativeIndex => {
"indices of intersection numbers must be positive"
}
MiscError::RepeatedIdxIntNums => {
"the input intersection numbers must be uniquely specified"
}
};
write!(f, "{message}")
}
}

0 comments on commit 47956e7

Please sign in to comment.