Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
lan496 committed Apr 7, 2024
1 parent 60f3328 commit 92c6a90
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 90 deletions.
2 changes: 1 addition & 1 deletion moyo/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ pub use transformation::{Linear, OriginShift};
pub use cell::orbits_from_permutations;
#[allow(unused_imports)]
pub use operation::traverse;
pub use tolerance::EPS;
pub use tolerance::{ToleranceHandler, EPS};
pub use transformation::{Transformation, UnimodularLinear, UnimodularTransformation};
69 changes: 68 additions & 1 deletion moyo/src/base/tolerance.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,74 @@
use log::warn;

use super::error::MoyoError;

pub const EPS: f64 = 1e-8;

const INITIAL_SYMMETRY_SEARCH_STRIDE: f64 = 2.0;

#[derive(Debug, Copy, Clone)]
pub enum AngleTolerance {
Radian(f64),
Default,
}

pub const EPS: f64 = 1e-8;
pub struct ToleranceHandler {
pub symprec: f64,
pub angle_tolerance: AngleTolerance,
stride: f64,
prev_error: Option<MoyoError>,
}

impl ToleranceHandler {
pub fn new(symprec: f64, angle_tolerance: AngleTolerance) -> Self {
Self {
symprec,
angle_tolerance,
stride: INITIAL_SYMMETRY_SEARCH_STRIDE,
prev_error: None,
}
}

pub fn update(&mut self, err: MoyoError) {
// Update stride
if !self.prev_error.is_none() && self.prev_error != Some(err) {
self.stride = self.stride.sqrt()
}
self.prev_error = Some(err);

// Update tolerances
(self.symprec, self.angle_tolerance) = match err {
MoyoError::TooSmallToleranceError => self.increase_tolerance(),
MoyoError::TooLargeToleranceError => self.reduce_tolerance(),
_ => (self.symprec, self.angle_tolerance),
}
}

fn increase_tolerance(&self) -> (f64, AngleTolerance) {
let symprec = self.symprec * self.stride;
let angle_tolerance = if let AngleTolerance::Radian(angle) = self.angle_tolerance {
AngleTolerance::Radian(angle * self.stride)
} else {
AngleTolerance::Default
};
warn!(
"Increase tolerance to symprec={}, angle_tolerance={:?}",
symprec, angle_tolerance
);
(symprec, angle_tolerance)
}

fn reduce_tolerance(&self) -> (f64, AngleTolerance) {
let symprec = self.symprec / self.stride;
let angle_tolerance = if let AngleTolerance::Radian(angle) = self.angle_tolerance {
AngleTolerance::Radian(angle / self.stride)
} else {
AngleTolerance::Default
};
warn!(
"Reduce tolerance to symprec={}, angle_tolerance={:?}",
symprec, angle_tolerance
);
(symprec, angle_tolerance)
}
}
106 changes: 18 additions & 88 deletions moyo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ pub mod math;
pub mod search;
pub mod symmetrize;

use log::warn;
use nalgebra::Matrix3;

use crate::base::{AngleTolerance, Cell, MoyoError, Operations, OriginShift, Transformation};
use crate::base::{
AngleTolerance, Cell, MoyoError, Operations, OriginShift, ToleranceHandler, Transformation,
};
use crate::data::{HallNumber, Number, Setting};
use crate::identify::SpaceGroup;
use crate::search::{PrimitiveCell, PrimitiveSymmetrySearch};
Expand Down Expand Up @@ -154,111 +155,40 @@ impl MoyoDataset {
}

const MAX_SYMMETRY_SEARCH_TRIALS: usize = 16;
const INITIAL_SYMMETRY_SEARCH_STRIDE: f64 = 2.0;

fn iterative_symmetry_search(
cell: &Cell,
symprec: f64,
angle_tolerance: AngleTolerance,
) -> Result<(PrimitiveCell, PrimitiveSymmetrySearch, f64, AngleTolerance), MoyoError> {
let mut symprec = symprec;
let mut angle_tolerance = angle_tolerance;
let mut stride: f64 = INITIAL_SYMMETRY_SEARCH_STRIDE;
let mut prev_error: Option<MoyoError> = None;

fn _increase_tolerance(
symprec: f64,
angle_tolerance: AngleTolerance,
stride: f64,
) -> (f64, AngleTolerance) {
let symprec = symprec * stride;
let angle_tolerance = if let AngleTolerance::Radian(angle) = angle_tolerance {
AngleTolerance::Radian(angle * stride)
} else {
AngleTolerance::Default
};
warn!(
"Increase tolerance to symprec={}, angle_tolerance={:?}",
symprec, angle_tolerance
);
(symprec, angle_tolerance)
}

fn _reduce_tolerance(
symprec: f64,
angle_tolerance: AngleTolerance,
stride: f64,
) -> (f64, AngleTolerance) {
let symprec = symprec / stride;
let angle_tolerance = if let AngleTolerance::Radian(angle) = angle_tolerance {
AngleTolerance::Radian(angle / stride)
} else {
AngleTolerance::Default
};
warn!(
"Reduce tolerance to symprec={}, angle_tolerance={:?}",
symprec, angle_tolerance
);
(symprec, angle_tolerance)
}

fn _update_stride(
err: MoyoError,
prev_error: Option<MoyoError>,
stride: f64,
) -> (Option<MoyoError>, f64) {
let stride = if !prev_error.is_none() && prev_error != Some(err) {
stride.sqrt()
} else {
stride
};
(Some(err), stride)
}

fn handle_tolerance_error(
err: MoyoError,
prev_error: Option<MoyoError>,
stride: f64,
symprec: f64,
angle_tolerance: AngleTolerance,
) -> (Option<MoyoError>, f64, f64, AngleTolerance) {
let (new_error, new_stride) = _update_stride(err, prev_error, stride);
let (new_symprec, new_angle_tolerance) = match err {
MoyoError::TooSmallToleranceError => {
_increase_tolerance(symprec, angle_tolerance, new_stride)
}
MoyoError::TooLargeToleranceError => {
_reduce_tolerance(symprec, angle_tolerance, new_stride)
}
_ => (symprec, angle_tolerance),
};
(new_error, new_stride, new_symprec, new_angle_tolerance)
}
let mut tolerance_handler = ToleranceHandler::new(symprec, angle_tolerance);

for _ in 0..MAX_SYMMETRY_SEARCH_TRIALS {
match PrimitiveCell::new(cell, symprec) {
match PrimitiveCell::new(cell, tolerance_handler.symprec) {
Ok(prim_cell) => {
match PrimitiveSymmetrySearch::new(&prim_cell.cell, symprec, angle_tolerance) {
match PrimitiveSymmetrySearch::new(
&prim_cell.cell,
tolerance_handler.symprec,
tolerance_handler.angle_tolerance,
) {
Ok(symmetry_search) => {
return Ok((prim_cell, symmetry_search, symprec, angle_tolerance));
return Ok((
prim_cell,
symmetry_search,
tolerance_handler.symprec,
tolerance_handler.angle_tolerance,
));
}
Err(err @ MoyoError::TooSmallToleranceError)
| Err(err @ MoyoError::TooLargeToleranceError) => {
(prev_error, stride, symprec, angle_tolerance) = handle_tolerance_error(
err,
prev_error,
stride,
symprec,
angle_tolerance,
);
tolerance_handler.update(err);
}
Err(err) => return Err(err),
}
}
Err(err @ MoyoError::TooSmallToleranceError)
| Err(err @ MoyoError::TooLargeToleranceError) => {
(prev_error, stride, symprec, angle_tolerance) =
handle_tolerance_error(err, prev_error, stride, symprec, angle_tolerance);
tolerance_handler.update(err);
}
Err(err) => return Err(err),
}
Expand Down

0 comments on commit 92c6a90

Please sign in to comment.