Правильно: это проблема, с которой я столкнулся при отправке пакета R в CRAN. Поэтому я
- не могу контролировать размер стека (поскольку проблема возникла на одной из платформ CRAN)
- Я не могу предоставить воспроизводимый пример (поскольку я не знаю точных конфигураций в CRAN)
Проблема
При попытке отправить пакет cSEM.DGP в CRAN автоматический предварительный тест c (для Debian x86_64-p c - linux -gnu; не для Windows!) завершился неудачей с ПРИМЕЧАНИЕ: C stack usage 7975520 is too close to the limit
.
Я знаю, что это вызвано функцией с тремя аргументами, тело которой имеет длину около 800 строк. Тело функции состоит из сложений и умножений этих аргументов. Это функция varzeta6()
, которую вы найдете здесь (от строки 647 и далее).
Как я могу решить эту проблему?
То, что я не могу сделать:
- предоставить воспроизводимый пример (по крайней мере, я бы не знал, как)
- изменить размер стека
Вещи, о которых я думаю:
- попробуйте разбить функцию на более мелкие части. Но я не знаю, как лучше всего это сделать.
- как-то прекомпилировать? функция (если честно, я просто догадываюсь), чтобы CRAN не жаловался?
Дайте мне знать ваши идеи!
Подробности / Фон
Причина, почему varzeta6()
(и varzeta4()
/ varzeta5()
и даже более того varzeta7()
) настолько длинны и R-неэффективны, что по существу они вставляются с помощью mathematica (после максимально возможного упрощения кода mathematica и его адаптации). быть действительным R-кодом). Следовательно, код ни в коем случае не оптимизирован для R (на что @MauritsEvers правильно указал).
Зачем нам математика? Потому что нам нужен общий вид корреляционной матрицы конструктивно подразумеваемой конструкции модели рекурсивного структурного уравнения, содержащей до 8 конструкций в зависимости от параметров уравнений модели. Кроме того, есть ограничения. Чтобы понять проблему, давайте возьмем систему из двух уравнений, которые могут быть рекурсивно решены:
- Y2 = beta1 * Y1 + zeta1
- Y3 = beta2 * Y1 + beta3 * Y2 + zeta2
Нам интересны ковариации: E (Y1 * Y2), E (Y1 * Y3) и E (Y2 * Y3) как функция от beta1, beta2 , бета3 при условии, что
- E (Y1) = E (Y2) = E (Y3) = 0,
- E (Y1 ^ 2) = E (Y2 ^ 2 ) = E (Y3 ^ 3) = 1
- E (Yi * zeta_j) = 0 (при i = 1, 2, 3 и j = 1, 2)
Для такая простая модель, это довольно тривиально:
- E (Y1 * Y2) = E (Y1 * (бета1 * Y1 + zeta1) = бета1 * E (Y1 ^ 2) + E (Y1 * zeta1) = beta1
- E (Y1 * Y3) = E (Y1 * (beta2 * Y1 + beta3 * (beta1 * Y1 + zeta1) + zeta2) = beta2 + beta3 * beta1
- E (Y2 * Y3) = ...
Но вы видите, как быстро это становится грязным, когда вы добавляете Y4, Y5, до Y8. В общем случае можно записать матрицу корреляции конструктивно подразумеваемой конструкции как (выражение на самом деле выглядит более сложным, потому что использование мы также допускаем до 5 экзогенных конструкций. Вот почему varzeta1()
уже выглядит сложным. Но пока проигнорируйте это.):
- V (Y) = (I - B) ^ - 1 В (дзета) (I - B) '^ - 1
где I - единичная матрица, а B - нижняя три angular матрица параметров модели (бета). V (дзета) является диагональной матрицей. Функции varzeta1()
, varzeta2()
, ..., varzeta7()
вычисляют основные диагональные элементы. Поскольку мы ограничиваем Var (Yi) всегда равным 1, дисперсии Зетов следуют. Возьмем для примера уравнение Var (Y2) = beta1 ^ 2 * Var (Y1) + Var (zeta1) -> Var (zeta1) = 1 - beta1 ^ 2. Здесь это выглядит просто, но становится чрезвычайно сложным, когда мы берем дисперсию, скажем, шестого уравнения в такой цепочке рекурсивных уравнений, потому что Var (zeta6) зависит от всех предыдущих ковариаций между Y1, ..., Y5, которые сами по себе зависит от их соответствующих предыдущих ковариаций.
Хорошо, я не знаю, делает ли это что-то более ясным. Вот основной смысл:
- Код для
varzeta1()
, ..., varzeta7()
является копией, вставленной из mathematica и, следовательно, не оптимизированной для R. - Mathematica требуется потому что, насколько я знаю, R не может обрабатывать символьные c вычисления.
- Я мог бы оптимизировать R "вручную" (что крайне утомительно)
- Я думаю, что структура
varzetaX()
должен быть принят как дано. Поэтому возникает вопрос: могу ли я так или иначе использовать эту функцию?