// 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 }
// 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 }
// 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 }