Сортировка собственных векторов по их собственным значениям (связанная сортировка)
-
30-09-2019 - |
Вопрос
У меня есть несортированный вектор собственных значений и связанной с ней матрицы собственных веществ. Я хотел бы отсортировать колонны матрицы в отношении отсортированного набора собственных значений. (например, если 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 ++. Возможно, кто-то другой делает, и в этом случае это можно сделать аналогичным образом.