예제 #1
0
bool insert_keep_sorted_and_unique(typename VECTOR::value_type p, VECTOR& procs)
{
  typename VECTOR::iterator iter = std::lower_bound(procs.begin(), procs.end(), p);
  if (iter == procs.end() || *iter != p) {
    procs.insert(iter, p);
    return true;
  }
  return false;
}
예제 #2
0
//-------------------------------------------------------------------------
// Jenks' Optimization Method
//
//-------------------------------------------------------------------------
void MgFeatureNumericFunctions::GetJenksCategories(  VECTOR &inputData, int numPartsRequested,
                                                 double dataMin, double dataMax,
                                                 VECTOR &distValues )
{
    // numPartsRequested // 2 - 10; 5 is good
    int i = 0;  // index for numObservations (may be very large)
    int j = 0;  // index for numPartsRequested (about 4-8)
    int k = 0;

    // Sort the data values in ascending order
    std::sort(inputData.begin(), inputData.end());

    int numObservations = (int)inputData.size();  // may be very large
    // Possible improvement: Rework the code to use normal 0 based arrays.
    // Actually it doesn't matter much since we have to create two
    // matrices that themselves use more memory than the local copy
    // of inputData.
    //
    // In order to ease the use of original FORTRAN and the later BASIC
    // code, I will use 1 origin arrays and copy the inputData into
    // a local array;
    // I'll dimension the arrays one larger than necessary and use the
    // index values from the original code.
    //
    // The algorithm must calculate with floating point values.
    // If more optimization is attempted in the future, be aware of
    // problems with calculations using mixed numeric types.

    std::vector<double> data;
    data.push_back(0);  // dummy value at index 0
    std::copy(inputData.begin(), inputData.end(), std::back_inserter(data));
    // copy from parameter inputData so that data index starts from 1

    // Note that the Matrix constructors initialize all values to 0.
    // mat1 contains integer values used for indices into data
    // mat2 contains floating point values of data and bigNum
    MgMatrix<int>     mat1(numObservations + 1, numPartsRequested + 1);
    MgMatrix<double>  mat2(numObservations + 1, numPartsRequested + 1);

//  const double bigNum = 1e+14; // from original BASIC code;
//  const double bigNum = std::numeric_limits<double>::max();
    const double bigNum = DBL_MAX;   // compiler's float.h

    for (i = 1; i <= numPartsRequested; ++i)
    {
        mat1.Set(1, i, 1);
        for (j = 2; j <= numObservations; ++j)
        {
            mat2.Set(j, i, bigNum);
        }
    }

    std::vector<int> classBounds;
    classBounds.push_back(-2);  // dummy value
    for (i = 1; i <= numPartsRequested; ++i)
    {
        classBounds.push_back(-1);
    }

    for (int L = 2; L <= numObservations; ++L)
    {
        double s1 = 0;
        double s2 = 0;
        double v = 0;
        int w = 0;

        for (int m = 1; m <= L; ++m)
        {
            int i3 = L - m + 1;
            double val = data[i3];
            s2 += (double(val) * double(val));
            // if datatype of val is ever allowed to be same as template
            // parameter T, make sure multiplication is done in double.
            s1 += val;
            ++w;
            v = s2 - ((s1 * s1) / w);
            int i4 = i3 - 1;

            if (i4 > 0)
            {
                for (j = 2; j <= numPartsRequested; ++j)
                {
                    double tempnum = v + mat2.Get(i4, j - 1);
                    if (double(mat2.Get(L, j)) >= tempnum)
                    {
                        mat1.Set(L, j, i3);
                        mat2.Set(L, j, tempnum);
                    }
                }
            }
        }

        mat1.Set(L, 1, 1);
        mat2.Set(L, 1, v);
    }

    k = numObservations;
    for (j = numPartsRequested; j >= 1; --j)
    {
        if (k >= 0 && k <= numObservations)
        {
            classBounds[j] = mat1.Get(k, j);
            k = mat1.Get(k, j) - 1;
        }
    }

    std::vector<int> indices;

    indices.push_back(0);
    for (i = 2; i <= numPartsRequested; ++i)
    {
        int index = classBounds[i] - 1;
        if (index > indices.back())
        {
            indices.push_back(index);
        }
    }

    FixGroups(inputData, indices);

    double val = 0.0;
    int index = 0;
    int totIndex = (int)indices.size();

    for (int i = 1; i < totIndex; ++i)
    {
        index = indices[i] - 1;

        val = inputData[index];
        distValues.push_back(val);
    }

    index = numObservations - 1;
    val = inputData[index];
    distValues.push_back(val);

    int retCnt = (int)distValues.size();
    int inCnt = (int)inputData.size();

    if (retCnt > 0 && inCnt > 0)
    {
        if (!doubles_equal(distValues[0],inputData[0]))
        {
            distValues.insert(distValues.begin(), inputData[0]);
        }
    }

    return;
}