private List <ComparableEvent> Index(List <TrainingEvent> events, Dictionary <string, int> predicateIndex)
        {
            var map = new Dictionary <string, int>();

            int eventCount   = events.Count;
            int outcomeCount = 0;

            var eventsToCompare = new List <ComparableEvent>(eventCount);
            var indexedContext  = new List <int>();

            for (int eventIndex = 0; eventIndex < eventCount; eventIndex++)
            {
                TrainingEvent   currentTrainingEvent = events[eventIndex];
                string[]        eventContext         = currentTrainingEvent.Context;
                ComparableEvent comparableEvent;

                int outcomeIndex;

                string outcome = currentTrainingEvent.Outcome;

                if (map.ContainsKey(outcome))
                {
                    outcomeIndex = map[outcome];
                }
                else
                {
                    outcomeIndex = outcomeCount++;
                    map.Add(outcome, outcomeIndex);
                }

                for (int currentEventContext = 0; currentEventContext < eventContext.Length; currentEventContext++)
                {
                    string predicate = eventContext[currentEventContext];
                    if (predicateIndex.ContainsKey(predicate))
                    {
                        indexedContext.Add(predicateIndex[predicate]);
                    }
                }

                // drop events with no active features
                if (indexedContext.Count > 0)
                {
                    comparableEvent = new ComparableEvent(outcomeIndex, indexedContext.ToArray());
                    eventsToCompare.Add(comparableEvent);
                }
                else
                {
                    //"Dropped event " + oEvent.Outcome + ":" + oEvent.Context);
                }
                // recycle the list
                indexedContext.Clear();
            }
            SetOutcomeLabels(ToIndexedStringArray(map));
            SetPredicateLabels(ToIndexedStringArray(predicateIndex));
            return(eventsToCompare);
        }
        private List <ComparableEvent> Index(int eventCount, ITrainingEventReader eventReader, Dictionary <string, int> predicateIndex)
        {
            var outcomeMap      = new Dictionary <string, int>();
            int outcomeCount    = 0;
            var eventsToCompare = new List <ComparableEvent>(eventCount);
            var indexedContext  = new List <int>();

            while (eventReader.HasNext())
            {
                TrainingEvent   currentTrainingEvent = eventReader.ReadNextEvent();
                string[]        eventContext         = currentTrainingEvent.Context;
                ComparableEvent comparableEvent;

                int    outcomeId;
                string outcome = currentTrainingEvent.Outcome;

                if (outcomeMap.ContainsKey(outcome))
                {
                    outcomeId = outcomeMap[outcome];
                }
                else
                {
                    outcomeId = outcomeCount++;
                    outcomeMap.Add(outcome, outcomeId);
                }

                for (int currentPredicate = 0; currentPredicate < eventContext.Length; currentPredicate++)
                {
                    string predicate = eventContext[currentPredicate];
                    if (predicateIndex.ContainsKey(predicate))
                    {
                        indexedContext.Add(predicateIndex[predicate]);
                    }
                }

                // drop events with no active features
                if (indexedContext.Count > 0)
                {
                    comparableEvent = new ComparableEvent(outcomeId, indexedContext.ToArray());
                    eventsToCompare.Add(comparableEvent);
                }
                else
                {
                    //"Dropped event " + currentTrainingEvent.Outcome + ":" + currentTrainingEvent.Context);
                }
                // recycle the list
                indexedContext.Clear();
            }
            SetOutcomeLabels(ToIndexedStringArray(outcomeMap));
            SetPredicateLabels(ToIndexedStringArray(predicateIndex));
            return(eventsToCompare);
        }
        /// <summary>
        /// Sorts and uniques the array of comparable events.  This method
        /// will alter the eventsToCompare array -- it does an in place
        /// sort, followed by an in place edit to remove duplicates.
        /// </summary>
        /// <param name="eventsToCompare">
        /// a List of <code>ComparableEvent</code> values
        /// </param>
        protected internal virtual void SortAndMerge(List <ComparableEvent> eventsToCompare)
        {
            eventsToCompare.Sort();
            int eventCount       = eventsToCompare.Count;
            int uniqueEventCount = 1;             // assertion: eventsToCompare.length >= 1

            if (eventCount <= 1)
            {
                return;                 // nothing to do; edge case (see assertion)
            }

            ComparableEvent comparableEvent = eventsToCompare[0];

            for (int currentEvent = 1; currentEvent < eventCount; currentEvent++)
            {
                ComparableEvent eventToCompare = eventsToCompare[currentEvent];

                if (comparableEvent.Equals(eventToCompare))
                {
                    comparableEvent.SeenCount++;                     // increment the seen count
                    eventsToCompare[currentEvent] = null;            // kill the duplicate
                }
                else
                {
                    comparableEvent = eventToCompare;       // a new champion emerges...
                    uniqueEventCount++;                     // increment the # of unique events
                }
            }

            //NotifyProgress("done. Reduced " + eventCount + " events to " + uniqueEventCount + ".");

            mContexts           = new int[uniqueEventCount][];
            mOutcomeList        = new int[uniqueEventCount];
            mNumTimesEventsSeen = new int[uniqueEventCount];

            for (int currentEvent = 0, currentStoredEvent = 0; currentEvent < eventCount; currentEvent++)
            {
                ComparableEvent eventToStore = eventsToCompare[currentEvent];
                if (null == eventToStore)
                {
                    continue;                     // this was a dupe, skip over it.
                }
                mNumTimesEventsSeen[currentStoredEvent] = eventToStore.SeenCount;
                mOutcomeList[currentStoredEvent]        = eventToStore.Outcome;
                mContexts[currentStoredEvent]           = eventToStore.GetPredicateIndexes();
                ++currentStoredEvent;
            }
        }