public void SynthethicModelStudy(string fileName) { // start from full configuration int fullLength = this.N; int[] input = new int[fullLength]; for (int i = 0; i < fullLength; i++) input[i] = i; bool first = true; // for each possible length combination for (int l = 1; l <= fullLength; l++) { Combinations<int> combinations = new Combinations<int>(input, l); foreach (int[] combination in combinations) { // copy of the full configuration LineSegmentConfiguration c = new LineSegmentConfiguration(this); // find the complement set List<int> complement = new List<int>(input); for (int i = 0; i < l; i++) complement.Remove(combination[i]); // get the configuration according the combination for (int i = 0; i < fullLength - l; i++) c.RemoveAtIndex(complement[i]); // calculate Up, Ud, U an H of the current configuration c.CalculateUP(); c.CalculateUD(); c.CalculateU(); c.CalculateH(); // output line segment details if (first) { first = false; c.WriteDebugDetails(fileName); } else { c.WriteDebugDetails(fileName, FileMode.Append, FileAccess.Write); } } } }
public LineSegmentConfiguration(LineSegmentConfiguration c) { _configuration = new List<LineSegment>(c._configuration); _joinedConfiguration = new List<LineSegment>(c._joinedConfiguration); _n = c._n; _nfe = c._nfe; _nf = c._nf; _pC = c._pC; _pCPair = c._pCPair; if (c._pC == null) _pC = null; else _pC = new List<double>(c._pC); if (c._pCPair == null) _pCPair = null; else { _pCPair = new double[_n, _n]; Array.Copy(c._pCPair, _pCPair, c._pCPair.Length); } _totalL = c._totalL; _averageL = c._averageL; _sumPC = c._sumPC; _sumPL = c._sumPL; _sumPG = c._sumPG; _sumPI = c._sumPI; _srcImage = c._srcImage; _gvfU = c._gvfU; _gvfV = c._gvfV; _gvfMagnitude = c._gvfMagnitude; // prior model _w1 = c._w1; _w2 = c._w2; _w3 = c._w3; _wC = c._wC; _wL = c._wL; _thetaMax = c._thetaMax; // data term _It = c._It; _kI = c._kI; _Gt = c._Gt; _wG = c._wG; _wI = c._wI; _Up = c._Up; _Ud = c._Ud; }
/// <summary> /// death accept probability /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> private double DeathAcceptProbability(LineSegmentConfiguration x, LineSegmentConfiguration y) { double R; double evaY = _GMTargetDistribution.Evaluate(y); double evaX = _GMTargetDistribution.Evaluate(x); R = evaY * x.N / evaX / _vS; //R = evaX / evaY; return R < 1.0 ? R : 1.0; }
/// <summary> /// birth accept probability (birth accept rate) /// </summary> /// <returns></returns> private double BirthAcceptProbability(LineSegmentConfiguration x, LineSegmentConfiguration y) { // calculate birth accept probability double R; double evaY = _GMTargetDistribution.Evaluate(y); double evaX = _GMTargetDistribution.Evaluate(x); R = evaY * _vS / evaX / y.N; //R = evaX / evaY; return R < 1.0 ? R : 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; }
/// <summary> /// init MCMC /// data term has been assigned to the pool /// </summary> public void Init(LineSegmentConfiguration pool) { // source line segment list _sourceLineSegmentList = new LineSegmentConfiguration(pool); // line segment pool _lineSegmentPool = new LineSegmentConfiguration(pool); _lineSegmentPool.Empty(); // RJMCMC starts from full line segment configuration LineSegmentConfiguration startList = new LineSegmentConfiguration(pool); _totalSamples.Add(startList); // v(S) _vS = LebesgueMeasure(_lamda, _width, _height); _totalLineSegment = pool.N; }
/// <summary> /// example target distribution function /// </summary> /// <returns></returns> public static double ExampleDensityFunction(LineSegmentConfiguration x) { // calculate hp x.FreeEndsFreeSegments(); x.JoinSegments(); x.CalculatePC(); x.CalculateSumPC(); x.CalculateTotalL(); x.CalculateAverageL(); // explicitly calculate sum(pL(s)), sum(pG(s)), and sum(pI(s)) for the efficiency sake int count = x.Configure.Count; double sumPL = 0.0; double sumPG = 0.0; double sumPI = 0.0; for (int s = 0; s < count; s++) { // calculate sum(pL(s)) x.Configure[s].CalculatePL(x.TotalLength, x.AverageLength); // try different weight double pL = x.Configure[s].PL; if (pL < 0.0) sumPL += pL * 100; else sumPL += pL; x.SumPL = sumPL; // calculate sum(pG(s)) x.Configure[s].CalculatePG(x.Gt); double pG = x.Configure[s].PG; if (pG < 0.0) sumPG += pG * 100; else sumPG += pG; x.SumPG = sumPG; // calculate sum(pI(s)) x.Configure[s].CalculatePI(x.It, x.KI); double pI = x.Configure[s].PI; if (pI < 0.0) sumPI += pI * 10000; else sumPI += pI; x.SumPI = sumPI; } double up = x.W1 * x.N + x.W2 * x.NF + x.W3 * x.NFE + x.WC * x.SumPC + x.WL * x.SumPL; // calculate hd double ud = x.WG * x.SumPG + x.WI * x.SumPI; // h = hp + hd; double u = up + ud; //return 1 / h; // density function U = exp(-h); double h = System.Math.Exp(-1.0 * u); return h; }