private static LinkedList1 <UOPair <HlaMsr1> > MakeUnphased(UOPair <LinkedList1 <HlaMsr1> > phaseGrounded)
        {
            LinkedList1 <UOPair <HlaMsr1> > unphased = null;

            foreach (var pair in SpecialFunctions.EnumerateTwo(phaseGrounded.First, phaseGrounded.Second))
            {
                unphased = LinkedList1 <UOPair <HlaMsr1> > .GetInstance(UOPair <HlaMsr1> .GetInstance(pair.Key, pair.Value), unphased);
            }
            return(unphased);
        }
        internal void Prenormalize(PidAndHlaSet pidAndHlaSet, Linkdis linkdis)
        {
            PhaseToLogProb       = new Dictionary <UOPair <LinkedList1 <HlaMsr1> >, double>();
            UnphaseToLogProb     = new Dictionary <LinkedList1 <UOPair <HlaMsr1> >, double>();
            LogTotal             = double.NegativeInfinity;
            BadHlaMsr1NameOrNull = null;
            UsedLowerResModel    = false;

            //CounterWithMessages abstractPhaseCounter = CounterWithMessages.GetInstance("\tabstract phase index = {0}", 1, null);

            try
            {
                foreach (var phaseAbstract in pidAndHlaSet.GetPhasedEnumeration())
                {
                    //abstractPhaseCounter.Increment();

                    var firstHlaListToProb  = linkdis.CreateHlaListToProb(phaseAbstract.First);
                    var secondHlaListToProb = linkdis.CreateHlaListToProb(phaseAbstract.Second);
                    if (firstHlaListToProb.Count * secondHlaListToProb.Count > linkdis.CombinationLimit)
                    {
                        throw new CombinationLimitException("The combinationLimit was exceeded. " + linkdis.CombinationLimit.ToString());
                    }

                    CounterWithMessages groundPhaseCounter = CounterWithMessages.GetInstance("\t\tground phase index = {0}", 1000, null);
                    foreach (var firstHlaListAndProb in firstHlaListToProb)
                    {
                        foreach (var secondHlaListAndProb in secondHlaListToProb)
                        {
                            groundPhaseCounter.Increment();

                            var phaseGrounded = UOPair <LinkedList1 <HlaMsr1> > .GetInstance(firstHlaListAndProb.Key, secondHlaListAndProb.Key);

                            var unphasedGrounded = MakeUnphased(phaseGrounded);

                            double prob = firstHlaListAndProb.Value.Key * secondHlaListAndProb.Value.Key;
                            UsedLowerResModel |= firstHlaListAndProb.Value.Value || secondHlaListAndProb.Value.Value;
                            double logProb = Math.Log(prob);


                            LogSum(PhaseToLogProb, phaseGrounded, logProb);
                            LogSum(UnphaseToLogProb, unphasedGrounded, logProb);
                            LogTotal = SpecialFunctions.LogSum(LogTotal, logProb);
                        }
                    }
                }
            }
            catch (HlaNotInModelException e)
            {
                CreateNoAnswerAnswer(pidAndHlaSet, e);
            }
        }
        public static IEnumerable <PidAndHlaSet> GetEnumerationDense(TextReader inputTextReader)
        {
            foreach (var pidAndHlaRecord in SpecialFunctions.ReadDelimitedFile(inputTextReader, new { pid = "", A1 = "", A2 = "", B1 = "", B2 = "", C1 = "", C2 = "" }, new char[] { '\t' }, true))
            {
                PidAndHlaSet pidAndHlaSet = new PidAndHlaSet();
                pidAndHlaSet.Pid           = pidAndHlaRecord.pid;
                pidAndHlaSet.WarningSet    = new HashSet <string>();
                pidAndHlaSet.HlaUopairList = LinkedList1 <UOPair <HlaMsr1> > .GetInstance(
                    UOPair <HlaMsr1> .GetInstance(CreateHla(pidAndHlaRecord.C1, ref pidAndHlaSet.WarningSet), CreateHla(pidAndHlaRecord.C2, ref pidAndHlaSet.WarningSet)),
                    UOPair <HlaMsr1> .GetInstance(CreateHla(pidAndHlaRecord.B1, ref pidAndHlaSet.WarningSet), CreateHla(pidAndHlaRecord.B2, ref pidAndHlaSet.WarningSet)),
                    UOPair <HlaMsr1> .GetInstance(CreateHla(pidAndHlaRecord.A1, ref pidAndHlaSet.WarningSet), CreateHla(pidAndHlaRecord.A2, ref pidAndHlaSet.WarningSet)));

                pidAndHlaSet.ClassList = new List <string> {
                    "C", "B", "A"
                };
                yield return(pidAndHlaSet);
            }
        }
        private void CreateNoAnswerAnswer(PidAndHlaSet pidAndHlaSet, HlaNotInModelException e)
        {
            PhaseToLogProb   = new Dictionary <UOPair <LinkedList1 <HlaMsr1> >, double>();
            UnphaseToLogProb = new Dictionary <LinkedList1 <UOPair <HlaMsr1> >, double>();

            BadHlaMsr1NameOrNull = e.HlaName;
            UsedLowerResModel    = true;

            var phaseGrounded = UOPair <LinkedList1 <HlaMsr1> > .GetInstance(
                LinkedList1 <HlaMsr1> .GetInstanceFromList(pidAndHlaSet.HlaUopairList.Select(pair => pair.First).ToList()),
                LinkedList1 <HlaMsr1> .GetInstanceFromList(pidAndHlaSet.HlaUopairList.Select(pair => pair.Second).ToList())
                );

            var unphasedGrounded = pidAndHlaSet.HlaUopairList;

            double logProb = double.NaN;

            LogSum(PhaseToLogProb, phaseGrounded, logProb);
            LogSum(UnphaseToLogProb, unphasedGrounded, logProb);
        }
        private static PidAndHlaSet CreatePidAndHlaSet(string previousPid, Dictionary <string, List <HlaMsr1> > classToHlaList, HashSet <string> warningSet)
        {
            SpecialFunctions.CheckCondition(new HashSet <string>(classToHlaList.Keys).SetEquals(new HashSet <string> {
                "A", "B", "C"
            }), "Expect Hla's for exactly classes A,B, & C. " + previousPid);
            SpecialFunctions.CheckCondition(classToHlaList.Values.All(list => list.Count == 2), "Expect two hla lines for each Hla class. " + previousPid);
            PidAndHlaSet pidAndHlaSet = new PidAndHlaSet();

            pidAndHlaSet.Pid           = previousPid;
            pidAndHlaSet.WarningSet    = warningSet;
            pidAndHlaSet.HlaUopairList = LinkedList1 <UOPair <HlaMsr1> > .GetInstance(
                UOPair <HlaMsr1> .GetInstance(classToHlaList["C"][0], classToHlaList["C"][1]),
                UOPair <HlaMsr1> .GetInstance(classToHlaList["B"][0], classToHlaList["B"][1]),
                UOPair <HlaMsr1> .GetInstance(classToHlaList["A"][0], classToHlaList["A"][1]));

            pidAndHlaSet.ClassList = new List <string> {
                "C", "B", "A"
            };
            return(pidAndHlaSet);
        }