// WF returns the Wootton and Federhen complexity of a segment of s defined by // start and end. func WF(s seq.Sequence, start, end int) (cwf float64, err error) { if start < s.Start() || end > s.End() { err = fmt.Errorf("complex: index out of range") return } if start == end { return 0, nil } var N int k := s.Alphabet().Len() logk := math.Log(float64(k)) n := make([]int, k) // tally classes it := s.Alphabet().LetterIndex() for i := start; i < end; i++ { if ind := it[s.At(i).L]; ind >= 0 { N++ n[ind]++ } } // 1/N*log_k(N!/∏i=1..k(n_i!)) cwf = lnFac(N) for i := 0; i < k; i++ { cwf -= lnFac(n[i]) } cwf /= float64(N) * logk return }
// Entropic returns the entropic complexity of a segment of s defined by // start and end. func Entropic(s seq.Sequence, start, end int) (ce float64, err error) { if start < s.Start() || end > s.End() { err = fmt.Errorf("complex: index out of range") return } if start == end { return 0, nil } var N float64 k := s.Alphabet().Len() logk := math.Log(float64(k)) n := make([]float64, k) // tally classes it := s.Alphabet().LetterIndex() for i := start; i < end; i++ { if ind := it[s.At(i).L]; ind >= 0 { N++ n[ind]++ } } // -∑i=1..k((n_i/N)*log_k(n_i/N)) for i := 0; i < k; i++ { if n[i] != 0 { // ignore zero counts ce += n[i] * logBaseK(logk, n[i]/N) } } ce = -ce / N return }
// Z returns the zlib compression estimate of complexity of a segment of s defined by // start and end. func Z(s seq.Sequence, start, end int) (cz float64, err error) { if start < s.Start() || end > s.End() { err = fmt.Errorf("complex: index out of range") return } if start == end { return 0, nil } bc := new(byteCounter) z := zlib.NewWriter(bc) defer z.Close() it := s.Alphabet().LetterIndex() var N float64 for i := start; i < end; i++ { if b := byte(s.At(i).L); it[b] >= 0 { N++ z.Write([]byte{b}) } } z.Close() cz = (float64(*bc - overhead)) / N return }
// Write a single sequence and return the number of bytes written and any error. func (w *Writer) Write(s seq.Sequence) (n int, err error) { var ( _n int enc alphabet.Encoding ) if e, ok := s.(Encoder); ok { enc = e.Encoding() } else { enc = alphabet.Sanger } n, err = w.writeHeader('@', s) if err != nil { return } for i := 0; i < s.Len(); i++ { _n, err = w.w.Write([]byte{byte(s.At(i).L)}) if n += _n; err != nil { return } } _n, err = w.w.Write([]byte{'\n'}) if n += _n; err != nil { return } if w.QID { _n, err = w.writeHeader('+', s) if n += _n; err != nil { return } } else { _n, err = w.w.Write([]byte("+\n")) if n += _n; err != nil { return } } for i := 0; i < s.Len(); i++ { _n, err = w.w.Write([]byte{s.At(i).Q.Encode(enc)}) if n += _n; err != nil { return } } _n, err = w.w.Write([]byte{'\n'}) if n += _n; err != nil { return } return }
// Write a single sequence and return the number of bytes written and any error. func (w *Writer) Write(s seq.Sequence) (n int, err error) { var ( _n int prefix = append([]byte{'\n'}, w.SeqPrefix...) ) id, desc := s.Name(), s.Description() header := make([]byte, 0, len(w.IDPrefix)+len(id)+len(desc)+1) header = append(header, w.IDPrefix...) header = append(header, id...) if len(desc) > 0 { header = append(header, ' ') header = append(header, desc...) } n, err = w.w.Write(header) if err != nil { return n, err } for i := 0; i < s.Len(); i++ { if i%w.Width == 0 { _n, err = w.w.Write(prefix) if n += _n; err != nil { return n, err } } _n, err = w.w.Write([]byte{byte(s.At(i).L)}) if n += _n; err != nil { return n, err } } _n, err = w.w.Write([]byte{'\n'}) if n += _n; err != nil { return n, err } return n, nil }