LINUX.ORG.RU

[C++] [хочу либу] Хранение кучи данных y(x)

 


0

2

Есть записи некоторой величины в течение трёх месяцев с промежутком в 5 секунд. Нужно 2 вещи.

  • Находить значение этой величины (с линейной интерполяцией, например) для произвольных моментов.
  • Находить среднее арифметическое для произвольных интервалов.

Естественно, написание простого класса для этого дела займёт 5 минут. Вот только будут некоторые проблемы. Для п.1 это большое время поиска двух соседних величин записи. Для п.2 это то, что придётся как-то обходить переполнение.

Посоветуйте, пожалуйста, готовые либы для моих задач.

★★★★★

люди разучились писать код чтоли? Скоро либы для хелловорлда просить будут

берешь значит редис. складываешь туда записи. 15млн он переварит без проблем. Ключ == время. И тащи что тебе надо. Можешь сделать расчет вообще не стороне редиса, тогда будет еще шустрей.

anonymous
()
Ответ на: комментарий от tailgunner

Ок. Берешь значит С++ и людую реализация хэша %)

anonymous
()
Ответ на: комментарий от anonymous

Нет, не пошутил. Есть у меня 2 значения, записанные для 11:00:00 и для 11:00:05. Нужно получить значение для 11:00:02. Как тут поможет хэш?

Ну то есть да, если бы значения были бы гарантированно известны для каждой пятой секунды, то проблем бы не было, ибо нужные ключи получались бы на раз. Но тут немного другая ситуация (надо было сразу о ней сказать), среди всех значений есть брак (который заранее отфильтрован), так что некоторые значения не существуют.

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

Похоже на то. А в виде библиотеки для C/C++ есть?

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от Obey-Kun

А как интерполируют вообще?... Берут 2 соседних значения. в 11:00:05 и в 11:00:00 и интерполируют (в данном случае линейно). Осталось придумать более-менее быстрый способ находить 2 соседних ключа. Можно тупо-перебором, если интервалы небольшие. Не вижу в чём проблема. В качестве контейнера взять к примеру это http://goog-sparsehash.sourceforge.net

В дистрибутивах есть пакет даже соответствующий.

anonymous
()
Ответ на: комментарий от Obey-Kun

> Ну то есть да, если бы значения были бы гарантированно известны для каждой пятой секунды, то проблем бы не было, ибо нужные ключи получались бы на раз. Но тут немного другая ситуация (надо было сразу о ней сказать), среди всех значений есть брак (который заранее отфильтрован), так что некоторые значения не существуют.

Бинарный поиск же

static_lab ★★★★★
()
Ответ на: комментарий от anonymous

> Можно тупо-перебором, если интервалы небольшие.

Перебором не катит, запись трёх месяцев с интервалом 5 секунд это немало.

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от static_lab

Тогда да, с бинарным поиском вполне можно использовать тот же QMap. Но это лишь одно из возможных шагов к ускорению нужного мне процесса. Можно разбивать всё на некоторое подобие b-trees, можно длинные места, где функция апроксимируема, заменять на формулы и т.п. Поэтому я и хочу готовую либу, самому всё это делать долго.

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от Obey-Kun

Грёбанный Кебастос! Ведь есть iterator QMap::lowerBound(const Key &key). И не надо заботиться о реализации поиска.

Остаётся вопрос рассчёта среднего значения. Есть миллион int'ов, как для них посчитать среднее?

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от Obey-Kun

… и получаешь переполнение.

Суммируй в больший по размеру тип.

Begemoth ★★★★★
()
Ответ на: комментарий от Obey-Kun

Нет, ну там перебор небольшой. Вы похоже не поняли о чём я.
У вас есть записи
11:00:00
11:00:05
11:00:10

Вы хотите получить значение в 11:00:07.
В итоге нужно сделать 3 операции поиска, для того чтобы найти последующее значение и 2 - предыдущее.
Т.е. вы проверяете на наличие в хэш таблице ключи: 11:00:08, 11:00:09, 11:00:10
И соответственно вниз. Если вы уверены, что записи идут с точностью раз в 5 секунд, то тогда можно просто как-нибудь так: startTime + 5 * floor(curKey / 5)
startTime - время первой записи(первый ключ)...

anonymous
()
Ответ на: комментарий от Obey-Kun

Почему бы не выбрать double? Всё-таки размерность удобна + сохраняется точность. Приведения вроде как в обоих случаях будут?

cattail
()
Ответ на: комментарий от anonymous

Достаточно сделать одну операцию поиска с помощью lowerBound, а следующее значение будет следующим итератором.

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от Obey-Kun

Достаточно сделать одну операцию поиска с помощью lowerBound

У тебя же данные упорядочены по времени с равномерным шагом, мочему напрямую индекс не вычислять?

Begemoth ★★★★★
()
Ответ на: комментарий от Begemoth

потому что как выяснилось, нифига не равномерно

anonymous
()
Ответ на: комментарий от Obey-Kun

> Ты int'ами оперируешь что ли?

конечно, ведь это продолжение разговора о том, что у тебя при суммировании int переполнится.

arsi ★★★★★
()
Ответ на: комментарий от cool_hedin

Задача ставилась как.

Есть миллион int'ов, как для них посчитать среднее?

В упор не вижу при чем здесь

целочисленная же арифметика

baverman ★★★
()

Для быстрого подсчёта суммы на интервале нужно дерево отрезков. Из суммы на интервале легко найти среднее на интервале.

gentoo_root ★★★★★
()
Ответ на: комментарий от arsi

ты писал этот пост не приходя в сознание?

У меня час ночи уже, а тред про недобуки разъел остатки серого вещества. Поэтому не смотри свысока на убогого. Если не сложно, просто разверни мысль. Я тебя тупо не понимаю.

baverman ★★★
()
Ответ на: комментарий от baverman

> Если не сложно, просто разверни мысль. Я тебя тупо не понимаю.

я вот тебя тоже не понимаю. ТС в процитированном тобой посте жалуется, что у него при суммировании 1млн интов пойдёт переполнение. когда может случится переполнение? правильно, если суммировать в тот же инт; double с его максимумом 10^308 и миллиардом интов не переполнишь. но если использовать для аккумулятора double, то на кой фиг вообще считать среднее инкрементально?

arsi ★★★★★
()
Ответ на: комментарий от anonymous

*записи по айдишнику. В редисе быстрей.

anonymous
()
Ответ на: комментарий от anonymous

Эээ... поясните пожалуйста, редис это однолетние или двулетние растения из рода Редька семейства Капустные или что?

Nicholass ★★★
()
Ответ на: комментарий от arsi

но если использовать для аккумулятора double, то на кой фиг вообще считать среднее инкрементально?

Резонно, но тогда уж лучше взять long long, в double мантисса всего 52 бита.

baverman ★★★
()

Посмотри в mrtg либу для хранения данных (не помню название, но разбирался в ней в свое время).

Она позволяет сохранять не все данные, а с уменьшающимся временным разрешением.

Не знаю, это ли именно тебе нужно, но советую.

bk_ ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.