Exemple #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;
}
  void
  JacobiPreconditioner<MATRIX,VECTOR>::apply_preconditioner(const VECTOR& Px, VECTOR& x) const
  {
    x = Px;
    unsigned int i(0);
    for (typename VECTOR::iterator it(x.begin()), itend(x.end());
	 it != itend; ++it, ++i)
      *it /= A.get_entry(i, i);
  }
//-------------------------------------------------------------------------
// 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;
}
// Calculate Quantile Distribution for the values
void MgFeatureNumericFunctions::GetQuantileCategories(  VECTOR &values, int numCats,
                                                    double dataMin, double dataMax,
                                                    VECTOR &distValues )
{
    // Expected categories should be more than zero
    if (numCats <= 0)
    {
        STRING message = MgServerFeatureUtil::GetMessage(L"MgInvalidComputedProperty");

        MgStringCollection arguments;
        arguments.Add(message);
        throw new MgFeatureServiceException(L"MgServerSelectFeatures.GetEqualCategories", __LINE__, __WFILE__, &arguments, L"", NULL);
    }

    int count = (int)values.size();
    if (count <= 0) { return; } // Nothing to do, we just send back Property Definition to clients from reader

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

    // How many go into each full bucket?

    int perBucket = ROUND((double)count/(double)numCats);
    if (perBucket * numCats > count)
        perBucket--;

    // How many buckets are full, and how many are missing one?
    int nearlyFullBuckets = numCats - (count - perBucket * numCats);
    int fullBuckets = numCats - nearlyFullBuckets;

    // expand min and max a little to account for numerical instability
    double delta = 0.0001 * (values[count-1] - values[0]);
    double* categories = new double[numCats+1];

    // the first and last categories are limited by the data method limits
    categories[0] = values[0] - delta;
    if (categories[0] < dataMin)
        categories[0] = dataMin;

    categories[numCats] = values[count-1] + delta;
    if (categories[numCats] > dataMax)
        categories[numCats] = dataMax;

    // Mix full and nearly-full buckets to fill in the categories between the ends.
    int indexOfLast = -1;
    for ( int i = 1; i<numCats; i++)
    {
        bool doingSmallBucket = (nearlyFullBuckets > fullBuckets);
        // find the index of the last element we want in this bucket
        indexOfLast += (doingSmallBucket ? perBucket : perBucket + 1);
        // make category value be halfway between that element and the next
        categories[i] = 0.5 * (values[indexOfLast] + values[indexOfLast+1]);

        // Decrement count of correct bucket type.
        if (doingSmallBucket)
            nearlyFullBuckets--;
        else
            fullBuckets--;
    }

    for (int kk = 0; kk < numCats+1; kk++)
    {
        distValues.push_back(categories[kk]);
    }

    delete[] categories; // Delete the memory allocated before
}
Exemple #5
0
void sort_and_unique(VECTOR &vector, COMPARE compare )
{
    std::sort(vector.begin(), vector.end(), compare);
    auto endIter = std::unique(vector.begin(), vector.end());
    vector.resize(endIter - vector.begin());
}
Exemple #6
0
void sort_and_unique(VECTOR &vector, COMPARE_LESS compare_less, COMPARE_EQUALS compare_equals  )
{
    std::sort(vector.begin(), vector.end(), compare_less);
    auto endIter = std::unique(vector.begin(), vector.end(), compare_equals);
    vector.resize(endIter - vector.begin());
}