Pull to refresh

Comments 10

Интерполирует данные прямой линией (т.е., f(x)=m ⋅ x + q).
Функция линейной интерполяции из GSL gsl_fit_linear() принимает на вход обычные массивы.

Это не интерполяция, это скорее аппроксимация, ну или фитирование (fitting).


Все же мне абсолютно не понятно, зачем использовать C/C++ для такого.
В языках, специально для этого созданных, манипуляции такого уровня занимают примерно 2 строчки. 4 если добавить считывание данных из .csv и сохранение графика в файл.


plot(mtcars$disp, mtcars$hp)
lines(mtcars$disp, lm(hp ~ disp, mtcars)$fitted.values)

График


Created on 2020-07-06 by the reprex package (v0.3.0)

Почему бы не использовать готовые библиотеки для чтения CSV? На практике при его парсинге встречаются разные особенности, которые запаришься отлавливать.

Эти утверждения не верны:

1) «Массивы в языке С не являются динамическими» — в C99 как раз динамические массивы есть (в статье сказано «мы будем использовать C99» — а не просто «C»)

2) «использовать C99 из-за… широкой поддержки» — на самом деле, как раз наоборот. В частности, Microsoft Visual Studio до сих пор не поддерживает C99 полностью (в отличии от C++11)

Ну и, до кучи, CSV означает comma-separated values, парсить их используя delimiter="\t"… как-то странно. (про осмысленность использования C/C++ для написания довольно кривой обертки для пакета GSL уже написали)
про осмысленность использования C/C++ для написания довольно кривой обертки для пакета GSL уже написали

Ну, все-таки в скорострельности с/с++ не откажешь, и те же операции по парсингу наборов данных (иногда весьма веселых) на этих языках могут серьезно сокращать время обработки. Особенно, если изменения нужно в онлайне смотреть…

Правильно. Поэтому языки для data science вызывают методы, написанные на C/C++/FORTRAN/Rust для большинства вычислений, при этом предоставляя удобный интеофейс и высокий уровень абстракции и управление памятью.

Я больше первичную подготовку данных имел ввиду… Парсить многогигабайтный не особо структурированный лог на с/с++ и на R каком-нибудь — вещи разные.
методы тоже можно повелосипедить для практики)

Я совершенно упустил еще одну проблему у данного подхода:


Так как вы обычно не знаете, сколько точек данных находится в файле, используйте односвязный список. Это динамическая структура данных, которая может расти бесконечно. К счастью, BSD предоставляет односвязные списки. Вот пример определения:|
Этот пример определяет список data_point, состоящий из структурированных значений, которые содержат как значения x, так и значения y. Синтаксис довольно сложный, но интуитивно понятный, и его подробное описание было бы слишком многословным.

Связный список, конечно, удобен для хранения данных, которые вы получаете построчно (например, из человеко-читаемого файла типа .csv). Однако, такой способ хранения довольно неэффективен. Во-первых, обычно количество записей в таблице не меняется в результате операций (ну или уменьшается до 1-3 если считается какой-то статистический параметр по столбцу, типа среднего). Количество столбцов же, наоборот, переменно.
Представьте ситуацию, что из [x; y] нужно получить новое значение, "расстояние до точки [x0; y0]". В таблице должен появиться новый столбец, R = sqrt((x - x0) ^ 2 + (y - y0) ^ 2), чего не сделать если тип вашей табличной строки прибит гвоздями в compile-time и не поддерживает легко изменения.


Альтренативно можно хранить данные по столбцам. Тогда каждый столбец — контейнер примитивного (ну или довольно простого, типа строки) типа. Все столбцы имеют одинаковую длину, количество столбцов можно менять — легко удалять, перемещать, добавлять новые, манипулируя просто указателями, не меняя положения даных в памяти пока это не потребуется.
Достаточно создать тип-заголовок для каждого столбца, содержащий, например, имя столбца, тип хранимых данных и условный void* на участок памяти, а таблица будет содержать информацию о свом размере (строки и столбцы), и указатель типа PColDef* со столбцами. Даже C99 должен такое осилить.


Теперь вашими данными легко манипулировать, а код — легко адаптировать если тип (а точнее форма) входных данных изменится.

К счастью, BSD предоставляет односвязные списки.
Точно «саентист» переводил (или писал оригинал) :)

Память может закончиться гораздо раньше, чем будет достигнут конец чтения файлов, из-за дикого выделения мелких объектов и дефрагментации. К примеру, на моем ПК (16Гб ОЗУ) загнать телефонные CDR в память таким образом получается не более 5 000 000 строк (правда это QT-фреймворк и контейнер — QMap, структура CDR поболее 2-х столбцов). Далее, машина перестает ворочаться…
В принципе, редко бывает необходимость в таком объеме, в противном случае пришлось бы городить огород с предварительным запросом кол-ва записей, выделением массива под это дело.
UFO just landed and posted this here
Sign up to leave a comment.