Сортировка собственных векторов по их собственным значениям (связанная сортировка)

StackOverflow https://stackoverflow.com/questions/2686548

Вопрос

У меня есть несортированный вектор собственных значений и связанной с ней матрицы собственных веществ. Я хотел бы отсортировать колонны матрицы в отношении отсортированного набора собственных значений. (например, если EigenValue [3] перемещается в EIGENVALUE [2], я хочу столбец 3 матрицы EigenVector для перехода к столбцу 2.)

Я знаю, что я могу отсортировать собственные значения в O(N log N) через std::sort. Отказ Не прокаживая свой собственный алгоритм сортировки, как я могу убедиться, что колонны матрицы (ассоциированные собственные собственные средства) следуют вместе со своими собственными значениями, когда последние сортируются?

Это было полезно?

Решение

Как правило, просто создайте структуру что-то вроде этого:

struct eigen { 
    int value;
    double *vector;

    bool operator<(eigen const &other) const { 
        return value < other.value;
    }
};

Альтернативно, просто поставьте собственное значение / собственные вектора в std::pair - хотя я бы предпочел eigen.value а также eigen.vector над something.first а также something.second.

Другие советы

Я сделал это несколько раз в разных ситуациях. Вместо того, чтобы сортировать массив, просто создайте новый массив, который в нем сортирован индексы.

Например, у вас есть длина n массива (вектор) уклончивает, а 2D-массив NXN Evects. Создайте новый индекс массива, который содержит значения [0, N-1].

Тогда, а не доступа к ухальмам как уклончиво [I], вы получаете доступ к нему как уклончивые [index [i]] и вместо Evects [i] [j], вы получаете доступ к этому evects [index [i]] [j].

Теперь вы пишете рутина сортировки, чтобы сортировать индексный массив, а не массив уклончика, поэтому вместо индекса выглядит как {0, 1, 2, ..., N-1}, значение в массиве индекса будет увеличиваться значений в массиве уклонника.

Так после сортировки, если вы сделаете это:

for (int i=0;i<n;++i)
{
  cout << evals[index[i]] << endl;
}

Вы получите отсортированный список увлечений.

Таким образом, вы можете отказаться от того, что связано с тем, что уклончивает массив, не двигаясь памятью вокруг. Это важно, когда n становится большим, вы не хотите двигаться вокруг колонн матрицы Evects.

В основном, самая маленькая Eval Eval будет расположена при индексе [I], и это соответствует индексу [I] Th Exect.

Отредактировано для добавления. Вот функция сортировки, которую я написал для работы с std :: сортирует делать то, что я только что сказал:

template <class DataType, class IndexType>
class SortIndicesInc
{
protected:
    DataType* mData;
public:
    SortIndicesInc(DataType* Data) : mData(Data) {}
    Bool operator()(const IndexType& i, const IndexType& j) const
    {
        return mData[i]<mData[j];
    }
};

Решение чисто опирается на то, как вы храните свою матрицу собственного вектора.

Лучшая производительность, когда сортировка будет достигнута, если вы сможете реализовать swap(evector1, evector2) Так что он только переподнимает указатели, и реальные данные остаются без изменений.

Это можно сделать, используя что-то вроде double* или, вероятно, что-то более сложное, зависит от вашей матричной реализации.

Если сделано так, swap(...) не повлияет на работу вашей сортировки операции.

Идея конгломерации вашего вектора и матрицы, вероятно, является лучшим способом сделать это в C ++. Я думаю о том, как я бы сделаю это в R и вижу, если это можно перевести на C ++. В R очень просто, просто evec <-evec [, порядок (Eval)]. К сожалению, я не знаю какой-либо встроенного способа выполнить операцию заказа () в C ++. Возможно, кто-то другой делает, и в этом случае это можно сделать аналогичным образом.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top