Russian Qt Forum
Ноябрь 16, 2024, 01:21 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 [3]   Вниз
  Печать  
Автор Тема: operator <  (Прочитано 18398 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #30 : Апрель 02, 2013, 11:50 »

Да очень просто: У Вас нет никаких гарантий что если a < b и b < c, то и a < c.
про то, что транзитивность ( a<b & b<c => a<c ) не выполняется уже сказали.
Да как-то сказали - повторили написанное  Улыбающийся Лучше на живом примере. Пусть epsilon = 1 и матрицы отличаются только первыми 2-мя числами. Имеем 2 ключа

(0.9, 10) (0.1, 30)

Поскольку разница по первому ключу < epsilon, используем второй. Теперь появляется 3-й ключ, напр

(1.5, 20)

Выясняется что как бы мы не крутили, расставить ключи по возрастанию (a < b < c), не удается. Мапа не будет работать правильно, а для некоторых реализаций имеет право даже рухнуть. Это популярная ошибка, поэтому лучше разжевать. 
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #31 : Апрель 02, 2013, 12:01 »

Простое и хорошее решение было предложено в первом же ответе, оформим

Код
C++ (Qt)
typedef std::map <double, CMatrix> TMap;
 
const CMatrix * Lookup( TMap & theMap, const CMatrix & m )
{
double key = m.Sum();  // сумма всех 16 значений
 
TMap::iterator it = theMap.lower_bound(key - epsilon * 16);
if (it == theMap.end())
 it = theMap.begin();
 
while (it != theMap.end()) {
 if (it.first > key + epsilon * 16) break;
 if (m == it->second) return &it->second;
}  
return &theMap.insert(std::make_pair(key, m)).first->second;
}
 
Писал прямо здесь, возможны погрешности. Критикуем, опровергаем  Улыбающийся
« Последнее редактирование: Апрель 02, 2013, 12:04 от Igors » Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #32 : Апрель 02, 2013, 12:10 »

Тогда уж в качестве ключа лучше брать Sp (шпур) (он же Tr (трэйс), он же след), поскольку он инвариантен по отношению к вращениям..
Да и считается быстрей)
 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Anchorite
Гость
« Ответ #33 : Апрель 07, 2013, 19:50 »

Код:
bool operator < ( const CMatrix & sec ) const
{
    return memcmp(m, sec.m, sizeof(m[0]) * 16) < 0;
}

Не подойдет?
Естественно, что никакого "физического" или "математического" смысла в этом операторе нет.
Записан
Bepec
Гость
« Ответ #34 : Апрель 07, 2013, 20:13 »

Гениальный!!! ответ.  Без сарказма.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #35 : Апрель 08, 2013, 11:42 »

Код:
bool operator < ( const CMatrix & sec ) const
{
    return memcmp(m, sec.m, sizeof(m[0]) * 16) < 0;
}

Не подойдет?
Естественно, что никакого "физического" или "математического" смысла в этом операторе нет.
Конечно этот оператор будет работать корректно, но полученный отсортированный контейнер (напр std::map) оказывается бесполезным - ведь "близкие" элементы (для которых == вернет true) окажутся где угодно, а совсем не рядом друг с другом. А задача добавлять в мапу только те матрицы для которых нет близких имеющихся
Записан
Bepec
Гость
« Ответ #36 : Апрель 08, 2013, 12:04 »

Забацайте там 20% погрешности.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #37 : Апрель 08, 2013, 12:13 »

Забацайте там 20% погрешности.
Улыбающийся Что-то у Вас с фундаментальными вещами совсем неважно
Записан
Bepec
Гость
« Ответ #38 : Апрель 08, 2013, 12:32 »

Умейте отличать сарказм от серьёзных ответов. Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #39 : Апрель 08, 2013, 12:57 »

Умейте отличать сарказм от серьёзных ответов. Улыбающийся
У Вас ни то ни другое, так, скажу что-нибудь, авось попаду в тему Улыбающийся
Записан
Bepec
Гость
« Ответ #40 : Апрель 08, 2013, 13:50 »

Спасибо за лестные слова. Я их ждал.
Записан
Anchorite
Гость
« Ответ #41 : Апрель 08, 2013, 17:11 »

Конечно этот оператор будет работать корректно, но полученный отсортированный контейнер (напр std::map) оказывается бесполезным - ведь "близкие" элементы (для которых == вернет true) окажутся где угодно, а совсем не рядом друг с другом. А задача добавлять в мапу только те матрицы для которых нет близких имеющихся

Ну тогда, я считаю, что operator== следует модифицировать следующим образом

Код:
bool operator < ( const CMatrix & sec ) const
{
    for (size_t i = 0; i < 16; ++i)
    {
        const double delta = m[i] - sec.m[i];

        if (fabs(delta) > epsilon)
        {
            return delta < 0.0;
        }
    }

    return false;
}
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #42 : Апрель 08, 2013, 17:48 »

Код:
bool operator < ( const CMatrix & sec ) const
{
    for (size_t i = 0; i < 16; ++i)
    {
        const double delta = m[i] - sec.m[i];

        if (fabs(delta) > epsilon)
        {
            return delta < 0.0;
        }
    }

    return false;
}
Это опять-таки "нетранзитивно" - найдутся такие 3 ключа которые невозможно выстроить в порядке a < b < c
Записан
Страниц: 1 2 [3]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.179 секунд. Запросов: 23.