123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- ;; The Computer Language Shootout
- ;; http://shootout.alioth.debian.org/
- ;; This is a Kawa implementation of the knucelotide benchmark.
- ;; This is is fairly low-level - it by-passes the Scheme APIs
- ;; to use pure Java libraries. It does make use of
- ;; gnu.kawa.util.AbstractHashTable, but it sort-of cheats by getting
- ;; down into implementation internals.
- ;;
- ;; Original Kawa version based on mzscheme version,
- ;; with some bits based on Java version contributed by James McIlree.
- (define-simple-class StrIntNode (java.util.Map$Entry)
- (next ::StrIntNode)
- (hash :: int)
- (key ::java.lang.String)
- (count ::int)
- ((getKey) key)
- ((getValue) ::object count))
- (define (make-node key::string hash::int count::int) ::StrIntNode
- (let ((n (StrIntNode)))
- (set! n:key key)
- (set! n:hash hash)
- (set! n:count count)
- n))
- (define-simple-class StrIntHashTable (gnu.kawa.util.AbstractHashTable)
- ((getEntryHashCode entry) (as StrIntNode entry):hash)
- ((getEntryNext entry) (as StrIntNode entry):next)
- ((setEntryNext entry next) (set! (as StrIntNode entry):next next))
- ((allocEntries n) (StrIntNode[] size: n))
- ((makeEntry key hash value) (make-node key hash value))
- ;; FIXME this code should be made into library code.
- ((toNodeArray) ::StrIntNode[]
- (let* ((arr ::StrIntNode[] table)
- (length arr:length)
- (n ::int ((this):size))
- (result (StrIntNode[] length: n))
- (j ::int 0))
- (do ((i ::int (- length 1) (- i 1)))
- ((< i 0) result)
- (do ((node ::StrIntNode (table i)
- node:next))
- ((eq? node #!null) #!void)
- (set! (result j) node)
- (set! j (+ j 1)))))))
- (define (all-counts (len :: int) (dna :: java.lang.String))
- (let ((table (StrIntHashTable)))
- (let loop ((s :: int (- (string-length dna) len)))
- (let* ((key (dna:substring s (+ s len)))
- (node ::StrIntNode (table:getNode key)))
- (if (eq? node #!null)
- ;; Non-optimal - requires recalculating hashCode.
- (table:put key (key:hashCode) 1)
- (set! node:count (+ node:count 1))))
- (if (> s 0)
- (loop (- s 1))))
- table))
- (define node-comparator ::java.util.Comparator
- (object (java.util.Comparator)
- ((compare o1 o2) ::int
- (let ((v1 ::int (as StrIntNode o1):count)
- (v2 ::int (as StrIntNode o2):count))
- (cond ((> v1 v2) -1)
- ((< v1 v2) 1)
- (else 0))))
- ((equals o)::boolean (eq? o (this)))))
- (define (write-freqs table::StrIntHashTable) ::void
- (let* ((content (table:toNodeArray))
- (size content:length)
- (total ::double
- (let ((sum ::int 0))
- (do ((i ::int 0 (+ i 1)))
- ((>= i size) sum)
- (set! sum (+ sum (content i):count)))
- sum)))
- (java.util.Arrays:sort content node-comparator)
- (do ((i ::int 0 (+ i 1)))
- ((>= i size))
- (let ((a (content i)))
- (format #t "~a ~,3f~%"
- a:key
- (* 100 (/ (as double a:count) total)))))))
- (define (write-one-freq table::StrIntHashTable key::string)
- (let* ((node ::StrIntNode (table:getNode key))
- (cnt (if (eq? node #!null) 0 node:count)))
- (format #t "~a\t~a~%" cnt key)))
- (define dna
- (let ((in :: input-port (current-input-port))
- (sb (java.lang.StringBuilder)))
- ;; Skip to ">THREE ..."
- (do ()
- ((let ((line (in:readLine)))
- (or (eq? line #!null) (line:startsWith ">THREE")))))
- (let loop ()
- (let ((line (in:readLine)))
- (cond (line
- (sb:append line)
- (loop)))))
- ((sb:toString):toUpperCase)))
- ;; 1-nucleotide counts:
- (write-freqs (all-counts 1 dna))
- (newline)
- ;; 2-nucleotide counts:
- (write-freqs (all-counts 2 dna))
- (newline)
- ;; Specific sequences:
- (for-each (lambda (seq)
- (write-one-freq (all-counts (string-length seq) dna)
- seq))
- '("GGT" "GGTA" "GGTATT" "GGTATTTTAATT" "GGTATTTTAATTTATAGT"))
|