packages feed

Nussinov78 0.0.1.3 → 0.1.0.0

raw patch · 5 files changed

+209/−208 lines, 5 filesdep +ghc-primdep −BiobaseXNAdep ~ADPfusiondep ~PrimitiveArraydep ~primitivePVP ok

version bump matches the API change (PVP)

Dependencies added: ghc-prim

Dependencies removed: BiobaseXNA

Dependency ranges changed: ADPfusion, PrimitiveArray, primitive, vector

API changes (from Hackage documentation)

- BioInf.Nussinov78: base' :: Primary -> DIM2 -> (Scalar Nuc)
- BioInf.Nussinov78: basepair :: MkViennaPair (t, t1) => t -> t1 -> Bool
- BioInf.Nussinov78: empty :: DIM2 -> Scalar Bool
- BioInf.Nussinov78: fillTable :: PrimMonad m => MArr0 (PrimState m) DIM2 Int -> (DIM2 -> m Int) -> m ()
- BioInf.Nussinov78: h :: (Monad m, Ord a) => Stream m a -> m a
- BioInf.Nussinov78: left :: Nuc -> Int -> Int
- BioInf.Nussinov78: nil :: Bool -> Int
- BioInf.Nussinov78: nussinov78 :: MkPrimary a => a -> [Backtrace]
- BioInf.Nussinov78: nussinov78BT :: Primary -> Arr0 DIM2 Int -> [Backtrace]
- BioInf.Nussinov78: nussinov78Fill :: Primary -> ST s (Arr0 DIM2 Int)
- BioInf.Nussinov78: pair :: Nuc -> Int -> Nuc -> Int
- BioInf.Nussinov78: right :: Int -> Nuc -> Int
- BioInf.Nussinov78: split :: Int -> Int -> Int
- BioInf.Nussinov78: type Backtrace = (Int, String)
+ BioInf.GAPlike: (<**) :: (Monad m, Eq b, Eq e, Show e, Show (m [b])) => Signature m e e -> Signature m b (Stream m b) -> CombSignature m e b
+ BioInf.GAPlike: aPairmax :: Monad m => Signature m Int Int
+ BioInf.GAPlike: aPretty :: Monad m => Signature m String (Stream m String)
+ BioInf.GAPlike: backtrack :: Vector Char -> Arr0 DIM2 Int -> [String]
+ BioInf.GAPlike: fillTable :: PrimMonad m => (MTbl E (MArr0 (PrimState m) DIM2 Int), (Int, Int) -> m Int) -> m ()
+ BioInf.GAPlike: gNussinov :: (Monad m, Build x, Build b, Build b1, Build (TransTo b1), StreamElement (BuildStack x), StreamElement (:. (BuildStack b) b1), StreamElement (:. (BuildStack b1) b), StreamElement (:. (:. (BuildStack b) b1) b), StreamElement (:. (BuildStack (TransTo b1)) (TransTo b1)), MkStream m (BuildStack x), MkStream m (:. (BuildStack b) b1), MkStream m (:. (BuildStack b1) b), MkStream m (:. (:. (BuildStack b) b1) b), MkStream m (:. (BuildStack (TransTo b1)) (TransTo b1)), TransToN b1, Apply (StreamArg (BuildStack x) -> a), Apply (StreamArg (:. (BuildStack b) b1) -> a), Apply (StreamArg (:. (BuildStack b1) b) -> a), Apply (StreamArg (:. (:. (BuildStack b) b1) b) -> a), Apply (StreamArg (:. (BuildStack (TransTo b1)) (TransTo b1)) -> a)) => (Fun (StreamArg (BuildStack x) -> a), Fun (StreamArg (:. (BuildStack b) b1) -> a), Fun (StreamArg (:. (BuildStack b1) b) -> a), Fun (StreamArg (:. (:. (BuildStack b) b1) b) -> a), Fun (StreamArg (:. (BuildStack (TransTo b1)) (TransTo b1)) -> a), Stream m a -> t) -> b1 -> b -> x -> (b1, (Int, Int) -> t)
+ BioInf.GAPlike: instance Show (Id [String])
+ BioInf.GAPlike: nussinov78 :: [Char] -> (Int, [String])
+ BioInf.GAPlike: nussinov78Fill :: Vector Char -> ST s (Arr0 DIM2 Int)
+ BioInf.GAPlike: type CombSignature m e b = (() -> (e, m (Stream m b)), Char -> (e, m (Stream m b)) -> (e, m (Stream m b)), (e, m (Stream m b)) -> Char -> (e, m (Stream m b)), Char -> (e, m (Stream m b)) -> Char -> (e, m (Stream m b)), (e, m (Stream m b)) -> (e, m (Stream m b)) -> (e, m (Stream m b)), Stream m (e, m (Stream m b)) -> m (Stream m b))
+ BioInf.GAPlike: type Signature m a r = (() -> a, Char -> a -> a, a -> Char -> a, Char -> a -> Char -> a, a -> a -> a, Stream m a -> m r)

Files

+ BioInf/GAPlike.hs view
@@ -0,0 +1,164 @@+{-# LANGUAGE NoMonomorphismRestriction #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE PackageImports #-}+{-# LANGUAGE ScopedTypeVariables #-}++module BioInf.GAPlike where++import Control.Monad+import Control.Monad.Primitive+import Control.Monad.ST+import Control.Monad.ST+import Data.Char (toUpper, ord)+import Data.Primitive+import Data.Vector.Fusion.Stream as S+import Data.Vector.Fusion.Stream.Monadic as SM+import Data.Vector.Fusion.Stream.Size+import Data.Vector.Fusion.Util+import Prelude as P+import "PrimitiveArray" Data.Array.Repa.Index+import qualified Data.Vector.Unboxed as VU++import ADP.Fusion.GAPlike+import Data.PrimitiveArray as PA+import Data.PrimitiveArray.Zero.Unboxed as PA++import Debug.Trace+import Control.Arrow (second)++++-- The signature++type Signature m a r =+  ( ()   -> a+  , Char -> a    -> a+  , a    -> Char -> a+  , Char -> a    -> Char -> a+  , a    -> a    -> a+  , SM.Stream m a -> m r+  )++-- the grammar++gNussinov (empty,left,right,pair,split,h) s b e =+  ( s, (  empty <<< e         |||+          left  <<< b % s     |||+          right <<<     s % b |||+          pair  <<< b % s % b |||+          split <<<  s' % s'  ... h)+  ) where s' = transToN s+{-# INLINE gNussinov #-}++-- pairmax algebra++aPairmax :: (Monad m) => Signature m Int Int+aPairmax = (empty,left,right,pair,split,h) where+  empty   _   = 0+  left    b s = s+  right s b   = s+  pair  l s r = if basepair l r then 1+s else -999999+  {-# INLINE [0] pair #-}+  split  l r  = l+r+  h = SM.foldl1' max+  basepair l r = f l r where+    f 'C' 'G' = True+    f 'G' 'C' = True+    f 'A' 'U' = True+    f 'U' 'A' = True+    f 'G' 'U' = True+    f 'U' 'G' = True+    f _   _   = False+  {-# INLINE basepair #-}+{-# INLINE aPairmax #-}++aPretty :: (Monad m) => Signature m String (SM.Stream m String)+aPretty = (empty,left,right,pair,split,h) where+  empty _     = ""+  left  b s   = "." P.++ s+  right   s b = s P.++ "."+  pair  l s r = "(" P.++ s P.++ ")"+  split l   r = l P.++ r+  h = return . id+{-# INLINE aPretty #-}++type CombSignature m e b =+  ( () -> (e, m (SM.Stream m b))+  , Char -> (e, m (SM.Stream m b)) -> (e, m (SM.Stream m b))+  , (e, m (SM.Stream m b)) -> Char -> (e, m (SM.Stream m b))+  , Char -> (e, m (SM.Stream m b)) -> Char -> (e, m (SM.Stream m b))+  , (e, m (SM.Stream m b)) -> (e, m (SM.Stream m b)) -> (e, m (SM.Stream m b))+  , SM.Stream m (e, m (SM.Stream m b)) -> m (SM.Stream m b)+  )++instance Show (Id [String]) where+  show xs = show $ unId xs++(<**)+  :: (Monad m, Eq b, Eq e, Show e, Show (m [b]))+  => Signature m e e+  -> Signature m b (SM.Stream m b)+  -> CombSignature m e b+(<**) f s = (empty,left,right,pair,split,h) where+  (emptyF,leftF,rightF,pairF,splitF,hF) = f+  (emptyS,leftS,rightS,pairS,splitS,hS) = s++  empty e         = (emptyF e   , return $ SM.singleton (emptyS e))+  left b (x,ys)   = (leftF b x  , ys >>= return . SM.map (\y -> leftS b y  ))+  right  (x,ys) b = (rightF x b , ys >>= return . SM.map (\y -> rightS  y b))+  pair l (x,ys) r = (pairF l x r, ys >>= return . SM.map (\y -> pairS l y r))+  split (x,ys) (s,ts) = (splitF x s, ys >>= \ys' -> ts >>= \ts' -> return $ SM.concatMap (\y -> SM.map (\t -> splitS y t) ts') ys')+  h xs = do+    hfs <- hF $ SM.map fst xs+    let phfs = SM.concatMapM snd . SM.filter ((hfs==) . fst) $ xs+    -- trace (">>>" P.++ show (hfs, SM.toList phfs)) $ hS phfs+    hS phfs+++-- * Boilerplate and driver, will be moved to library++nussinov78 inp = (arr ! (Z:.0:.n),bt) where+  (_,Z:._:.n) = bounds arr+  len  = P.length inp+  vinp = VU.fromList . P.map toUpper $ inp+  arr  = runST (nussinov78Fill $ vinp)+  bt   = backtrack vinp arr+{-# NOINLINE nussinov78 #-}++-- type TBL s = Tbl E (PA.MArr0 s DIM2 Int)++nussinov78Fill :: forall s . VU.Vector Char -> ST s (Arr0 DIM2 Int)+nussinov78Fill inp = do+  let n = VU.length inp+  t' <- fromAssocsM (Z:.0:.0) (Z:.n:.n) 0 []+  let t = mtblE t'+  let b = Chr inp+  let e = Empty+  fillTable $ gNussinov aPairmax t b e+  freeze t'+{-# NOINLINE nussinov78Fill #-}++fillTable :: PrimMonad m => (MTbl E (MArr0 (PrimState m) DIM2 Int), ((Int,Int) -> m Int)) -> m ()+fillTable (MTbl tbl, f) = do+  let (_,Z:.n:._) = boundsM tbl+  forM_ [n,n-1..0] $ \i -> forM_ [i..n] $ \j -> do+    v <- f (i,j)+    v `seq` writeM tbl (Z:.i:.j) v+{-# INLINE fillTable #-}++-- * backtracking++backtrack (inp :: VU.Vector Char) (tbl :: PA.Arr0 DIM2 Int) = unId . SM.toList . unId $ g (0,n) where+  n = VU.length inp+  c = Chr inp+  e = Empty+  t = bttblE tbl (g :: BTfun Id String)+  (_,g) = gNussinov (aPairmax <** aPretty) t c e+{-# INLINE backtrack #-}+
− BioInf/Nussinov78.hs
@@ -1,167 +0,0 @@-{-# LANGUAGE PackageImports #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE DoAndIfThenElse #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE NoMonomorphismRestriction #-}---- | Strict, scalar nussinov78 algorithm.--module BioInf.Nussinov78 where--import Control.Arrow (first,second,(***))-import Control.Monad-import Control.Monad.Primitive-import Control.Monad.ST-import Control.Monad.State.Lazy-import "PrimitiveArray" Data.Array.Repa.Index-import qualified Data.Vector.Fusion.Stream as P-import qualified Data.Vector.Fusion.Stream.Monadic as S-import qualified Data.Vector.Unboxed as VU--import Biobase.Primary-import Biobase.Secondary.Vienna--import Data.PrimitiveArray-import Data.PrimitiveArray.Unboxed.Zero--import ADP.Fusion-import ADP.Fusion.Monadic-import ADP.Fusion.Monadic.Internal------ | Simple RNA folding with basepair maximization.--nussinov78 inp = arr `seq` bt where-  (_,Z:._:.n) = bounds arr-  arr = runST (nussinov78Fill . mkPrimary $ inp)-  bt  = nussinov78BT (mkPrimary inp) arr-{-# NOINLINE nussinov78 #-}---- | The actual Nussinov78 folding algorithm.--nussinov78Fill :: Primary -> ST s (Arr0 DIM2 Int)-nussinov78Fill inp = do-  let base = base' inp-      {-# INLINE base #-}-  let n = let (_,Z:.l) = bounds inp in l+1-  s <- fromAssocsM (Z:.0:.0) (Z:.n:.n) 0 []--  fillTable s (-                nil   <<< empty               |||-                left  <<< base -~~ s          |||-                right <<<          s ~~- base |||-                pair  <<< base -~~ s ~~- base |||-                split <<<       s +~+ s       ... h-              )-  freeze s-{-# INLINE nussinov78Fill #-}---- | Fill the single table with values in an orderly fashion. The order in--- which we fill depends on the algorithm.--fillTable :: PrimMonad m => MArr0 (PrimState m) DIM2 Int -> (DIM2 -> m Int) -> m ()-fillTable tbl f = do-  let (_,Z:.n:._) = boundsM tbl-  forM_ [n,n-1..0] $ \i -> forM_ [i..n] $ \j -> do-    v <- f (Z:.i:.j)-    writeM tbl (Z:.i:.j) v-    return ()-{-# INLINE fillTable #-}---- | Request the single character enclosed by (i,i+1), with i+1==j--base' :: Primary -> DIM2 -> (Scalar Nuc)-base' inp (Z:.i:.j) = Scalar $ inp ! (Z:.i)-{-# INLINE base' #-}---- | True, if the subword at ij is empty.--empty :: DIM2 -> Scalar Bool-empty (Z:.i:.j) = Scalar $ i==j---- | The base case of our recursion.--nil :: Bool -> Int-nil b = if b then 0 else -999999---- | A single nucleotide to the left. Note that "x" is monadic. In 'nussinov'--- we are in the ST monad, here we just know that we are in a monad.--left :: Nuc -> Int -> Int-left l x = x-{-# INLINE left #-}---- | A single nucleotide to the right.--right :: Int -> Nuc -> Int-right x r = x-{-# INLINE right #-}---- | Pair function--pair :: Nuc -> Int -> Nuc -> Int-pair l x r-  | basepair l r = x+1-  | otherwise    = -999999-{-# INLINE pair #-}---- | Combine the partition of x next-to y.--split :: Int -> Int -> Int-split = (+)-{-# INLINE split #-}---- | Determine if two characters form a legal basepair.--basepair l r-  | mkViennaPair (l,r) /= vpNS = True-basepair _   _   = False-{-# INLINE basepair #-}---- | the grammar makes sure that we at least have "nil #<< empty" in the stream-h = S.foldl1' max-{-# INLINE h #-}------ * backtrace secondary structures--type Backtrace = (Int,String)--nussinov78BT :: Primary -> Arr0 DIM2 Int -> [Backtrace]-nussinov78BT inp s = P.toList $ grammar (Z:.0:.n) where-  base = base' inp-  n = let (_,(Z:._:.l)) = bounds s in l-  s' :: DIM2 -> Scalar (DIM2,Int)-  s' ij = Scalar $ (ij,s!ij)--  grammar :: DIM2 -> P.Stream Backtrace-  grammar = (-      nilBT   <<< empty                |||-      leftBT  <<< base -~~ s'          |||-      rightBT <<<          s' ~~- base |||-      pairBT  <<< base -~~ s' ~~- base |||-      splitBT <<<      s' +~+ s'       ..@ hBT)--  nilBT :: Bool -> (Int, P.Stream Backtrace)-  nilBT b      = if b then (0, P.singleton (0,"")) else (0, P.empty)--  leftBT :: Nuc -> (DIM2,Int) -> (Int, P.Stream Backtrace)-  leftBT _ (ij,x)   = (x, P.map (second ("."++)) $ grammar ij)--  rightBT :: (DIM2,Int) -> Nuc -> (Int, P.Stream Backtrace)-  rightBT (ij,x) _  = (x, P.map (second (++".")) $ grammar ij)--  pairBT :: Nuc -> (DIM2,Int) -> Nuc -> (Int, P.Stream Backtrace)-  pairBT l (ij,x) r = if basepair l r then (x+1, P.map (second (\a -> "("++a++")")) $ grammar ij) else (0, P.empty)--  splitBT :: (DIM2,Int) -> (DIM2,Int) -> (Int, P.Stream Backtrace)-  splitBT (ij,x) (kl,y)  = (x+y, P.concatMap (\(s1,bts1) -> P.map (\(s2,bts2) -> (s1+s2,bts1++bts2)) $ grammar kl) $ grammar ij)--  hBT ij = P.concatMap (\(score,bts) -> P.map (first (const score)) bts) . P.filter (\(score,bts) -> score == s!ij)-
C/nussinov.c view
@@ -1,16 +1,19 @@-//#include <stdlib.h>-//#include <stdio.h>+#include <stdlib.h>+#include <stdio.h>+#include <string.h> +int nussinov (int, char *);+ int main () {-  char *p;+  char p[10000];   int n;   int e;-  while (1==scanf ("%as", &p)) { // only GNU C+  while (1==scanf ("%9999s", &p)) { // only GNU C     n = strlen(p);     e = nussinov (n, p);     printf ("%s %d\n", p, e);-    free(p);-    p=0;+    //free(p);+    //p=0;   };   return 0; }
Nussinov78.cabal view
@@ -1,5 +1,5 @@ name:           Nussinov78-version:        0.0.1.3+version:        0.1.0.0 author:         Christian Hoener zu Siederdissen, 2011-2012 copyright:      Christian Hoener zu Siederdissen, 2011-2012 homepage:       http://www.tbi.univie.ac.at/~choener/adpfusion@@ -18,15 +18,14 @@                 .                 This algorithm is simple enough to be used as a tutorial-type                 example. It also shows that efficient code is possible. The-                ADPfusion code compared to C is slower by a factor of only 1.8.+                ADPfusion code compared to C is slower by a factor of only 1.2.                 We plan to improve upon this.                 .                 A number of helper functions currently present in                 BioInf.Nussinov78 will later move in their own library.                 .-                If possible, build using the GHC llvm backend, and GHC-7.2.2.-                GHC-7.4.x produces very bad code on my system, please benchmark-                using 7.2.2.+                Build using GHC-7.6.1, the new code generator and llvm for best+                performance.                 .                 For comparison, a version of the algorithm written in C is                 available under C/nussinov.c. Use at least@@ -37,50 +36,34 @@ Extra-Source-Files:   C/nussinov.c -Flag llvm-  description: build using llvm backend-  default: True  - library   build-depends:     base >= 4 && < 5,     mtl            >= 2,-    primitive      == 0.4.*   ,-    vector         == 0.9.*   ,-    PrimitiveArray == 0.2.2.0 ,-    BiobaseXNA     == 0.6.2.5 ,-    ADPfusion      == 0.0.1.2+    primitive      == 0.5.*   ,+    vector         == 0.10.*  ,+    PrimitiveArray == 0.4.0.0 ,+--    BiobaseXNA     == 0.6.2.5 ,+    ADPfusion      == 0.1.* ,+    ghc-prim   exposed-modules:-    BioInf.Nussinov78+--    BioInf.Nussinov78+    BioInf.GAPlike   ghc-options:-    -O2-    -funbox-strict-fields-    -funfolding-use-threshold100-    -funfolding-keeness-factor100-  if flag (llvm)-    ghc-options:-      -fllvm -optlo-O3 -optlo-inline -optlo-std-compile-opts+    -O2 -fllvm -optlo-O3 -optlo-inline -optlo-std-compile-opts    executable Nussinov78   build-depends:---    from above   main-is:     Nussinov78.hs   other-modules:-    BioInf.Nussinov78+--    BioInf.Nussinov78   ghc-options:-    -rtsopts-    -O2-    -funbox-strict-fields-    -funfolding-use-threshold100-    -funfolding-keeness-factor100-  if flag (llvm)-    ghc-options:-      -fllvm -optlo-O3 -optlo-inline -optlo-std-compile-opts+    -fnew-codegen -fllvm -O2 -funbox-strict-fields -optlo-O3 -optlo-std-compile-opts   
Nussinov78.hs view
@@ -6,16 +6,34 @@ module Main where  import Text.Printf+import System.Environment -import BioInf.Nussinov78+-- import BioInf.Nussinov78+import qualified BioInf.GAPlike as G    main = do-  xs <- fmap lines getContents-  mapM_ doNussinov78 xs+  as <- getArgs+  print as+  case as of+  {-+    [] -> do xs <- fmap lines getContents+             mapM_ doNussinov78 xs -}+    ["gaplike"] -> do xs <- fmap lines getContents+                      mapM_ (doGAPlike 0) xs+    ["gaplike",k] -> do xs <- fmap lines getContents+                        mapM_ (doGAPlike (read k)) xs +{- doNussinov78 inp = do   putStrLn inp   let rs = nussinov78 inp   mapM_ (\(e,bt) -> putStr bt >> printf " %5d\n" e) $ take 10 rs+-}++doGAPlike :: Int -> String -> IO ()+doGAPlike k inp = do+  let (n,bt) = G.nussinov78 inp+  n `seq` printf "%s %d\n" inp n+  mapM_ putStrLn $ take k bt