Sequence class.
상속: BaseChain, IBaseObject
        /// <summary>
        /// The create.
        /// </summary>
        /// <param name="source">
        /// The source.
        /// </param>
        /// <param name="link">
        /// The link.
        /// </param>
        /// <returns>
        /// The <see cref="Chain"/>.
        /// </returns>
        /// <exception cref="ArgumentException">
        /// Thrown if link is unacceptable.
        /// </exception>
        public static Chain Create(Chain source, Link link)
        {
            if (link != Link.Start && link != Link.End && link != Link.CycleEnd && link != Link.CycleStart)
            {
                throw new ArgumentException("Unknown link", "link");
            }

            var result = new Chain(source.GetLength());
            Alphabet sourceAlphabet = source.Alphabet;
            var entries = new int[sourceAlphabet.Cardinality];

            var intervals = new int[sourceAlphabet.Cardinality][];

            for (int j = 0; j < sourceAlphabet.Cardinality; j++)
            {
                var intervalsManager = new CongenericIntervalsManager(source.CongenericChain(j));
                intervals[j] = intervalsManager.GetIntervals(link);
            }

            for (int i = 0; i < source.GetLength(); i++)
            {
                var elementIndex = sourceAlphabet.IndexOf(source[i]);
                int entry = entries[elementIndex]++;
                var interval = intervals[elementIndex][entry];
                result.Set(new ValueInt(interval), i);
            }

            return result;
        }
        public void WriteTest()
        {
            var messages = new List<ValueString>(12)
                               {
                                   new ValueString('1'),
                                   new ValueString('2'),
                                   new ValueString('1'),
                                   new ValueString('3'),
                                   new ValueString('3'),
                                   new ValueString('1'),
                                   new ValueString('2'),
                                   new ValueString('1'),
                                   new ValueString('2'),
                                   new ValueString('2'),
                                   new ValueString('3'),
                                   new ValueString('1')
                               };

            var toWrite = new Chain(12);
            var iteratorWrite = new IteratorWritableStart(toWrite);
            int i = 0;
            while (iteratorWrite.Next())
            {
                iteratorWrite.WriteValue(messages[i++]);
            }

            Assert.AreEqual(chainToIterate, toWrite);
        }
        public void Initialize()
        {
            // Creating sequence containing 12 elements.
            // |a|d|b|a|a|c|b|b|a|a|c|a|
            testChain = new Chain(12);
            testChain.Set((ValueString)"a", 0);
            testChain.Set((ValueString)"d", 1);
            testChain.Set((ValueString)"b", 2);
            testChain.Set((ValueString)"a", 3);
            testChain.Set((ValueString)"a", 4);
            testChain.Set((ValueString)"c", 5);
            testChain.Set((ValueString)"b", 6);
            testChain.Set((ValueString)"b", 7);
            testChain.Set((ValueString)"a", 8);
            testChain.Set((ValueString)"a", 9);
            testChain.Set((ValueString)"c", 10);
            testChain.Set((ValueString)"a", 11);

            secondTestChain = new Chain(12);
            secondTestChain.Set((ValueString)"a", 0);
            secondTestChain.Set((ValueString)"a", 1);
            secondTestChain.Set((ValueString)"a", 2);
            secondTestChain.Set((ValueString)"a", 3);
            secondTestChain.Set((ValueString)"a", 4);
            secondTestChain.Set((ValueString)"a", 5);
            secondTestChain.Set((ValueString)"b", 6);
            secondTestChain.Set((ValueString)"a", 7);
            secondTestChain.Set((ValueString)"a", 8);
            secondTestChain.Set((ValueString)"a", 9);
            secondTestChain.Set((ValueString)"b", 10);
            secondTestChain.Set((ValueString)"a", 11);
        }
        /// <summary>
        /// The compare sequences by subsequences.
        /// </summary>
        /// <param name="characteristicTypeLinkId">
        /// The characteristic type link id.
        /// </param>
        /// <param name="notationId">
        /// The notation id.
        /// </param>
        /// <param name="firstChains">
        /// The first chains.
        /// </param>
        /// <param name="secondChains">
        /// The second chains.
        /// </param>
        /// <param name="difference">
        /// The difference.
        /// </param>
        /// <param name="excludeType">
        /// The exclude type.
        /// </param>
        /// <returns>
        /// The <see cref="double"/>.
        /// </returns>
        public double CompareSequencesBySubsequences(int characteristicTypeLinkId, int notationId, Chain[] firstChains, Chain[] secondChains, double difference, string excludeType)
        {
            var firstSequenceCharacteristics = CalculateCharacteristic(characteristicTypeLinkId, firstChains);

            var secondSequenceCharacteristics = CalculateCharacteristic(characteristicTypeLinkId, secondChains);

            var similarSubsequences = new List<IntPair>();

            for (int i = 0; i < firstSequenceCharacteristics.Count; i++)
            {
                for (int j = 0; j < secondSequenceCharacteristics.Count; j++)
                {
                    if (System.Math.Abs(firstSequenceCharacteristics[i] - secondSequenceCharacteristics[j]) <= difference)
                    {
                        similarSubsequences.Add(new IntPair(i, j));

                        if (excludeType == "Exclude")
                        {
                            firstSequenceCharacteristics[i] = double.NaN;
                            secondSequenceCharacteristics[j] = double.NaN;
                        }
                    }
                }
            }

            return similarSubsequences.Count * 200d / (firstChains.Length + secondChains.Length);
        }
        public void LevelOneTest()
        {
            var cycleTestChainLevel1 = new Chain("adbaacbbaacaa");

            var rebulder = new NullCycleSpaceReorganizer(1);
            var result = rebulder.Reorganize(testChain);
            Assert.AreEqual(cycleTestChainLevel1, result);
        }
        public void LevelFiveTest()
        {
            var cycleTestChainLevel5 = new Chain("adbaacbbaacaadbaa");

            var reorganizer = new NullCycleSpaceReorganizer(5);
            var result = reorganizer.Reorganize(testChain);
            Assert.AreEqual(cycleTestChainLevel5, result);
        }
 public void ToStringTest()
 {
     var stringExpected = "abcabccc";
     var chain = new Chain(stringExpected);
     Assert.AreEqual(stringExpected, chain.ToString());
     var baseChain = new BaseChain(stringExpected);
     Assert.AreEqual(stringExpected, baseChain.ToString());
 }
        /// <summary>
        /// The calculate characteristics.
        /// </summary>
        /// <param name="chain">
        /// The chain.
        /// </param>
        /// <param name="characteristic">
        /// The characteristic for calculation.
        /// </param>
        /// <returns>
        /// The <see cref="List{Double}"/>.
        /// </returns>
        private List<double> CalculateCharacteristics(Chain chain, List<LinkedCharacteristic> characteristic)
        {
            var characteristics = new List<double>(characteristic.Count);
            foreach (LinkedCharacteristic calculator in characteristic)
            {
                characteristics.Add(calculator.Calculator.Calculate(chain, calculator.Link));
            }

            return characteristics;
        }
        /// <summary>
        /// Calculation method.
        /// </summary>
        /// <param name="chains">
        /// The chains.
        /// </param>
        /// <param name="calculators">
        /// The calculators.
        /// </param>
        /// <param name="links">
        /// The links.
        /// </param>
        /// <param name="characteristicTypeLinkIds">
        /// The characteristic type link ids.
        /// </param>
        /// <returns>
        /// The <see cref="T:double[][]"/>.
        /// </returns>
        public static double[][] Calculate(Chain[][] chains, IFullCalculator[] calculators, Link[] links, int[] characteristicTypeLinkIds)
        {
            var newCharacteristics = new List<Characteristic>();
            var characteristics = new double[chains.Length][];
            var sequenceIds = chains.SelectMany(c => c).Select(c => c.Id).Distinct();

            Dictionary<long, Dictionary<int, double>> dbCharacteristics;
            using (var db = new LibiadaWebEntities())
            {
                dbCharacteristics = db.Characteristic
                                              .Where(c => characteristicTypeLinkIds.Contains(c.CharacteristicTypeLinkId) && sequenceIds.Contains(c.SequenceId))
                                              .ToArray()
                                              .GroupBy(c => c.SequenceId)
                                              .ToDictionary(c => c.Key, c => c.ToDictionary(ct => ct.CharacteristicTypeLinkId, ct => ct.Value));
            }

            for (int i = 0; i < chains.Length; i++)
            {
                characteristics[i] = new double[calculators.Length];

                for (int j = 0; j < calculators.Length; j++)
                {
                    long sequenceId = chains[i][j].Id;
                    chains[i][j].FillIntervalManagers();

                    Dictionary<int, double> sequenceDbCharacteristics;
                    if (!dbCharacteristics.TryGetValue(sequenceId, out sequenceDbCharacteristics))
                    {
                        sequenceDbCharacteristics = new Dictionary<int, double>();
                    }

                    if (!sequenceDbCharacteristics.TryGetValue(characteristicTypeLinkIds[j], out characteristics[i][j]))
                    {
                        characteristics[i][j] = calculators[j].Calculate(chains[i][j], links[j]);
                        var currentCharacteristic = new Characteristic
                        {
                            SequenceId = sequenceId,
                            CharacteristicTypeLinkId = characteristicTypeLinkIds[j],
                            Value = characteristics[i][j]
                        };

                        newCharacteristics.Add(currentCharacteristic);
                    }
                }
            }

            // trying to save calculated characteristics to database
            using (var db = new LibiadaWebEntities())
            {
                var characteristicRepository = new CharacteristicRepository(db);
                characteristicRepository.TrySaveCharacteristicsToDatabase(newCharacteristics);
            }

            return characteristics;
        }
 public void Initialize()
 {
     testChain = new Chain(8);
     testChain.Set((ValueString)"A", 0);
     testChain.Set((ValueString)"G", 1);
     testChain.Set((ValueString)"T", 2);
     testChain.Set((ValueString)"A", 3);
     testChain.Set((ValueString)"A", 4);
     testChain.Set((ValueString)"G", 5);
     testChain.Set((ValueString)"T", 6);
     testChain.Set((ValueString)"C", 7);
 }
        public void ToStringDelimiterTest()
        {
            var source = "abcabccc";
            var chain = new Chain(source);
            var baseChain = new BaseChain(source);

            var expected = "a b c a b c c c";
            Assert.AreEqual(expected, chain.ToString(" "));
            Assert.AreEqual(expected, baseChain.ToString(" "));

            expected = "acbcccacbcccccc";
            Assert.AreEqual(expected, chain.ToString("c"));
            Assert.AreEqual(expected, baseChain.ToString("c"));
        }
        public void ToStringLongDelimiterTest()
        {
            var source = "abcabccc";
            var chain = new Chain(source);
            var baseChain = new BaseChain(source);

            var expected = "a - b - c - a - b - c - c - c";
            Assert.AreEqual(expected, chain.ToString(" - "));
            Assert.AreEqual(expected, baseChain.ToString(" - "));

            expected = "a, b, c, a, b, c, c, c";
            Assert.AreEqual(expected, chain.ToString(", "));
            Assert.AreEqual(expected, baseChain.ToString(", "));
        }
        /// <summary>
        /// Method that creates chain of "first occurrences of different elements".
        /// </summary>
        /// <param name="source">
        /// Source chain.
        /// </param>
        /// <returns>/
        /// Dissimilar chain.
        /// </returns>
        public static Chain Create(BaseChain source)
        {
            var result = new Chain(source.GetLength());
            Alphabet sourceAlphabet = source.Alphabet;
            var entries = new int[sourceAlphabet.Cardinality];

            for (int i = 0; i < source.GetLength(); i++)
            {
                int elementIndex = sourceAlphabet.IndexOf(source[i]);
                int entry = ++entries[elementIndex];
                result.Set(new ValueInt(entry), i);
            }

            return result;
        }
        /// <summary>
        /// The extract chains.
        /// </summary>
        /// <param name="subsequences">
        /// The subsequences.
        /// </param>
        /// <param name="chainId">
        /// The sequence id.
        /// </param>
        /// <returns>
        /// The <see cref="List{Chain}"/>.
        /// </returns>
        public Chain[] ExtractChains(Subsequence[] subsequences, long chainId)
        {
            var parentChain = commonSequenceRepository.ToLibiadaBaseChain(chainId).ToString();
            var sourceSequence = new Sequence(Alphabets.DNA, parentChain);
            var result = new Chain[subsequences.Length];

            for (int i = 0; i < subsequences.Length; i++)
            {
                result[i] = subsequences[i].Position.Count == 0
                        ? ExtractSimpleSubsequence(sourceSequence, subsequences[i])
                        : ExtractJoinedSubsequence(sourceSequence, subsequences[i]);
            }

            return result;
        }
        /// <summary>
        /// The is valid.
        /// </summary>
        /// <param name="building">
        /// The building.
        /// </param>
        /// <returns>
        /// true if
        /// </returns>
        public bool IsValid(string building)
        {
            var chain = new Chain(building);
            var countCalculator = new ElementsCount();

            var firstCount = (int)countCalculator.Calculate(chain.CongenericChain(0), Link.Start);
            for (int i = 1; i < chain.Alphabet.Cardinality; i++)
            {
                if (firstCount != (int)countCalculator.Calculate(chain.CongenericChain(i), Link.Start))
                {
                    return false;
                }
            }

            return true;
        }
        public void CustomIteratorTest()
        {
            var starts = new List<List<int>> { new List<int> { 0 }, new List<int> { 3 }, new List<int> { 5, 9 } };
            var lengthes = new List<List<int>> { new List<int> { 2 }, new List<int> { 3 }, new List<int> { 2, 1 } };

            var source = new Chain("abcdefghij");

            List<Chain> expected = new List<Chain> { new Chain("ab"), new Chain("def"), new Chain("fgj") };

            var iterator = new CustomIterator(source, starts, lengthes);

            for (int i = 0; iterator.Next(); i++)
            {
                Chain result = (Chain)iterator.Current();

                Assert.AreEqual(expected[i], result);
            }
        }
        public void GetBinaryIntervalIncompleteChainTest()
        {
            // A C A _ C C _ A A A C C A
            // A _ A _ _ _ _ A A A _ _ A
            // _ C _ _ C C _ _ _ _ C C _
            var chain = new Chain(13);

            chain.Set(elements["A"], 0);
            chain.Set(elements["C"], 1);
            chain.Set(elements["A"], 2);

            chain.Set(elements["C"], 4);
            chain.Set(elements["C"], 5);

            chain.Set(elements["A"], 7);
            chain.Set(elements["A"], 8);
            chain.Set(elements["A"], 9);
            chain.Set(elements["C"], 10);
            chain.Set(elements["C"], 11);
            chain.Set(elements["A"], 12);

            var intervalManager = chain.GetRelationIntervalsManager(elements["A"], elements["C"]);
            Assert.AreEqual(1, intervalManager.GetBinaryInterval(1));
            Assert.AreEqual(2, intervalManager.GetBinaryInterval(2));
            Assert.AreEqual(-1, intervalManager.GetBinaryInterval(3));
            Assert.AreEqual(-1, intervalManager.GetBinaryInterval(4));
            Assert.AreEqual(1, intervalManager.GetBinaryInterval(5));
            Assert.AreEqual(-1, intervalManager.GetBinaryInterval(6));
            Assert.AreEqual(-1, intervalManager.GetBinaryInterval(7));

            intervalManager = chain.GetRelationIntervalsManager(elements["C"], elements["A"]);
            Assert.AreEqual(1, intervalManager.GetBinaryInterval(1));
            Assert.AreEqual(-1, intervalManager.GetBinaryInterval(2));
            Assert.AreEqual(2, intervalManager.GetBinaryInterval(3));
            Assert.AreEqual(-1, intervalManager.GetBinaryInterval(4));
            Assert.AreEqual(1, intervalManager.GetBinaryInterval(5));
            Assert.AreEqual(-1, intervalManager.GetBinaryInterval(6));
        }
        public ActionResult Index(
            int[] transformationLinkIds,
            int[] transformationIds,
            int iterationsCount,
            string[] customSequences,
            bool localFile,
            HttpPostedFileBase[] file)
        {
            return Action(() =>
            {
                int sequencesCount = localFile ? Request.Files.Count : customSequences.Length;
                var sourceSequences = new string[sequencesCount];
                var sequences = new string[sequencesCount];
                var names = new string[sequencesCount];

                for (int i = 0; i < sequencesCount; i++)
                {
                    if (localFile)
                    {
                        var sequenceStream = FileHelper.GetFileStream(file[i]);
                        var fastaSequence = NcbiHelper.GetFastaSequence(sequenceStream);
                        sourceSequences[i] = fastaSequence.ConvertToString();
                        names[i] = fastaSequence.ID;
                    }
                    else
                    {
                        sourceSequences[i] = customSequences[i];
                        names[i] = "Custom sequence " + (i + 1) + ". Length: " + customSequences[i].Length;
                    }
                }

                for (int k = 0; k < iterationsCount; k++)
                {
                    var sequence = new Chain(sourceSequences[k]);
                    for (int j = 0; j < iterationsCount; j++)
                    {
                        for (int i = 0; i < transformationIds.Length; i++)
                        {
                            if (transformationIds[i] == 1)
                            {
                                sequence = DissimilarChainFactory.Create(sequence);
                            }
                            else
                            {
                                sequence = HighOrderFactory.Create(sequence, (Link)transformationLinkIds[i]);
                            }
                        }
                    }
                }

                var transformations = new Dictionary<int, string>();
                for (int i = 0; i < transformationIds.Length; i++)
                {
                    var link = ((Link)transformationLinkIds[i]).GetDisplayValue();
                    transformations.Add(i, transformationIds[i] == 1 ? "dissimilar" : "higher order " + link);
                }

                var result = new Dictionary<string, object>
                {
                    { "names", names },
                    { "sequences", sequences },
                    { "transformationsList", transformations },
                    { "iterationsCount", iterationsCount }
                };
                return result;
            });
        }
 public void Initialization()
 {
     chain = new Chain("adbaacbbaaca");
     baseChain = new BaseChain("adbaacbbaaca");
 }
        /// <summary>
        /// Extracts nucleotide sequences from database.
        /// </summary>
        /// <param name="matterIds">
        /// The matter ids.
        /// </param>
        /// <returns>
        /// The <see cref="T:Chain[]"/>.
        /// </returns>
        public Chain[] GetNucleotideChains(long[] matterIds)
        {
            var chains = new Chain[matterIds.Length];

            for (int i = 0; i < matterIds.Length; i++)
            {
                var matterId = matterIds[i];
                var sequenceId = Db.CommonSequence.Single(c => c.MatterId == matterId && c.NotationId == Aliases.Notation.Nucleotide).Id;
                chains[i] = ToLibiadaChain(sequenceId);
            }

            return chains;
        }
        /// <summary>
        /// Calculation method.
        /// </summary>
        /// <param name="chains">
        /// The chains.
        /// </param>
        /// <param name="calculators">
        /// The calculators.
        /// </param>
        /// <param name="links">
        /// The links.
        /// </param>
        /// <param name="rotate">
        /// The rotate flag.
        /// </param>
        /// <param name="complementary">
        /// The complementary flag.
        /// </param>
        /// <param name="rotationLength">
        /// The rotation length.
        /// </param>
        /// <returns>
        /// The <see cref="T:double[][]"/>.
        /// </returns>
        public static double[][] Calculate(Chain[][] chains, IFullCalculator[] calculators, Link[] links, bool rotate, bool complementary, uint? rotationLength)
        {
            var characteristics = new double[chains.Length][];

            for (int i = 0; i < chains.Length; i++)
            {
                characteristics[i] = new double[calculators.Length];

                for (int j = 0; j < calculators.Length; j++)
                {
                    if (complementary)
                    {
                        var sourceSequence = new Sequence(Alphabets.DNA, chains[i][j].ToString());
                        var complementarySequence = sourceSequence.GetReverseComplementedSequence();
                        chains[i][j] = new Chain(complementarySequence.ConvertToString());
                    }

                    if (rotate)
                    {
                        var building = chains[i][j].Building.Rotate(rotationLength ?? 0);
                        var newSequence = building.Select(t => new ValueInt(t)).Cast<IBaseObject>().ToList();
                        chains[i][j] = new Chain(newSequence);
                    }

                    chains[i][j].FillIntervalManagers();

                    characteristics[i][j] = calculators[j].Calculate(chains[i][j], links[j]);
                }
            }

            return characteristics;
        }
        /// <summary>
        /// Calculation method.
        /// </summary>
        /// <param name="chains">
        /// The chains.
        /// </param>
        /// <param name="calculator">
        /// The calculator.
        /// </param>
        /// <param name="link">
        /// The link.
        /// </param>
        /// <param name="characteristicTypeLinkId">
        /// The characteristic type link id.
        /// </param>
        /// <returns>
        /// The <see cref="T:double[]"/>.
        /// </returns>
        public static double[] Calculate(Chain[] chains, IFullCalculator calculator, Link link, int characteristicTypeLinkId)
        {
            var newCharacteristics = new List<Characteristic>();
            var characteristics = new double[chains.Length];
            var sequenceIds = chains.Select(c => c.Id);

            Dictionary<long, double> dbCharacteristics;
            using (var db = new LibiadaWebEntities())
            {
                dbCharacteristics = db.Characteristic
                                              .Where(c => characteristicTypeLinkId == c.CharacteristicTypeLinkId && sequenceIds.Contains(c.SequenceId))
                                              .ToArray()
                                              .GroupBy(c => c.SequenceId)
                                              .ToDictionary(c => c.Key, c => c.Single().Value);
            }

            for (int i = 0; i < chains.Length; i++)
            {
                chains[i].FillIntervalManagers();

                long sequenceId = chains[i].Id;

                if (!dbCharacteristics.TryGetValue(sequenceId, out characteristics[i]))
                {
                    characteristics[i] = calculator.Calculate(chains[i], link);
                    var currentCharacteristic = new Characteristic
                    {
                        SequenceId = sequenceId,
                        CharacteristicTypeLinkId = characteristicTypeLinkId,
                        Value = characteristics[i]
                    };

                    newCharacteristics.Add(currentCharacteristic);
                }
            }

            // trying to save calculated characteristics to database
            using (var db = new LibiadaWebEntities())
            {
                var characteristicRepository = new CharacteristicRepository(db);
                characteristicRepository.TrySaveCharacteristicsToDatabase(newCharacteristics);
            }

            return characteristics;
        }
        public void MarkovChainNotCongenericDynamicOneRangTwoTest()
        {
            // using mock of random generator
            IGenerator generator = new MockGenerator();

            // rank of markov chain is 2 (each element depends on one previous element)
            int markovChainRank = 2;

            // heterogeneity is 1 (there are 2 models - for odd and even positions)
            int notCongenericRank = 1;

            // creating markov chain
            // MarkovChainNotCongenericDynamic<Chain, Chain> MarkovChain = new MarkovChainNotCongenericDynamic<Chain, Chain>(markovChainRank, notCongenericRank, generator);

            // length of generated sequence
            int length = 12;

            // teaching markov chain (TeachingMethod.None means there is no preprocessing)
            // MarkovChain.Teach(TestChain, TeachingMethod.None);

            // Chain Temp = MarkovChain.Generate(length);

            /**
             * Внутри неоднородной марковской цепи существует n однородных марковских цепей. n - порядок неоднородности цепи
             * порядок данных однородных цепей равен порядку неоднородной цепи
             * однородные цепи используются по очереди как при обучении так и  при генерации.
             *
             * В данном тесте внутри неоднородной марковской цепи есть 2 однородные цепи.
             * Матрицы переходных вероятностей (в скобках указано кол-во входений при обучении) в них такие
             *
             * 1. Sequence
             *   first level (unconditional probability)
             *
             *    a| 1/2 (3) |
             *    b| 1/3 (2) |
             *    c| 1/6 (1) |
             *    d| 0 (0)   |
             *
             *   second level (conditional probability taking into account 1 previous element)
             *
             *    |   a  |   b  |  с   |  d   |
             * ---|------|------|------|------|
             *  a |0,3(1)| 0(0) |0,3(1)|0,3(1)|
             * ---|------|------|------|------|
             *  b |0,5(1)|0,5(1)| 0(0) | 0(0) |
             * ---|------|------|------|------|
             *  c | 1(1) | 0(0) | 0(0) | 0(0) |
             * ---|------|------|------|------|
             *  d | 0(0) | 0(0) | 0(0) | 0(0) |
             * ---|------|------|------|------|
             *
             * 2. Sequence
             *   first level (unconditional probability)
             *
             *    a| 2/5 (2) |
             *    b| 1/5 (1) |
             *    c| 1/5 (1) |
             *    d| 1/5 (1) |
             *
             *   second level (conditional probability taking into account 1 previous element)
             *
             *    |   a  |   b  |  с   |  d   |
             * ---|------|------|------|------|
             *  a |0,5(1)| 0(0) |0,5(1)| 0(0) |
             * ---|------|------|------|------|
             *  b | 1(1) | 0(0) | 0(0) | 0(0) |
             * ---|------|------|------|------|
             *  c | 0(0) | 1(1) | 0(0) | 0(0) |
             * ---|------|------|------|------|
             *  d | 0(0) | 1(1) | 0(0) | 0(0) |
             * ---|------|------|------|------|
             *
             *
             * During teaching pairs are added as folowing
             *   |-| |-| |-| |-| |-|   <>- In second markov chain
             * a d b a a c b b a a c a
             * |_| |_| |_| |_| |_| |_| <>- In first markov chain
             *
             */

            // expected result of generation
            var result = new Chain(12);
            result.Set((ValueString)"b", 0); // 1 chain. вероятность по первому уровню. выпало  0,77 Получаем b
            result.Set((ValueString)"a", 1); // 2 chain. вероятность по второму уровню. выпало  0.15 Получаем a
            result.Set((ValueString)"c", 2); // 1 chain. вероятность по второму уровню. выпало  0.96 Получаем с
            result.Set((ValueString)"b", 3); // 2 chain. вероятность по второму уровню. выпало  0.61 Получаем b
            result.Set((ValueString)"a", 4); // 1 chain. вероятность по второму уровню. выпало  0.15 Получаем a
            result.Set((ValueString)"c", 5); // 2 chain. вероятность по второму уровню. выпало  0.85 Получаем c
            result.Set((ValueString)"a", 6); // 1 chain. вероятность по второму уровню. выпало  0.67 Получаем a
            result.Set((ValueString)"c", 7); // 2 chain. вероятность по второму уровню. выпало  0.51 Получаем c
            result.Set((ValueString)"a", 8); // 1 chain. вероятность по второму уровню. выпало  0.71 Получаем a
            result.Set((ValueString)"a", 9); // 2 chain. вероятность по второму уровню. выпало  0.2 Получаем a
            result.Set((ValueString)"c", 10); // 1 chain. вероятность по второму уровню. выпало  0.77 Получаем с
            result.Set((ValueString)"b", 11); // 2 chain. вероятность по второму уровню. выпало  0.15 Получаем b
        }
        /// <summary>
        /// Extracts sequences from database.
        /// </summary>
        /// <param name="matterIds">
        /// The matter ids.
        /// </param>
        /// <param name="notationIds">
        /// The notation ids.
        /// </param>
        /// <param name="languageIds">
        /// The language ids.
        /// </param>
        /// <param name="translatorIds">
        /// The translator ids.
        /// </param>
        /// <returns>
        /// The <see cref="T:Chain[][]"/>.
        /// </returns>
        public Chain[][] GetChains(long[] matterIds, int[] notationIds, int[] languageIds, int?[] translatorIds)
        {
            var chains = new Chain[matterIds.Length][];
            var notationsRepository = new NotationRepository(Db);

            for (int i = 0; i < matterIds.Length; i++)
            {
                var matterId = matterIds[i];
                chains[i] = new Chain[notationIds.Length];

                for (int j = 0; j < notationIds.Length; j++)
                {
                    Notation notation = notationsRepository.Notations.Single(n => n.Id == notationIds[j]);

                    long sequenceId;
                    if (notation.Nature == Nature.Literature)
                    {
                        int languageId = languageIds[j];
                        int? translatorId = translatorIds[j];

                        sequenceId = Db.LiteratureSequence.Single(l =>
                                    l.MatterId == matterId && l.NotationId == notation.Id
                                    && l.LanguageId == languageId
                                    && ((translatorId == null && l.TranslatorId == null)
                                        || (translatorId == l.TranslatorId))).Id;
                    }
                    else
                    {
                        sequenceId = Db.CommonSequence.Single(c => c.MatterId == matterId && c.NotationId == notation.Id).Id;
                    }

                    chains[i][j] = ToLibiadaChain(sequenceId);
                }
            }

            return chains;
        }
        public void MarkovChainNotCongenericZeroRankTwoTest()
        {
            // using mock of random generator
            IGenerator generator = new MockGenerator();

            // rank of markov chain is 2 (each element depends on one previous element)
            const int MarkovChainRank = 2;

            // heterogeneity is 1 (there are 2 models - for odd and even positions)
            const int NoCongenericRank = 0;

            // creating markov chain
            var markovChain = new MarkovChainNotCongenericStatic(MarkovChainRank, NoCongenericRank, generator);

            // length of generated sequence
            const int Length = 30;

            // teaching markov chain (TeachingMethod.None means there is no preprocessing)
            markovChain.Teach(secondTestChain, TeachingMethod.Cycle);

            var temp = markovChain.Generate(Length);

            /*
             * 1. Sequence a a a a a a b a a a b a
             *   first level (unconditional probability)
             *
             *    a| 10/12 (0,83333)  not more than 0,83333|
             *    b| 2/12 (0,16667)  not more than 1|
             *
             *   second level (conditional probability taking into account 1 previous element)
             *
             *    |   a  |   b  |
             * ---|------|------|
             *  a |7/9(7)|2/9(2)|
             * ---|------|------|
             *  b |1,0(1)|0,0(0)|
             * ---|------|------|
             */

            // expected result of generation
            var resultTheory = new Chain(30);
            resultTheory[0] = (ValueString)"a"; // "a" 0.77;
            resultTheory[1] = (ValueString)"a"; // "a" 0.15;
            resultTheory[2] = (ValueString)"b"; // "b" 0.96;
            resultTheory[3] = (ValueString)"a"; // "a" 0.61;
            resultTheory[4] = (ValueString)"a"; // "a" 0.15;
            resultTheory[5] = (ValueString)"b"; // "b" 0.85;
            resultTheory[6] = (ValueString)"a"; // "a" 0.67;
            resultTheory[7] = (ValueString)"a"; // "a" 0.51;
            resultTheory[8] = (ValueString)"a"; // "a" 0.71;
            resultTheory[9] = (ValueString)"a"; // "a" 0.2;
            resultTheory[10] = (ValueString)"a"; // "a" 0.77;
            resultTheory[11] = (ValueString)"a"; // "a" 0.15;
            resultTheory[12] = (ValueString)"b"; // "b" 0.96;
            resultTheory[13] = (ValueString)"a"; // "a" 0.61;
            resultTheory[14] = (ValueString)"a"; // "a" 0.15;
            resultTheory[15] = (ValueString)"b"; // "b" 0.85;
            resultTheory[16] = (ValueString)"a"; // "a" 0.67;
            resultTheory[17] = (ValueString)"a"; // "a" 0.51;
            resultTheory[18] = (ValueString)"a"; // "a" 0.71;
            resultTheory[19] = (ValueString)"a"; // "a" 0.2;
            resultTheory[20] = (ValueString)"a"; // "a" 0.77;
            resultTheory[21] = (ValueString)"a"; // "a" 0.15;
            resultTheory[22] = (ValueString)"b"; // "b" 0.96;
            resultTheory[23] = (ValueString)"a"; // "a" 0.61;
            resultTheory[24] = (ValueString)"a"; // "a" 0.15;
            resultTheory[25] = (ValueString)"b"; // "b" 0.85;
            resultTheory[26] = (ValueString)"a"; // "a" 0.67;
            resultTheory[27] = (ValueString)"a"; // "a" 0.51;
            resultTheory[28] = (ValueString)"a"; // "a" 0.71;
            resultTheory[29] = (ValueString)"a"; // "a" 0.2;

            Assert.AreEqual(resultTheory, temp);
        }
        public ActionResult Index(
            int[] transformationLinkIds,
            int[] transformationIds,
            int iterationsCount,
            int[] characteristicTypeLinkIds,
            string[] customSequences,
            bool localFile,
            HttpPostedFileBase[] file)
        {
            return Action(() =>
            {
                var db = new LibiadaWebEntities();
                var characteristicTypeLinkRepository = new CharacteristicTypeLinkRepository(db);
                int sequencesCount = localFile ? Request.Files.Count : customSequences.Length;
                var sequences = new string[sequencesCount];
                var names = new string[sequencesCount];

                for (int i = 0; i < sequencesCount; i++)
                {
                    if (localFile)
                    {
                        var sequenceStream = FileHelper.GetFileStream(file[i]);
                        var fastaSequence = NcbiHelper.GetFastaSequence(sequenceStream);
                        sequences[i] = fastaSequence.ConvertToString();
                        names[i] = fastaSequence.ID;
                    }
                    else
                    {
                        sequences[i] = customSequences[i];
                        names[i] = "Custom sequence " + (i + 1) + ". Length: " + customSequences[i].Length;
                    }
                }

                var characteristics = new double[sequences.Length, characteristicTypeLinkIds.Length];

                for (int j = 0; j < sequences.Length; j++)
                {
                    for (int k = 0; k < characteristicTypeLinkIds.Length; k++)
                    {
                        var sequence = new Chain(sequences[j]);
                        for (int l = 0; l < iterationsCount; l++)
                        {
                            for (int w = 0; w < transformationIds.Length; w++)
                            {
                                if (transformationIds[w] == 1)
                                {
                                    sequence = DissimilarChainFactory.Create(sequence);
                                }
                                else
                                {
                                    sequence = HighOrderFactory.Create(sequence, (Link)transformationLinkIds[w]);
                                }
                            }
                        }

                        var link = characteristicTypeLinkRepository.GetLibiadaLink(characteristicTypeLinkIds[k]);
                        string className = characteristicTypeLinkRepository.GetCharacteristicType(characteristicTypeLinkIds[k]).ClassName;
                        var calculator = CalculatorsFactory.CreateFullCalculator(className);

                        characteristics[j, k] = calculator.Calculate(sequence, link);
                    }
                }

                var characteristicNames = characteristicTypeLinkIds.Select(c => characteristicTypeLinkRepository.GetCharacteristicName(c)).ToArray();

                var characteristicsList = new SelectListItem[characteristicTypeLinkIds.Length];
                for (int i = 0; i < characteristicNames.Length; i++)
                {
                    characteristicsList[i] = new SelectListItem
                    {
                        Value = i.ToString(),
                        Text = characteristicNames[i],
                        Selected = false
                    };
                }

                var transformations = new Dictionary<int, string>();
                for (int i = 0; i < transformationIds.Length; i++)
                {
                    var link = ((Link)transformationLinkIds[i]).GetDisplayValue();
                    transformations.Add(i, transformationIds[i] == 1 ? "dissimilar" : "higher order " + link);
                }

                var result = new Dictionary<string, object>
                                 {
                                     { "characteristics", characteristics },
                                     { "characteristicNames", characteristicNames },
                                     { "characteristicsList", characteristicsList },
                                     { "transformationsList", transformations },
                                     { "iterationsCount", iterationsCount }
                                 };

                return new Dictionary<string, object>
                           {
                               { "data", JsonConvert.SerializeObject(result) }
                           };
            });
        }
 public void Initialization()
 {
     testChain = new Chain("adbaacbbaaca");
 }
        public ActionResult Index(
            long[] matterIds,
            int[] characteristicTypeLinkIds,
            int? languageId,
            int? translatorId,
            int notationId,
            int length,
            int step,
            bool delta,
            bool fourier,
            bool growingWindow,
            bool autocorrelation)
        {
            return Action(() =>
            {
                var characteristicNames = new string[characteristicTypeLinkIds.Length];
                var partNames = new List<string>[matterIds.Length];
                var starts = new List<int>[matterIds.Length];
                var lengthes = new List<int>[matterIds.Length];
                var chains = new Chain[matterIds.Length];
                var mattersCharacteristics = new object[matterIds.Length];

                var calculators = new List<IFullCalculator>();
                var links = new List<Link>();
                matterIds = matterIds.OrderBy(m => m).ToArray();
                var matters = db.Matter.Where(m => matterIds.Contains(m.Id)).ToDictionary(m => m.Id);

                for (int k = 0; k < matterIds.Length; k++)
                {
                    long matterId = matterIds[k];
                    Nature nature = db.Matter.Single(m => m.Id == matterId).Nature;

                    long sequenceId;
                    switch (nature)
                    {
                        case Nature.Literature:
                            sequenceId = db.LiteratureSequence.Single(l => l.MatterId == matterId
                                                                        && l.NotationId == notationId
                                                                        && l.LanguageId == languageId
                                                                        && l.TranslatorId == translatorId).Id;
                            break;
                        default:
                            var id = notationId;
                            sequenceId = db.CommonSequence.Single(c => c.MatterId == matterId
                                                                    && c.NotationId == id).Id;
                            break;
                    }

                    chains[k] = commonSequenceRepository.ToLibiadaChain(sequenceId);
                }

                foreach (int characteristicTypeLinkId in characteristicTypeLinkIds)
                {
                    string className = characteristicTypeLinkRepository.GetCharacteristicType(characteristicTypeLinkId).ClassName;
                    calculators.Add(CalculatorsFactory.CreateFullCalculator(className));
                    links.Add(characteristicTypeLinkRepository.GetLibiadaLink(characteristicTypeLinkId));
                }

                for (int i = 0; i < chains.Length; i++)
                {
                    CutRule cutRule = growingWindow
                            ? (CutRule)new CutRuleWithFixedStart(chains[i].GetLength(), step)
                            : new SimpleCutRule(chains[i].GetLength(), step, length);

                    CutRuleIterator iter = cutRule.GetIterator();

                    List<Chain> fragments = new List<Chain>();
                    partNames[i] = new List<string>();
                    starts[i] = new List<int>();
                    lengthes[i] = new List<int>();

                    while (iter.Next())
                    {
                        var fragment = new Chain(iter.GetEndPosition() - iter.GetStartPosition());

                        for (int k = 0; iter.GetStartPosition() + k < iter.GetEndPosition(); k++)
                        {
                            fragment.Set(chains[i][iter.GetStartPosition() + k], k);
                        }

                        fragments.Add(fragment);
                        partNames[i].Add(fragment.ToString());
                        starts[i].Add(iter.GetStartPosition());
                        lengthes[i].Add(fragment.GetLength());
                    }

                    var fragmentsData = new FragmentData[fragments.Count];
                    for (int k = 0; k < fragments.Count; k++)
                    {
                        var characteristics = new double[calculators.Count];
                        for (int j = 0; j < calculators.Count; j++)
                        {
                            characteristics[j] = calculators[j].Calculate(fragments[k], links[j]);
                        }

                        fragmentsData[k] = new FragmentData(characteristics, fragments[k].ToString(), starts[i][k], fragments[k].GetLength());
                    }

                    double[][] differenceData = null;
                    double[][] fourierData = null;
                    double[][] autocorrelationData = null;

                    if (delta)
                    {
                        differenceData = CalculateDifference(fragmentsData.Select(f => f.Characteristics).ToArray());
                    }

                    if (fourier)
                    {
                        fourierData = FastFourierTransform.CalculateFastFourierTransform(fragmentsData.Select(f => f.Characteristics).ToArray());
                    }

                    if (autocorrelation)
                    {
                        autocorrelationData = AutoCorrelation.CalculateAutocorrelation(fragmentsData.Select(f => f.Characteristics).ToArray());
                    }

                    mattersCharacteristics[i] = new { matterName = matters[matterIds[i]].Name, fragmentsData, differenceData, fourierData, autocorrelationData };
                }

                for (int l = 0; l < characteristicTypeLinkIds.Length; l++)
                {
                    characteristicNames[l] = characteristicTypeLinkRepository.GetCharacteristicType(characteristicTypeLinkIds[l]).Name;
                }

                var characteristicsList = new SelectListItem[characteristicTypeLinkIds.Length];
                for (int k = 0; k < characteristicTypeLinkIds.Length; k++)
                {
                    characteristicNames[k] = characteristicTypeLinkRepository.GetCharacteristicName(characteristicTypeLinkIds[k], notationId);
                    characteristicsList[k] = new SelectListItem
                    {
                        Value = k.ToString(),
                        Text = characteristicNames[k],
                        Selected = false
                    };
                }

                string notationName = db.Notation.Single(n => n.Id == notationId).Name;

                var result = new Dictionary<string, object>
                {
                    { "characteristics", mattersCharacteristics },
                    { "notationName", notationName },
                    { "starts", starts },
                    { "partNames", partNames },
                    { "lengthes", lengthes },
                    { "characteristicNames", characteristicNames },
                    { "matterIds", matterIds },
                    { "characteristicsList", characteristicsList }
                };

                return new Dictionary<string, object> { { "data", JsonConvert.SerializeObject(result) } };
            });
        }
        /// <summary>
        /// The calculate.
        /// </summary>
        /// <param name="chain">
        /// The chain.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        /// <exception cref="Exception">
        /// Thrown if chain doesn't contain fmotives.
        /// </exception>
        private static bool Calculate(FmotivChain chain)
        {
            if (chain.FmotivList.Count < 1)
            {
                throw new Exception("Unable to count note remoteness with no elements in chain!");
            }

            var noteList = new List<ValueNote>(); // список нот, класса Note, всей цепи фмотивов

            foreach (Fmotiv fmotiv in chain.FmotivList)
            {
                foreach (ValueNote note in fmotiv.TieGathered().PauseTreatment((int)ParamPauseTreatment.Ignore).NoteList)
                {
                    noteList.Add((ValueNote)note.Clone());
                }
            }

            var noteChain = new Chain(noteList.Count);
            for (int i = 0; i < noteList.Count; i++)
            {
                string temp = string.Empty; // строка для временного хранения набора высот

                foreach (Pitch pitch in noteList[i].Pitch)
                {
                    temp += Convert.ToString(pitch.MidiNumber);
                }

                // TODO: переделать нормально чтоб цепочка складывалась из ValueNote, а не как попало
                noteChain[i] = new ValueString(temp + " " + Convert.ToString(noteList[i].Duration.Value * 10000000));
            }

            valR = new AverageRemoteness().Calculate(noteChain, Link.End);
            valG = new Depth().Calculate(noteChain, Link.End);
            return true;
        }
        /// <summary>
        /// The make new chain.
        /// </summary>
        /// <returns>
        /// The <see cref="Chain"/>.
        /// </returns>
        public Chain MakeNewChain()
        {
            var newChain = new Chain(range.Length);

            for (int i = 0; i < range.Length; i++)
            {
                newChain[i] = new ValueInt(range.Data[i].Id);
            }

            chain = (Chain)newChain.Clone();
            return newChain;
        }