index page
0001: //////////////////////////////////////////////////
0002: //
0003: // ppa-r
0004: // point process analysis system: pair correlation
0005: //
0006: // Copyright October 2001 by TAKENAKA, A.
0007: // rev. November 2004
0008:
0009: #include <iostream>
0010:
0011: #include "plotarea.h"
0012:
0013: //////////////////////////////
0014: //
0015: // Constructor # Does nothing.
0016:
0017: PlotArea::PlotArea(void)
0018: {}
0019:
0020: //////////////////////////////
0021: //
0022:
0023: bool PlotArea::loadPoints(const char* file1, const char* file2)
0024: {
0025: Points1.erase(Points1.begin(), Points1.end());
0026: Points2.erase(Points2.begin(), Points2.end());
0027:
0028: Points1.load(file1);
0029: if (Points1.size() == 0) { // No data.
0030: return false;
0031: }
0032:
0033: if (file2 != NULL) { // If two files are specified...
0034: Points2.load(file2);
0035: if (Points2.size() == 0) { // No data.
0036: return false;
0037: }
0038: }
0039:
0040: // The area of the first data set is stored.
0041:
0042: AreaSize = Points1.getAreaSize();
0043: Area = AreaSize.X * AreaSize.Y;
0044: Perimeter = 2.0 * (AreaSize.X + AreaSize.Y);
0045:
0046: Density1 = Points1.size() / Area;
0047: MeanDensity = Density1;
0048:
0049: if (Points2.size() > 0) {
0050: Density2 = Points2.size() / Area;
0051: MeanDensity = sqrt(Density1 * Density2);
0052: }
0053:
0054: if ((Points2.size()) > 0 && !(AreaSize == Points2.getAreaSize()) ) {
0055: std::cerr << "! WARNING: Area of two data sets does not match."
0056: << std::endl;
0057: }
0058:
0059: Delta = 0.15 / sqrt(MeanDensity); // width of Epanechnikov kernel.
0060:
0061: std::cout << "Delta\t" << Delta << std::endl;
0062:
0063: return true;
0064: }
0065:
0066: //////////////////////////////
0067: //
0068:
0069: bool PlotArea::calc_cor(double r_unit, double r_upto)
0070: {
0071: if (r_unit <= 0 || r_unit > r_upto) { // Invalid r specification.
0072: std::cerr << "Invalid r specification." << std::endl;
0073: return false;
0074: }
0075:
0076: R_Unit = r_unit;
0077: R_Upto = r_upto;
0078:
0079: // R is kept shorter than the width of the area.
0080:
0081: double min_side = (AreaSize.X < AreaSize.Y) ? AreaSize.X : AreaSize.Y;
0082: if (R_Upto > min_side) {
0083: R_Upto = min_side;
0084: }
0085:
0086: // r = R_Unit, 2 * R_Unit, 3 * R_Unit, ...(MaxR_Index - 1) * R_Unit.
0087:
0088: MaxR_Index = int (R_Upto / R_Unit);
0089:
0090: initArray(); // Initialize array to store the results.
0091:
0092: PointList::iterator itr1, itr2;
0093: PointList::iterator itr2_begin, itr2_end;
0094:
0095: if (Points2.size() > 0) { // between two sets of points.
0096: itr2_begin = Points2.begin();
0097: itr2_end = Points2.end();
0098: }
0099: else { // within a set of points.
0100: itr2_begin = Points1.begin();
0101: itr2_end = Points1.end();
0102: }
0103:
0104: for (itr1 = Points1.begin(); itr1 != Points1.end(); ++itr1) {
0105: for (itr2 = itr2_begin; itr2 != itr2_end; ++itr2) {
0106:
0107: if (itr1 == itr2) {
0108: continue;
0109: }
0110:
0111: double r = (*itr1).distance(*itr2);
0112:
0113: for (int i_r = 0; i_r < MaxR_Index; ++i_r) {
0114:
0115: double d = (i_r + 0.5) * R_Unit;
0116: double w = get_w(r - d); // Epanechnikov kernel
0117:
0118: if (w > 0) {
0119: double s = get_s(d); // Ohser's edge correction factor.
0120: ResultsArray[i_r].second += w / s / d;
0121: }
0122: }
0123: }
0124: }
0125:
0126: // Normalize for point density.
0127:
0128: for (int i = 0; i < MaxR_Index; ++i) {
0129: ResultsArray[i].second /= (MeanDensity * MeanDensity * 2.0 * M_PI);
0130: }
0131:
0132: return true;
0133: }
0134:
0135: //////////////////////////////
0136: //
0137:
0138: const r_X_Array& PlotArea::getResults(void)
0139: {
0140: return ResultsArray;
0141: }
0142:
0143: //////////////////////////////
0144: //
0145: // Initialize the result array.
0146:
0147: void PlotArea::initArray(void)
0148: {
0149: ResultsArray.erase(ResultsArray.begin(), ResultsArray.end());
0150:
0151: for (int i = 0; i < MaxR_Index; ++i) {
0152: double r = (i + 0.5) * R_Unit;
0153: ResultsArray.push_back(r_X_Pair(r, 0.0));
0154: }
0155: }
0156:
0157:
0158: //////////////////////////////
0159: //
0160: // Ohser's edge correction
0161:
0162: double PlotArea::get_s(double x)
0163: {
0164: return Area - x * (Perimeter - x) / M_PI;
0165: }
0166:
0167: //////////////////////////////
0168: //
0169: // Epanechnikov kernel
0170:
0171: double PlotArea::get_w(double d)
0172: {
0173: if (d < 0) {
0174: d = -d;
0175: }
0176:
0177: if (d >= Delta) {
0178: return 0;
0179: }
0180: else {
0181: return 0.75 / Delta * (1.0 - d * d / (Delta * Delta));
0182: }
0183: }
Back to Top of this Page