/// <summary>
        /// Calculates the theoretical volume the alphabet for a chain.
        /// </summary>
        /// <param name="chain">
        /// An estimated chain.
        /// </param>
        /// <param name="alphabet">
        /// Current alphabet.
        /// </param>
        /// <returns>
        /// The theoretical volume the alphabet.
        /// </returns>
        public double TheoryVolume(ComplexChain chain, FrequencyDictionary alphabet)
        {
            double f = 0;
            List<string> wordsList = alphabet.GetWords();
            foreach (string word in wordsList)
            {
                double freq = Frequency(chain, word);
                if (freq > f)
                {
                    f = freq;
                }
            }

            double z = chain.GetLength();
            double k = 1 / Math.Log(f * z);
            double b = (k / f) - 1;
            double v = (k * z) - b;
            return v;
        }
        /// <summary>
        /// The initialize method.
        /// </summary>
        /// <param name="chain">
        /// The chain.
        /// </param>
        /// <param name="windowLength">
        /// The window length.
        /// </param>
        /// <param name="step">
        /// The step.
        /// </param>
        private void Initialize(ComplexChain chain, int windowLength, int step)
        {
            try
            {
                int chainLength = chain.GetLength();

                if ((chainLength < windowLength) || (windowLength == 0) || ((step < 1) || (step > chainLength)))
                {
                    throw new Exception();
                }
            }
            catch (Exception)
            {
            }

            this.chain = chain.Clone();
            this.windowLength = windowLength;
            this.step = step;
            CursorPosition = -step;
            CalculateMaxShifts();
        }
 /// <summary>
 /// The frequency.
 /// </summary>
 /// <param name="chain">
 /// The chain.
 /// </param>
 /// <param name="word">
 /// The word.
 /// </param>
 /// <returns>
 /// The <see cref="double"/>.
 /// </returns>
 public double Frequency(ComplexChain chain, string word)
 {
     var temp = new List<object>(chain.Substring(0, chain.GetLength()));
     return Frequency(temp, word) / (double)chain.GetLength();
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="EndIterator"/> class.
 /// </summary>
 /// <param name="chain">
 /// The chain.
 /// </param>
 /// <param name="length">
 /// Length of a word (window of cutting)
 /// </param>
 /// <param name="step">
 /// The number of elements through which the pointer will jump at the next iteration
 /// </param>
 public EndIterator(ComplexChain chain, int length, int step)
     : base(chain, length, step)
 {
     CursorPosition = chain.GetLength() - windowLength + 1;
 }
 /// <summary>
 /// Extracts new words and their places of occurrence from a current word sequence
 /// </summary>
 /// <param name="sequence">the current word sequence</param>
 public void Fill(ComplexChain sequence)
 {
     Clear();
     for (int index = 0; index < sequence.GetLength(); index++)
     {
         Put(sequence[index].ToString(), index);
     }
 }
        /// <summary>
        /// The equals.
        /// </summary>
        /// <param name="complexChain">
        /// The complex chain.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        public bool Equals(ComplexChain complexChain)
        {
            if (complexChain.GetLength() != GetLength())
            {
                return false;
            }

            for (int index = 0; index < complexChain.GetLength(); index++)
            {
                if (!this[index].ToString().Equals(complexChain[index].ToString()))
                {
                    return false;
                }
            }

            return true;
        }
        /// <summary>
        /// The concat.
        /// </summary>
        /// <param name="sequence">
        /// The sequence.
        /// </param>
        /// <returns>
        /// The <see cref="ComplexChain"/>.
        /// </returns>
        public ComplexChain Concat(ComplexChain sequence)
        {
            if (sequence.IsEmpty())
            {
                return this;
            }

            ComplexChain temp = Clone();

            ClearAndSetNewLength(GetLength() + sequence.GetLength());
            for (int i = 0; i < temp.GetLength(); i++)
            {
                this[i] = temp[i];
            }

            for (int j = 0; j < sequence.GetLength(); j++)
            {
                this[j + temp.GetLength()] = sequence[j];
            }

            return this;
        }