Esempio n. 1
0
        /// <summary>
        /// do accept rejection sampling
        /// </summary>
        /// <returns></returns>
        public List<LineSegmentConfiguration> Sample()
        {
            if (_GMTargetDistribution == null)
                throw new ApplicationException("GVFThinningSampler::Sample(), Candidate generating distribution or Instrumental distribution is not delegated.");

            // initial work space
            long seed = DateTime.Now.Millisecond;
            UniformDistribution randomSample = new UniformDistribution(seed + 10);  // sample for accept/reject
            double uSample;
            UniformDistribution randomPool = new UniformDistribution(seed + 30); // sample for birth from pool
            double uPool;
            UniformDistribution randomBirth = new UniformDistribution(seed + 40); // birth/death probability
            double uBirth;
            double uDeath;
            UniformDistribution randomRemove = new UniformDistribution(seed + 50);  // sample for remove line segment
            double uRemove;
            double acceptProbability;

            // MCMC interation
            int n = 0;
            _hits = 0;
            int Nm1 = _n - 1;
            double hMax = Double.MinValue;
            while (n < _n)
            {
                // get current coinfiguration
                LineSegmentConfiguration X = new LineSegmentConfiguration(_totalSamples[n]);

                int xLength = X.N;
                bool death = false;
                bool reject = false;
                // count hits of line segments
                int sourceLength = _sourceLineSegmentList.N;
                for (int s = 0; s < xLength; s++)
                {
                    int lineSegmentIndex = X.Configure[s].Index;
                    _sourceLineSegmentList.Configure[lineSegmentIndex].Hit++;
                    //for (int si = 0; si < sourceLength; si++)
                    //{
                    //    if (_sourceLineSegmentList.Configure[si].Index == lineSegmentIndex)
                    //    {
                    //        _sourceLineSegmentList.Configure[si].Hit++;
                    //        continue;
                    //    }
                    //}
                }

                /// Birth or Death ?
                #region Birth or Death ?
                uBirth = randomBirth.Sample();
                if (xLength > 0 && xLength < _totalLineSegment)
                    uDeath = 1 - uBirth;
                else if (xLength == 0)
                // only birth
                {
                    uBirth = 1.0;
                    uDeath = 0.0;
                }
                else
                // only death
                {
                    uDeath = 1.0;
                    uBirth = 0.0;
                }
                #endregion

                if (uBirth > uDeath)
                // Birth
                #region Birth
                {
                    death = false;
                    // sample a new line segment from pool
                    uPool = System.Math.Floor(randomPool.Sample() * _lineSegmentPool.N);
                    LineSegment addedLineSegment = _lineSegmentPool.Configure[(int)uPool];

                    // propose Y
                    LineSegmentConfiguration Y = new LineSegmentConfiguration(X);
                    Y.Add(addedLineSegment);

                    // debug
                    #region debug
                    //double temphy = _GMTargetDistribution.Evaluate(Y);
                    //double temphx = _GMTargetDistribution.Evaluate(X);
                    //temphy = _GMTargetDistribution.Evaluate(Y);
                    //temphx = _GMTargetDistribution.Evaluate(X);
                    #endregion

                    // accept probability
                    acceptProbability = BirthAcceptProbability(X, Y);
                    _sumAcceptProbability += acceptProbability;
                    uSample = randomSample.Sample();
                    if (uSample <= acceptProbability)
                    // accept Y
                    {
                        reject = false;
                        _hits++;
                        if (n < Nm1)
                            // add Y to totalSample;
                            _totalSamples.Add(Y);
                        if (n >= _n0)
                            // add Y to targetSample
                            _targetSamples.Add(Y);
                        // remove l from pool
                        _lineSegmentPool.RemoveAt((int)uPool);
                        //_totalLineSegment--;
                    }
                    else
                    // reject Y
                    {
                        reject = true;
                        if (n < Nm1)
                            _totalSamples.Add(X);
                        if (n >= _n0)
                            _targetSamples.Add(X);
                    }
                }
                #endregion
                else
                // Death
                #region Death
                {
                    death = true;
                    // uniformly remove v from X
                    uRemove = (int)System.Math.Floor(randomRemove.Sample() * xLength);
                    // propose Y
                    LineSegmentConfiguration Y = new LineSegmentConfiguration(X);
                    LineSegment removedLineSegment = Y.Configure[(int)uRemove];
                    Y.RemoveAt((int)uRemove);

                    // accept probability
                    acceptProbability = DeathAcceptProbability(X, Y);
                    _sumAcceptProbability += acceptProbability;
                    uSample = randomSample.Sample();
                    if (uSample <= acceptProbability)
                    // accept Y
                    {
                        reject = false;
                        _hits++;
                        if (n < Nm1)
                            // add Y to totalSample;
                            _totalSamples.Add(Y);
                        if (n >= _n0)
                            // add Y to targetSample
                            _targetSamples.Add(Y);
                        // add l back to pool
                        _lineSegmentPool.Add(removedLineSegment);
                        //_totalLineSegment++;
                    }
                    else
                    // reject Y
                    {
                        reject = true;
                        if (n < Nm1)
                            _totalSamples.Add(X);
                        if (n >= _n0)
                            _targetSamples.Add(X);
                    }
                }
                #endregion

                n++;

                // debug output
                #region debug
                _averageAcceptProbability = _sumAcceptProbability / (double)n;
                double h = _GMTargetDistribution.Evaluate(_totalSamples[n - 1]);
                if (h > hMax)
                {
                    hMax = h;
                    _indexMax = n - 1;
                }
                Console.Write("n = " + (n - 1));
                if (death)
                    Console.Write(" Death");
                else
                    Console.Write(" Birth");
                if (reject)
                    Console.Write(" Reject");
                else
                    Console.Write(" Accept");
                Console.Write(" # = " + _totalSamples[n - 1].N);
                Console.Write(" h(x) = " + String.Format("{0:0.0000e+00}", h));
                Console.Write(" accept rate = " + String.Format("{0:0.0000e+00}", acceptProbability));
                Console.WriteLine(" average accept rate " + String.Format("{0:f}", _averageAcceptProbability));
                #endregion
            } // end of while

            #region debug
            Console.Write("hx max = " + String.Format("{0:0.0000}", hMax) + " index = " + _indexMax);
            _averageAcceptProbability = _sumAcceptProbability / (double)_n;
            #endregion

            return _targetSamples;
        }