/// <summary> /// direction of start poing to end point /// </summary> /// <param name="start"></param> /// <param name="end"></param> public PZDirection(PZPoint start, PZPoint end) { double dx = end.x - start.x; double dy = end.y - start.y; double length = System.Math.Sqrt(dx * dx + dy * dy); x = dx / length; y = dy / length; z = 0.0; }
/// <summary> /// extend from a given point, direction and distance /// </summary> /// <param name="p"></param> /// <param name="d"></param> /// <param name="dist"></param> /// <returns></returns> public void ExtendFrom(PZPoint p, PZDirection d, double dist) { x = p.x + dist * d.x; y = p.y + dist * d.y; z = p.z + dist * d.z; }
public bool EqualTo(PZPoint p) { if (x == p.x && y == p.y && z == p.z) return true; else return false; }
// distance between a and current point public double Distance(PZPoint a) { double d = (x - a.x) * (x - a.x); d += (y - a.y) * (y - a.y); d += (z - a.z) * (z - a.z); return System.Math.Sqrt(d); }
public PZPoint(PZPoint p) { x = p.x; y = p.y; z = p.z; }
/// <summary> /// get direction from 2 points /// </summary> /// <param name="p1">start point</param> /// <param name="p2">end point</param> /// <returns></returns> public void GetDirectionFrom2Points(PZPoint p1, PZPoint p2) { double dx = p2.x - p1.x; double dy = p2.y - p1.y; double length = System.Math.Sqrt(dx * dx + dy * dy); x = dx / length; y = dy / length; }
/// <summary> /// calculate value of unnormalized density /// </summary> /// <param name="pointArray"></param> /// <param name="theta1"></param> /// <param name="theta2"></param> /// <param name="r"></param> /// <returns></returns> private double H(PZPoint[] pointArray, double theta1, double theta2, double r, double c) { int nx = pointArray.Length; double mx = 2.0 * (double)S(pointArray, r); double ux = mx < c ? mx : c; double h = System.Math.Exp(nx * theta1 + ux * theta2); return h; }
public PZPointPair(PZPoint p1, PZPoint p2) { P1 = new PZPoint(p1); P2 = new PZPoint(p2); }
/// <summary> /// add a start/end point /// </summary> /// <param name="point"></param> public void AddEndPoint(PZPoint point) { if (_startPoint == null) { _startPoint = point; _pointList.Add(point); _Ls++; } else if (_endPoint == null) { _endPoint = point; _pointList.Add(point); _Ls++; } else PZMath_errno.ERROR("Illigal Start/End Points"); }
/// <summary> /// the number of pairs of points in point array that are separated by distance no more than r /// </summary> /// <param name="pointArray"></param> /// <returns></returns> private int S(PZPoint[] pointArray, double r) { int count = pointArray.Length; int s = 0; for (int i = 0; i < count - 1; i++) { for (int j = i + 1; j < count; j++) { if (pointArray[i].Distance(pointArray[j]) <= r) s++; //PZPoint xi = pointArray[i]; //PZPoint eta = pointArray[j]; //if (xi.Distance(eta) <= r) // s++; } } return s; //return s / 2; }
/// <summary> /// calculate value of unnormalized density /// </summary> /// <param name="pointArray"></param> /// <param name="theta1"></param> /// <param name="theta2"></param> /// <param name="r"></param> /// <returns></returns> private double H(PZPoint[] pointArray, double theta1, double theta2, double r) { int nx = pointArray.Length; int sx = S(pointArray, r); double h = System.Math.Exp(nx * theta1 + sx * theta2); return h; }
/// <summary> /// evolve Strauss process, C. J. Geyer 1999 /// start from empty point array /// birth-death algorithm /// </summary> private void EvolveStraussProcessStartFromEmpty(List<PZPoint[]> sampleList, double theta1, double theta2, double r, double lamda, double width, double height, int total, int burIn, int space, List<double> birthAcceptRateList, List<double> deathAcceptRateList, List<int> numberPointsList, List<int> numberClosePointsList) { ParkMillerUniform uniformRandom = new ParkMillerUniform(); PZPoint[] oldPointArray = new PZPoint[0]; PZPoint[] newPointArray; double birthRate = 0; double deathRate = 0; double birthAcceptRate = 0; double deathAcceptRate = 0; bool acceptNewPointArray = false; int spaceCount = 0; // MCMC evolving process for (int i = 0; i < _total; i++) { // birth or death if (oldPointArray.Length == 0) // birth only { birthRate = 1.0; deathRate = 0.0; } else { birthRate = uniformRandom.Sample(); deathRate = 1 - birthRate; } int nx = oldPointArray.Length; int sx = S(oldPointArray, r); if (birthRate >= deathRate) // birth { // simulate xi distributed proportional to lamda PZPoint xi = new PZPoint(width * uniformRandom.Sample(), height * uniformRandom.Sample()); newPointArray = new PZPoint[nx + 1]; // get new point array Array.Copy(oldPointArray, newPointArray, nx); newPointArray[nx] = xi; // birth accept rate birthAcceptRate = BirthAcceptRate(oldPointArray, newPointArray, lamda, width, height, theta1, theta2, r); birthAcceptRate = birthAcceptRate < 1.0 ? birthAcceptRate : 1.0; acceptNewPointArray = uniformRandom.Sample() < birthAcceptRate; } else // death { int removeIndex = (int)System.Math.Floor(nx * uniformRandom.Sample()); int nxNew = nx - 1; newPointArray = new PZPoint[nxNew]; // get new point array if (nx - 1 > 0) { for (int indexNew = 0, indexOld = 0; indexNew < nxNew; indexNew++, indexOld ++) { if (indexOld != removeIndex) { newPointArray[indexNew] = oldPointArray[indexOld]; } else { indexNew--; } } } // death accept rate deathAcceptRate = DeathAcceptRate(oldPointArray, newPointArray, lamda, width, height, theta1, theta2, r); deathAcceptRate = deathAcceptRate < 1.0 ? deathAcceptRate : 1.0; acceptNewPointArray = uniformRandom.Sample() < deathAcceptRate; } if (acceptNewPointArray) // accept new point array { oldPointArray = newPointArray; } else // reject new point array { } // record MCMC if (i > burIn) { if (spaceCount == space) { numberPointsList.Add(nx); numberClosePointsList.Add(sx); if (birthRate > deathRate) birthAcceptRateList.Add(birthAcceptRate); else deathAcceptRateList.Add(deathAcceptRate); spaceCount = 0; PZPoint[] recordPointArray = new PZPoint[oldPointArray.Length]; Array.Copy(oldPointArray, recordPointArray, oldPointArray.Length); sampleList.Add(recordPointArray); } } spaceCount++; } }
/// <summary> /// death accept rate, C. J. Geyer /// R = n(x) * h(x \ xi) / lamda(s) / h(x) /// </summary> private double DeathAcceptRate(PZPoint[] oldPointArray, PZPoint[] newPointArray, double lamda, double width, double height, double theta1, double theta2, double r) { double lamdaS = lamda * width * height; double nx = oldPointArray.Length; double hxOld = H(oldPointArray, theta1, theta2, r); double hxNew = H(newPointArray, theta1, theta2, r); double R = nx * hxNew / lamdaS / hxOld; return R; }
public double H(PZPoint[] pointArray) { return H(pointArray, _theta1, _theta2, _r); }
public bool Is8NeighbourOf(PZPoint p) { bool is8Neighbour = false; if ((x == p.x - 1 && y == p.y - 1) || (x == p.x - 1 && y == p.y) || (x == p.x - 1 && y == p.y + 1) || (x == p.x && y == p.y - 1) || (x == p.x && y == p.y + 1) || (x == p.x + 1 && y == p.y - 1) || (x == p.x + 1 && y == p.y) || (x == p.x + 1 && y == p.y + 1)) is8Neighbour = true; return is8Neighbour; }
public void MemCopyFrom(PZPoint p) { x = p.x; y = p.y; z = p.z; }
/// <summary> /// add a point to the point list /// </summary> /// <param name="point"></param> /// <returns></returns> public int AddPoint(PZPoint point) { _pointList.Add(point); _Ls++; return _Ls; }
/// <summary> /// do accept rejection sampling /// </summary> /// <returns></returns> public List<List<PZPoint>> Sample() { if (GMTargetDistribution == null) throw new ApplicationException("GeyerMollerSampler::Sample(), Candidate generating distribution or Instrumental distribution is not delegated."); averageAcceptProbability = 0.0; sumAcceptProbability = 0.0; averagesx = 0.0; averagenx = 0.0; sumnx = 0.0; sumsx = 0.0; // initial work space long seed = DateTime.Now.Millisecond; UniformDistribution U = new UniformDistribution(seed + 10); double u; UniformDistribution Ux = new UniformDistribution(seed + 20); UniformDistribution Uy = new UniformDistribution(seed + 30); double ux, uy; UniformDistribution Ub = new UniformDistribution(seed + 40); UniformDistribution Uremove = new UniformDistribution(seed + 50); double acceptProbability; double birthProbability; double deathProbability; // MCMC interation int n = 0; hits = 0; int Nm1 = N - 1; // start from empty chain. while (n < N) { List<PZPoint> X = new List<PZPoint>(totalSamples[n]); int xLength = X.Count; bool death = false; bool reject = false; // Birth or Death birthProbability = Ub.Sample(); if (xLength > 0) deathProbability = 1 - birthProbability; else { birthProbability = 1.0; deathProbability = 0.0; } if (birthProbability> deathProbability) // Birth { death = false; // creat a new point u in S ux = Ux.Sample() * width; uy = Uy.Sample() * height; PZPoint pointU = new PZPoint(ux, uy); // propose Y List<PZPoint> Y = new List<PZPoint>(X); Y.Add(pointU); // accept probability acceptProbability = BirthAcceptProbability(X, Y); sumAcceptProbability += acceptProbability; u = U.Sample(); if (u <= 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); } else // reject Y { reject = true; if (n < Nm1) totalSamples.Add(X); if (n >= n0) targetSamples.Add(X); } } else // Death { death = true; // uniformly remove v from X int removeIndex = Convert.ToInt32(Uremove.Sample() * xLength) - 1; removeIndex = removeIndex > 0 ? removeIndex : 0; // propose Y List<PZPoint> Y = new List<PZPoint>(X); Y.RemoveAt(removeIndex); // accept probability acceptProbability = DeathAcceptProbability(X, Y); sumAcceptProbability += acceptProbability; u = U.Sample(); if (u <= 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); } else // reject Y { reject = true; if (n < Nm1) totalSamples.Add(X); if (n >= n0) targetSamples.Add(X); } } n++; // debug output averageAcceptProbability = sumAcceptProbability / (double) n; double r = 0.3; int nx = totalSamples[n - 1].Count; int sx = Convert.ToInt32(Sx(totalSamples[n - 1], r)); sumsx += sx; sumnx += nx; double hx = GMTargetDistribution.Evaluate(totalSamples[n - 1]); Console.Write("n = " + n); if (death) Console.Write(" Death"); else Console.Write(" Birth"); if (reject) Console.Write(" Reject"); else Console.Write(" Accept"); Console.Write(" n(x) = " + nx); Console.Write(" s(x) = " + sx); Console.Write(" h(x) = " + String.Format("{0:f}", hx)); Console.Write(" accept rate = " + String.Format("{0:f}", acceptProbability)); Console.WriteLine(" average accept rate " + String.Format("{0:f}", averageAcceptProbability)); } averageAcceptProbability = sumAcceptProbability / (double) N; averagesx = sumsx / (double)N; averagenx = sumnx / (double)N; return targetSamples; }
/// <summary> /// birth accept rate, C. J. Geyer /// R = lamda(S) * h(x U xi) / (n(x) + 1) / h(x) /// </summary> private double BirthAcceptRate(PZPoint[] oldPointArray, PZPoint[] newPointArray, double lamda, double width, double height, double theta1, double theta2, double r, double c) { double lamdaS = lamda * width * height; double nx = oldPointArray.Length; double hxOld = H(oldPointArray, theta1, theta2, r, c); double hxNew = H(newPointArray, theta1, theta2, r, c); double R = lamdaS * hxNew / (nx + 1.0) / hxOld; return R; }