Skip to content

Commit

Permalink
feat!: Update strum and ordered-float dependencies and change Fro…
Browse files Browse the repository at this point in the history
…m<LogProb> into TryFrom<LogProb> for NotNan<f64>. (#491)

* Update `strum` crates

Figure we'll need to change eventually.

* Upgrade Ordered Float

ordered-float ditched their From<f64> methods for NotNan and instead made them TryFrom<f64> (reem/rust-ordered-float@39f76bb).  This change makes sense because From trait implementations generally shouldn’t panic, which the implementation did if the f64 was a NaN, and so TryFrom is more appropriate.  This commit accounts for this change in the upgrade

* Remove Deprecated Function Call

`ndarray` has renamed `genrows()` to `rows()`

* Formatting Fix

* Update CHANGELOG

* `From -> `TryFrom`

The conversion from LogProb is not guaranteed to succeed, so we use `TryFrom` instead of `From`, as per the Rust docs:

```Note: The From trait must not fail. The From trait is intended for perfect conversions. If the conversion can fail or is not perfect, use TryFrom.```

Note this does change the API.

* Apply suggestions from code review

Co-authored-by: Adam Azarchs <adam.azarchs@10xgenomics.com>

* Update CHANGELOG.md

* Update Cargo.toml

* Fix build issue.

Co-authored-by: Adam Azarchs <adam.azarchs@10xgenomics.com>
Co-authored-by: Johannes Köster <johannes.koester@uni-due.de>
  • Loading branch information
3 people committed Aug 19, 2022
1 parent 976e27d commit 57ccf8f
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 25 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,7 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).


## [0.41.0](https://www.github.com/rust-bio/rust-bio/compare/v0.40.0...v0.41.0) (2022-03-30)


Expand Down
6 changes: 3 additions & 3 deletions Cargo.toml
Expand Up @@ -37,16 +37,16 @@ serde_derive = "1.0"
approx = ">=0.3, <0.6"
custom_derive = "0.1"
newtype_derive = "0.1"
ordered-float = "1.0"
ordered-float = "2.0"
regex = { version = "1.3", default-features = false, features = ["std", "perf"] }
multimap = ">=0.6, <0.9"
fxhash = "0.2"
statrs = ">= 0.11, < 0.16"
bio-types = ">=0.11.0"
pest = { version = "2", optional = true }
pest_derive = { version = "2", optional = true }
strum = ">= 0.16, < 0.24"
strum_macros = ">= 0.16, < 0.24"
strum = ">= 0.16, < 0.25"
strum_macros = ">= 0.16, < 0.25"
getset = ">=0.0.9, <0.2"
enum-map = ">=0.6.4, <2"
triple_accel = ">=0.3, <0.5"
Expand Down
2 changes: 1 addition & 1 deletion src/pattern_matching/pssm/mod.rs
Expand Up @@ -296,7 +296,7 @@ pub trait Motif {
let bits = Self::get_bits();
let scores = self.get_scores();
let mut tot = 0.0;
for row in scores.genrows() {
for row in scores.rows() {
tot += bits - ent(row.iter());
}
tot
Expand Down
32 changes: 15 additions & 17 deletions src/stats/probs/adaptive_integration.rs
Expand Up @@ -5,7 +5,7 @@

use std::cmp;
use std::collections::HashMap;
use std::convert::Into;
use std::convert::{Into, TryFrom};
use std::hash::Hash;
use std::{
fmt::Debug,
Expand Down Expand Up @@ -43,7 +43,7 @@ use ordered_float::NotNan;
/// );
/// abs_diff_eq!(integral.exp(), 0.682, epsilon=0.01);
/// ```
pub fn ln_integrate_exp<T, F>(
pub fn ln_integrate_exp<T, F, E>(
mut density: F,
min_point: T,
max_point: T,
Expand All @@ -57,10 +57,11 @@ where
+ Div<NotNan<f64>, Output = T>
+ Mul<Output = T>
+ Into<f64>
+ From<f64>
+ TryFrom<f64, Error = E>
+ Ord
+ Debug
+ Hash,
E: Debug,
F: FnMut(T) -> LogProb,
f64: From<T>,
{
Expand Down Expand Up @@ -97,50 +98,47 @@ where
left = middle.unwrap();
}
}
// After that loop, we are guaranteed that middle.is_some().
let middle = middle.unwrap();
let first_middle = first_middle.unwrap();
// METHOD: add additional grid point in the initially abandoned arm
if middle < first_middle {
grid_point(
middle_grid_point(first_middle.unwrap(), max_point),
&mut probs,
);
grid_point(middle_grid_point(first_middle, max_point), &mut probs);
} else {
grid_point(
middle_grid_point(min_point, first_middle.unwrap()),
&mut probs,
);
grid_point(middle_grid_point(min_point, first_middle), &mut probs);
}
// METHOD additionally investigate small interval around the optimum
for point in linspace(
cmp::max(
middle.unwrap() - (max_resolution.into() * 3.0).into(),
T::try_from(middle.into() - max_resolution.into() * 3.0).unwrap(),
min_point,
)
.into(),
middle.unwrap().into(),
middle.into(),
4,
)
.take(3)
.chain(
linspace(
middle.unwrap().into(),
middle.into(),
cmp::min(
middle.unwrap() + (max_resolution.into() * 3.0).into(),
T::try_from(middle.into() + max_resolution.into() * 3.0).unwrap(),
max_point,
)
.into(),
4,
)
.skip(1),
) {
grid_point(point.into(), &mut probs);
grid_point(T::try_from(point).unwrap(), &mut probs);
}

let sorted_grid_points: Vec<f64> = probs.keys().sorted().map(|point| (*point).into()).collect();

// METHOD:
// Step 2: integrate over grid points visited during the binary search.
LogProb::ln_trapezoidal_integrate_grid_exp::<f64, _>(
|_, g| *probs.get(&T::from(g)).unwrap(),
|_, g| *probs.get(&T::try_from(g).unwrap()).unwrap(),
&sorted_grid_points,
)
}
10 changes: 6 additions & 4 deletions src/stats/probs/mod.rs
Expand Up @@ -10,6 +10,7 @@ pub mod adaptive_integration;
pub mod cdf;
pub mod errors;

use std::convert::TryFrom;
use std::f64;
use std::iter;
use std::mem;
Expand All @@ -18,7 +19,7 @@ use std::ops::{Add, AddAssign, Div, Mul, Sub, SubAssign};
use itertools::Itertools;
use itertools_num::linspace;
use num_traits::{Float, Zero};
use ordered_float::NotNan;
use ordered_float::{FloatIsNan, NotNan};

use crate::utils::FastExp;

Expand Down Expand Up @@ -401,9 +402,10 @@ impl From<NotNan<f64>> for LogProb {
}
}

impl From<LogProb> for NotNan<f64> {
fn from(p: LogProb) -> NotNan<f64> {
NotNan::from(*p)
impl TryFrom<LogProb> for NotNan<f64> {
type Error = FloatIsNan;
fn try_from(p: LogProb) -> Result<Self, Self::Error> {
NotNan::new(*p)
}
}

Expand Down

0 comments on commit 57ccf8f

Please sign in to comment.