R: "длинные векторы (аргумент 5) не поддерживаются в .C"

У меня очень большая матрица, которую я пытаюсь запустить через glmnet на сервере с большим количеством памяти. Он отлично работает даже на очень больших наборах данных до определенной точки, после чего я получаю следующую ошибку:

Error in elnet(x, ...) : long vectors (argument 5) are not supported in .C

Если я правильно понимаю, это вызвано ограничением в R, которое не может иметь вектор с длиной дольше, чем INT_MAX. Это верно? Есть ли доступные решения для этого, которые не требуют полной перезаписи glmnet? Использует ли какой-либо из альтернативных переводчиков R (Riposte и т.д.) Это ограничение?

Спасибо!

Ответ 1

Так как версия 3 R поддерживает длинные векторы. Длинный вектор индексируется double. Длинный вектор может быть базой для матрицы или массива размером более 2, поскольку каждое измерение достаточно мало, чтобы индексироваться с помощью integer. Длинные векторы не могут быть переданы в собственный код через .C и .Fortran. Сообщение об ошибке, которое вы получаете, связано с тем, что длинный вектор передается через .C.

Длинные векторы могут быть переданы через .Call. Таким образом, до тех пор, пока собственный код glmnet может поддерживать длинные векторы (64-разрядные индексы) или может быть изменен/скомпилирован для его поддержки, нужно будет только изменить интерфейс между R и собственным кодом glmnet. Вы можете сделать это вручную на C, и для этой задачи также есть новый пакет с именем dotCall64. Часть модификации интерфейса решает, когда копировать аргументы -.C/.Fortran превентивно копирует, но вы не хотите делать это без необходимости с большими структурами данных.

Я думаю, что трудность изменения собственного кода glmnet для поддержки 64-битных индексов зависит от фактического кода (который я смотрел только, но не работал). Легко переключить все целые числа (или явно или неявно 32-битные целые числа) в коде Fortran на 64-разрядные. Проблемы возникают, когда некоторые целые числа должны оставаться 32 бит, и это произойдет, например. для целых векторов, переданных из/в R-код, поскольку R использует 32-битные целые числа (даже в длинных векторах). В glmnet есть такие целые векторы. Насколько сложна модификация, тогда зависит от того, насколько чистым является исходный код Fortran (например, если он использует отдельные целочисленные переменные для индексирования и доступа к значениям целых массивов и т.д.).

Экспериментальные реализации подмножеств R, как и Riposte, не помогут.

Ответ 2

В ?"long vector" есть примечание, в котором говорится:

Однако, скомпилированный код обычно нуждается в довольно обширных изменениях. Заметка что интерфейсы .C и .Fortran не принимают длинные векторы, поэтому.Класс (или аналогичный) должен использоваться.

elnet вызывает вызовы .Fortran. Вам нужно будет изменить функцию для использования .Call, возможно, через оболочку C, которая вызывает код FORTRAN, и, возможно, переписать и скомпилировать соответствующий код FORTRAN для обработки длинных векторов.