Beispiel #1
0
            public void Dispose()
            {
                SourceStates oldValue = (SourceStates)Interlocked.Exchange(ref this.sourceState, (int)SourceStates.Disposed);

                if (oldValue != SourceStates.Disposed)
                {
                    if (this.ctRegistration != default(CancellationTokenRegistration))
                    {
                        this.ctRegistration.Dispose();
                        this.ctRegistration = default(CancellationTokenRegistration);
                    }

                    if (oldValue == SourceStates.Disposed) // TODO: Check if this is necessary!
                    {
                        Task.Run(() => this.Source.TrySetException(new ObjectDisposedException("Lock awaiter was unexpectedly disposed.")));
                    }
                }
            }
Beispiel #2
0
            public bool TrySignalSource(SourceStates state)
            {
                if ((SourceStates)this.sourceState == SourceStates.Disposed)
                {
                    throw new ObjectDisposedException("SyncTask");
                }

                int oldValue = -1;

                try { } finally
                {
                    if ((oldValue = Interlocked.CompareExchange(ref this.sourceState, (int)state, 0)) == 0)
                    {
                        switch (state)
                        {
                        case SourceStates.True:
                            Task.Factory.StartNew(() => { this.Source.TrySetResult(true); });
                            break;

                        case SourceStates.False:
                            Task.Factory.StartNew(() => { this.Source.TrySetResult(false); });
                            break;

                        case SourceStates.Canceled:
                            Task.Factory.StartNew(() => { this.Source.TrySetCanceled(); });
                            if (this.ctRegistration != default(CancellationTokenRegistration))
                            {
                                this.ctRegistration.Dispose();
                                this.ctRegistration = default(CancellationTokenRegistration);
                            }
                            break;

                        case SourceStates.Disposed:
                            throw new ArgumentException("SyncTask cannot be disposed this way.");

                        default:
                            break;
                        }
                    }
                }

                return(oldValue == 0);
            }
Beispiel #3
0
        /// <summary>
        ///   OnNext takes a tuple of an observation and a sequence of
        ///   states that might have emitted this observation (the
        ///   FROM states).  The name of the tuple is "value".  The
        ///   observation is in "value.Item1" and the sequence of
        ///   states is in "value.Item2".
        /// </summary>
        public void OnNext(Tuple <O, IEnumerable <S> > value)
        {
            Contract.Requires(value.Item2 != null);
            // Contract.Requires fails here due to visibility of the properties.
            Contract.Assert(Iff(TargetStates == null, LastV == null));

            // True only first time around -- at bootstrapping time.
            if (TargetStates == null)
            {
                // Initialize the HISTORY LIST of maps from state to
                // probability-of-most-probable-path.
                _V = new List <Dictionary <S, double> >();

                // Initialize the map from state to
                // most-probable-path-leading-to-state.
                Path = new Dictionary <S, List <S> >();

                // Initialize the FIRST map from state to probability
                // of most-probable-path leading to the state.
                var firstV = new Dictionary <S, double>();

                // value.Item2 contains the FROM states: the states
                // that might have emitted this observation.  Now
                // compute the probabilities for transition to all the
                // TO states.  In this bootstrapping case, the
                // probabilities are simply the emission
                // probabilities -- the probabilities that the state
                // produced this observation -- times the probability
                // that the system was in that state.
                foreach (var state in value.Item2)
                {
                    // The probability of the most probable path
                    // leading to "state" given observation is the
                    // a-priori probability of state times the
                    // conditional probability of observation given
                    // the state.  Observation is in the slot
                    // "value.Item1."
                    firstV[state] =
                        StartingProbabilities(state) *
                        EmissionProbabilities(state, value.Item1);

                    // The state that yielded the transition to this
                    // most probable path is just "state" itself.
                    Path[state] = new List <S>();
                    Path[state].Add(state);
                }
                // The possible targets for the next transition are in
                // the states, in-turn in slot "value.Item2."
                TargetStates = value.Item2;
                _V.Add(firstV);
                LastV = firstV;
                return;
            }

            // The source states for this observation are the target
            // states from the last observation (Viterbi, strictly
            // speaking, has a memory of ONE transition).  In case of
            // the first observation -- the bootstrapping case, this
            // is also true, it just so happens that the source and
            // target states are the same during bootstrapping.
            SourceStates = TargetStates;

            // The target states for this observation are in the input
            // to OnNext.
            TargetStates = value.Item2;

            // Space for the new probabilities of the
            // most-probable-paths leading to each state.
            var nextV = new Dictionary <S, double>();

            // and for each candidate target state . . .
            foreach (var target in TargetStates)
            {
                // . . . find the SOURCE state that leads to the most
                // probable path to the target.
                //
                // Maximize over the prior states: the transition
                // probabilities from the source state, times the
                // conditional probabilities of seeing the actual
                // observation given the candidate source state, times
                // the probability of the most-probable-path leading
                // to the source state.  Use the LINQ non-standard
                // query operator "ArgAndMax," which, for any
                // IEnumerable, finds the input (the arg or "source")
                // that produces the maximum value of its given
                // function (lambda expression), and also that maximum
                // value, returning both the argument and the maximum
                // in an instance of class ArgumentValuePair.
                //
                // In this lambda expression, "target" is fixed
                // (closed over).
                var maxStateAndProb = SourceStates.ArgAndMax(source =>
                {
                    // probability of the most probable path that led
                    // to source
                    var a = LastV[source];

                    // transition probability from source to target
                    var b = TransitionProbabilities(source, target);

                    // probability of seeing actual observation if we
                    // are in the target state; observation is stored
                    // in value.Item1.
                    var c = EmissionProbabilities(target, value.Item1);

                    return(a * b * c);
                });

                // After this point, we have found the SOURCE state
                // that produces the most probable path to the given
                // target state and yielding the given observation.
                // Save the probability of that most-probable-path.
                nextV[target] = maxStateAndProb.Value;

                // Copy the most probable path that led to the source
                // state that yields the maximum probability.  I must
                // copy it because this path might be the same for
                // multiple targets, and each target will need its own
                // copy of the prior path to append itself to.
                var newpath = new List <S>(Path[maxStateAndProb.Argument]);

                // Append the current state.
                newpath.Add(target);

                // Replace the path to the current target with the
                // refreshed one.
                Path[target] = newpath;
            }
            _V.Add(nextV);
            LastV = nextV;
        }