SaveDefinitions
- хороший вариант Manipulate
. Это заставляет Manipulate
хранить любые определения, используемые для его создания внутри панели Манипулировать. Манипулирование, сделанное таким образом, можно скопировать в пустой блокнот и по-прежнему работать самостоятельно. Кроме того, ваш рабочий блокнот, содержащий много таких манипуляторов, также не превращается в шквал розовых коробок с напечатанными сообщениями об ошибке ниже его при открытии. Отлично!
Однако вся эта доброта имеет свою темную сторону, которая может сильно вас укусить, если вы не знаете об этом. У меня это было в записной книжке, над которой я работал несколько дней, но представляю вам пошаговый пример примера игрушек, который воссоздает проблему.
В этом сценарии вы хотите создать Manipulate
, показывающий график хорошей волнистой функции, поэтому вы определяете это (пожалуйста, сделайте такой размер окна, это важно):
Определение хорошее, поэтому мы сохраняем его в следующий раз и делаем его ячейкой инициализации. Затем добавим Manipulate
и выполним его.
f[x_] := x^2
Manipulate[
Plot[n f[x], {x, -3, 3}],
{n, 1, 4},
SaveDefinitions -> True
]
Все отлично работает, Manipule действительно сияет, это хороший день.
Просто будучи вашим параноидальным явлением, вы проверяете, хорошо ли это определение:
Да, все еще проверяется. Хорошо. Но теперь вам приходит в голову, что лучшая волнистая функция будет синусоидальной, поэтому вы измените определение, выполните и параноик, проверьте:
Все по-прежнему хорошо. Вы готовы с тяжелой работы на день, вы сохраняете свою работу и уходите. Выйти из ядра.
На следующий день. Вы снова начинаете свою работу. Вы оцениваете ячейки инициализации в своем ноутбуке. Определение все еще хорошее? Проверьте.
Теперь прокрутите вниз до поля Манипуляции (нет необходимости повторять выполнение с помощью SaveDefinitions
), немного поиграйте со слайдером. И прокрутите резервную копию.
Будучи параноиком вас, вы еще раз проверите определение f:
Вот и кто-то изменил определение за вашей спиной! И ничего не выполнялось между вашей первой и второй проверкой Information
(?) В соответствии с номерами In [] (In[1]
: def f, In[2]
first?, In[3]
second?).
Что случилось? Ну, это, конечно, Manipulate
. A FullForm
показывает свою внутреннюю структуру:
Manipulate[Plot[n*f[x],{x, -3, 3}],{{n, 2.44}, 1, 4},Initialization:>{f[x_] := x^2}]
Там у вас есть преступник. Часть инициализации поля определяет f снова, но это старая версия, потому что мы не переоценили значение Manipulate
после изменения ее определения. Как только поле манипуляции появится на экране, оно будет оценено, и вы вернете свое прежнее определение. Во всем мире!
Конечно, в этом примере игрушек сразу видно, что происходит что-то странное. В моем случае у меня был более крупный модуль в более крупном ноутбуке, в котором я, после некоторой отладки, изменил небольшую часть. Казалось, это сработало, но на следующий день такая же ошибка, которая прослушивала меня, прежде чем снова нанести удар. Мне потребовалось пару часов, прежде чем я понял, что один из нескольких Манипуляций, которые я использовал для изучения проблемы со всех сторон, делал это.
Ясно, что у меня возникает соблазн сказать, что это нежелательное поведение. Теперь, по обязательному вопросу: , что мы можем сделать, чтобы предотвратить возникновение этого позади вашего поведения Manipulate
, кроме повторного выполнения каждого Manipulate
в вашем ноутбуке каждый раз, когда вы меняете определение, которое может быть используемые ими?