Подтвердить что ты не робот

Математика исчерпала память

Я пытаюсь запустить следующую программу, которая вычисляет корни многочленов степени до d с коэффициентами только +1 или -1, а затем сохраняет их в файлы.

d = 20; n = 18000; 
f[z_, i_] := Sum[(2 Mod[Floor[(i - 1)/2^k], 2] - 1) z^(d - k), {k, 0, d}];

Здесь f [z, i] дает многочлен от z с подсчетом знаков плюс или минус в двоичном выражении. Скажем, d = 2, мы имели бы

f [z, 1] = -z 2 - z - 1
f [z, 2] = -z 2 - z + 1
f [z, 3] = -z 2 + z - 1
f [z, 4] = -z 2 + z + 1

DistributeDefinitions[d, n, f]

ParallelDo[ 
            Do[ 
                     root = N[Root[f[z, i], j]];
                     {a, b} = Round[n ({Re[root], Im[root]}/1.5 + 1)/2];
            {i, 1, 2^d}],
{j, 1, d}]

Я понимаю, что это, вероятно, не слишком приятное, но в любом случае оно относительно короткое. Я бы попытался сократить соответствующие части, но здесь я действительно не понимаю, в чем проблема. Я вычисляю все корни f [z, i], а затем просто округляю их, чтобы они соответствовали точке в n по n сетке и сохраняли эти данные в разных файлах.

По какой-то причине использование памяти в Mathematica ползет до тех пор, пока оно не заполнит всю память (6 ГБ на этой машине); то вычисление продолжается очень медленно; почему это?

Я не уверен, что использует память здесь. Моей единственной догадкой был поток файлов, израсходованных на память, но это не так: я попытался добавить данные в 2GB файлы, и для этого не было заметного использования памяти. Кажется, нет никаких оснований для использования Mathematica больших объемов памяти здесь.

При малых значениях d (например, 15), поведение выглядит следующим образом: у меня есть 4 ядра. Поскольку все они проходят через цикл ParallelDo (каждый из которых выполняет значение j за раз), использование памяти увеличивается, пока они все не пройдут через этот цикл один раз. Затем в следующий раз они проходят через этот цикл, использование памяти не увеличивается вообще. Расчет в конечном итоге заканчивается, и все в порядке.

Кроме того, что очень важно, после прекращения вычисления использование памяти не возвращается. Если я начну другой расчет, произойдет следующее:

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

-Если предыдущий расчет прекратился, когда использование памяти не увеличивалось, оно больше не увеличивается.

Изменить: Проблема, похоже, связана с относительной сложностью f - изменения ее на несколько более простых полиномов, похоже, устраняет проблему. Я думал, что проблема может заключаться в том, что Mathematica запоминает f [z, i] для конкретных значений i, но устанавливая f [z, i]: =. сразу после вычисления корня f [z, i] жалуется, что назначение не было в первую очередь, а память все еще используется.

Это довольно озадачивает, так как f - единственная оставшаяся вещь, которую я могу себе представить, занимая память, но определение f во внутреннем цикле Do и ее очистка каждый раз после вычисления корня не решает проблему.

4b9b3361

Ответ 1

Ой, это противный.

Что происходит, так это то, что N сделает кеширование результатов, чтобы ускорить будущие вычисления, если они вам понадобятся. Иногда это абсолютно то, что вы хотите, но иногда это просто нарушает мир. К счастью, у вас есть несколько вариантов. Один из них - использовать команду ClearSystemCache, которая делает именно то, что она говорила на олове. После того, как я ненадолго запустил ваш нераспарализованный цикл (до того, как надоели и прервали расчет), MemoryInUse сообщил ~ 160 MiB в использовании. Использование ClearSystemCache получило примерно до 14 MiB.

Одна вещь, которую вы должны смотреть на выполнение, вместо вызова ClearSystemCache программно, заключается в использовании SetSystemOptions, чтобы изменить поведение кэширования. Вы должны посмотреть SystemOptions["CacheOptions"], чтобы узнать, что это за возможности.

EDIT: Не удивительно, что кеширование вызывает большую проблему для более сложных выражений. Это должно быть тиснение копий этих выражений где-то, и более сложные выражения требуют больше памяти.