Очистка числовых значений в Mathematica - PullRequest
1 голос
/ 14 апреля 2011

Я работаю над довольно большими проектами Mathematica, и возникает проблема, что я должен периодически проверять числовые результаты, но хочу легко вернуться к тому, чтобы все мои конструкции были в аналитической форме.

Код довольно изменчив, я не хочу везде использовать контекстные конструкции, так как они увеличивают нагрузку.Есть ли простой способ для идентификации и очистки всех заданий, которые являются числовыми?

РЕДАКТИРОВАТЬ: я действительно знаю, что определение объема является способом сделать это правильно ;-).Тем не менее, для моего рабочего процесса я на самом деле просто ищу подвох, чтобы отменить все числовые назначения после факта, вместо того, чтобы предвидеть, чтобы снять блок.

Ответы [ 2 ]

2 голосов
/ 14 апреля 2011

Если ваши назначения находятся на верхнем уровне, вы можете использовать что-то вроде этого:

a = 1;
b = c;
d = 3;
e = d + b;

Cases[DownValues[In],
   HoldPattern[lhs_ = rhs_?NumericQ] | 
   HoldPattern[(lhs_ = rhs_?NumericQ;)] :> Unset[lhs],
3]

Это будет работать, если у вас достаточная длина истории $HistoryLength (по умолчанию - бесконечность).Однако обратите внимание, что в приведенном выше примере e был присвоен 3+c, а 3 здесь не был отменен.Таким образом, проблема действительно неоднозначна в формулировке, потому что некоторые числа могут превратить ее в определения.Один из способов избежать этого - использовать SetDelayed для назначений, а не Set.

Другой альтернативой может быть анализ имен в, скажем, Global' контексте (если это контекст, в котором живут ваши символы)), а затем произнесите OwnValues и DownValues символов способом, аналогичным описанному выше, и удалите определения с чисто числовыми rhs

Но IMO ни один из этих подходов не является надежным.Я все еще использую ограничивающие конструкции и пытаюсь выделить числовые значения.Одна из возможностей - заключить окончательный код в Block и присвоить числовые значения внутри этого Block.Это выглядит намного чище.Затраты на работу минимальны - вам просто нужно запомнить, каким символам вы хотите присвоить значения.Block автоматически гарантирует, что вне него символы не будут иметь определений.

РЕДАКТИРОВАТЬ

Еще одна возможность заключается в использовании локальных правил.Например, можно определить rule[a] = a->1; rule[d]=d->3 вместо назначений выше.Затем вы можете применить эти правила, извлекая их, скажем, DownValues[rule][[All, 2]], всякий раз, когда вы хотите проверить с некоторыми числовыми аргументами.

1 голос
/ 14 апреля 2011

Опираясь на решение Эндрю Мойлана , можно создать блочную функцию, которая бы принимала правила:

SetAttributes[BlockRules, HoldRest]

BlockRules[rules_, expr_] := 
 Block @@ Append[Apply[Set, Hold@rules, {2}], Unevaluated[expr]]

Затем вы можете сохранить свои числовые правила в переменной и использовать BlockRules.[сохраненные правила, код] или даже определить функцию, которая будет применять фиксированный набор правил, например, так:

In[76]:= NumericCheck = 
  Function[body, BlockRules[{a -> 3, b -> 2`}, body], HoldAll];

In[78]:= a + b // NumericCheck

Out[78]= 5.

РЕДАКТИРОВАТЬ В ответ на комментарий Тимо может быть возможно использовать NotebookEvaluate (новое в 8) для достижения запрошенного эффекта.

SetAttributes[BlockRules, HoldRest]
BlockRules[rules_, expr_] := 
 Block @@ Append[Apply[Set, Hold@rules, {2}], Unevaluated[expr]]

nb = CreateDocument[{ExpressionCell[
     Defer[Plot[Sin[a x], {x, 0, 2 Pi}]], "Input"],
    ExpressionCell[Defer[Integrate[Sin[a x^2], {x, 0, 2 Pi}]], 
     "Input"]}];
BlockRules[{a -> 4}, NotebookEvaluate[nb, InsertResults -> "True"];]

В результате этой оценки вы получите блокнот с вашими командами, оцененными, когда локально было установлено значение 4. Чтобы продолжить, вам нужно будет взять блокнот с вашим кодом, открытьновый блокнот, оцените Notebooks[], чтобы найти интересующий блокнот, а затем выполните:

BlockRules[variablerules, 
 NotebookEvaluate[NotebookPut[NotebookGet[nbobj]], 
  InsertResults -> "True"]]

Надеюсь, вы сможете реализовать эту идею.

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...