extern crate lightmotif;
use lightmotif::abc::Background;
use lightmotif::abc::Dna;
use lightmotif::num::ArrayLength;
use lightmotif::num::StrictlyPositive;
use lightmotif::num::U1;
use lightmotif::num::U16;
use lightmotif::num::U32;
use lightmotif::pli::Maximum;
use lightmotif::pli::Pipeline;
use lightmotif::pli::Score;
use lightmotif::pli::Stripe;
use lightmotif::pwm::CountMatrix;
use lightmotif::scan::Scanner;
use lightmotif::scores::StripedScores;
use lightmotif::seq::EncodedSequence;
const SEQUENCE: &str = include_str!("../benches/ecoli.txt");
const PATTERNS: &[&str] = &["GTTGACCTTATCAAC", "GTTGATCCAGTCAAC"];
const N: usize = SEQUENCE.len() / 10;
fn test_argmax_f32<C: StrictlyPositive + ArrayLength, P: Maximum<f32, C>>(pli: &P) {
let generic = Pipeline::generic();
let seq = &SEQUENCE[..N];
let encoded = EncodedSequence::<Dna>::encode(seq).unwrap();
let mut striped = generic.stripe(encoded);
let bg = Background::<Dna>::uniform();
let cm = PATTERNS
.iter()
.map(EncodedSequence::encode)
.map(Result::unwrap)
.collect::<Result<CountMatrix<Dna>, _>>()
.unwrap();
let pbm = cm.to_freq(0.1);
let pssm = pbm.to_scoring(bg);
striped.configure(&pssm);
let scores: StripedScores<f32, C> = generic.score(pssm, striped);
let best = scores
.unstripe()
.iter()
.cloned()
.enumerate()
.max_by(|x, y| x.1.partial_cmp(&y.1).unwrap())
.unwrap();
let m = pli.argmax(&scores).unwrap();
assert_eq!(scores.offset(m), best.0);
assert_eq!(scores.matrix()[m], best.1);
}
mod generic {
use super::*;
#[test]
fn argmax_f32() {
let pli = Pipeline::<Dna, _>::generic();
super::test_argmax_f32::<U1, _>(&pli);
super::test_argmax_f32::<U16, _>(&pli);
super::test_argmax_f32::<U32, _>(&pli);
}
}
mod dispatch {
use super::*;
#[test]
fn argmax_f32() {
let pli = Pipeline::<Dna, _>::dispatch();
super::test_argmax_f32(&pli);
}
#[test]
fn scanner_max() {
let generic = Pipeline::generic();
let seq = &SEQUENCE[..N];
let encoded = EncodedSequence::<Dna>::encode(seq).unwrap();
let mut striped = generic.stripe(encoded);
let bg = Background::<Dna>::uniform();
let cm = PATTERNS
.iter()
.map(EncodedSequence::encode)
.map(Result::unwrap)
.collect::<Result<CountMatrix<Dna>, _>>()
.unwrap();
let pbm = cm.to_freq(0.1);
let pssm = pbm.to_scoring(bg);
striped.configure(&pssm);
let scores: StripedScores<f32, _> = generic.score(&pssm, &striped);
let best = scores
.unstripe()
.iter()
.cloned()
.enumerate()
.max_by(|x, y| x.1.partial_cmp(&y.1).unwrap())
.unwrap();
let m = Scanner::new(&pssm, &striped).max().unwrap();
assert_eq!(m.position(), best.0);
assert_eq!(m.score(), best.1);
}
}
#[cfg(target_feature = "sse2")]
mod sse2 {
use super::*;
#[test]
fn argmax_f32() {
let pli = Pipeline::<Dna, _>::sse2().unwrap();
super::test_argmax_f32::<U16, _>(&pli);
super::test_argmax_f32::<U32, _>(&pli);
}
}
#[cfg(target_feature = "avx2")]
mod avx2 {
use super::*;
#[test]
fn argmax_f32() {
let pli = Pipeline::<Dna, _>::avx2().unwrap();
super::test_argmax_f32(&pli);
}
}
#[cfg(target_feature = "neon")]
mod neon {
use super::*;
#[test]
fn argmax_f32() {
let pli = Pipeline::<Dna, _>::neon().unwrap();
super::test_argmax_f32::<U16, _>(&pli);
super::test_argmax_f32::<U32, _>(&pli);
}
}