Случайное затенение и `Удалено [символ]` - PullRequest
3 голосов
/ 14 февраля 2011

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

findHull[points_] := Module[{},
   Needs["ComputationalGeometry`"];
   ConvexHull[points]
   ];
findHull[RandomReal[1, {10, 2}]];
Remove["Global`ConvexHull"];
findHull[RandomReal[1, {10, 2}]]

Ответы [ 2 ]

6 голосов
/ 14 февраля 2011

Проблема в том, что, хотя модуль не оценивается до тех пор, пока вы не вызовете findHull, символы разрешаются, когда вы определяете findHull (т.е.: новое значение для findHull сохраняется в виде символов, а не текста ). Это означает, что во время первого раунда ConvexHull преобразуется в Global`ConvexHull, поскольку Needs не оценивается. Во время второго раунда ComputationalGeometry включен $ContextPath, поэтому ConvexHull разрешается, как вы и планировали.

Если вы действительно не можете заранее загрузить ComputationalGeometry, просто обратитесь к ConvexHull по его полному имени: ComputationalGeometry`ConvexHull. См. Также этот связанный ответ .

НТН

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

Не прямой ответ на вопрос, но слишком большой для комментария.В качестве другой альтернативы, общий способ отложить анализ символа до времени выполнения - использовать Symbol["your-symbol-name"].В вашем случае вы можете заменить ConvexHull в правой части вашего определения на Symbol["ConvexHull"]:

findHull[points_] := 
 Module[{}, 
    Needs["ComputationalGeometry`"];
    Symbol["ConvexHull"][points]];

Это решение не очень элегантно, поскольку Symbol["ConvexHull"] будет выполняться каждый раз заново.Это также может быть несколько подвержено ошибкам, если вы делаете нетривиальные манипуляции с $ContextPath.Вот модифицированная версия в сочетании с обычно полезным трюком с самоопределением, который я использую в подобных случаях:

Clear[findHull];
findHull[points_] :=
Module[{},
  Needs["ComputationalGeometry`"];
  With[{ch = Symbol["ConvexHull"]},
    findHull[pts_] := ch[pts];
    findHull[points]]];

Например,

findHull[RandomReal[1, {10, 2}]]

{4, 10, 9, 1, 6, 2, 5}

Что происходит, когдаПри первом вызове функции исходное определение с Module заменяется внутренним, и это происходит уже после загрузки необходимого пакета и размещения его контекста на $ContextPath.Здесь мы используем тот факт, что Mathematica заменяет старое определение новым, если оно может определить, что шаблоны одинаковы - как это может быть в таких случаях.

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

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