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

Проблема динамической интерактивности

Я пытаюсь иметь две панели, слева - графические и два локатора, а справа - увеличенную версию в области, определяемой локаторами.

Я пробовал

ClearAll[mndpt];
mndpt = Compile[{{c, _Complex}, {maxiter, _Integer}},
   Module[{z, iters},
        iters = 0.;
        z = c;
            While[(iters < maxiter) && ([email protected] < 2),
                iters++;
                z = z^2 + c];
        Sqrt[iters/maxiter]],
   {{z, _Complex}},
   CompilationTarget \[Rule] "C",
   RuntimeOptions \[Rule] "Speed"];

и do

Manipulate[
 Grid[
  {{DensityPlot[mndpt[x + y*I, 200],
        {x, -2, 1}, {y, -1.5, 1.5},
        PlotRange \[Rule] {0, 1}, PlotPoints \[Rule] 80, 
     ColorFunction \[Rule] "Rainbow"],
    DensityPlot[mndpt[x + y*I, 200],
        [email protected]{x, p1[[1]], p2[[1]]}, [email protected]{y, p1[[2]], p2[[2]]},
        PlotRange \[Rule] {0, 1}, PlotPoints \[Rule] 80, 
     ColorFunction \[Rule] "Rainbow"]}}],
 {{p1, {-1, -1}}, Locator}, {{p2, {0, 1}}, Locator}]

Правая панель не работает: enter image description here

Мой вопрос: почему это так? Как вы можете видеть, он жалуется, что "DensityPlot:: pllim: Спецификация диапазона {x, -1,0} не имеет формы {x, xmin, xmax}.", Которую я нахожу загадочной. На самом деле я вообще озадачен. Что происходит? Какой-то вопрос? Вопрос оценки? И как я могу заставить его работать? Это, вероятно, просто, но я никогда не понимал этого внешнего вида.

EDIT: Оказывается, этот вопрос был вызван (надеюсь, мгновенным) резким увеличением глупости с моей стороны. Как отметил Саймон в комментарии, удаление двух Dynamics  (который я добавил вслепую, чтобы сделать эту работу), все работает нормально. То есть

    Manipulate[
 Grid[
  {{DensityPlot[mndpt[x + y*I, 200],
        {x, -2, 1}, {y, -1.5, 1.5},
        PlotRange \[Rule] {0, 1}, PlotPoints \[Rule] 80, 
     ColorFunction \[Rule] "Rainbow"],
    DensityPlot[mndpt[x + y*I, 200],
        {x, p1[[1]], p2[[1]]},{y, p1[[2]], p2[[2]]},
        PlotRange \[Rule] {0, 1}, PlotPoints \[Rule] 80, 
     ColorFunction \[Rule] "Rainbow"]}}],
 {{p1, {-1, -1}}, Locator}, {{p2, {0, 1}}, Locator}]

делает правильную вещь:

enter image description here

Итак, кто знает, почему еще я сделал первые несколько раз, чтобы он не работал.

С другой стороны, сообщение в исходном случае, а именно: "DensityPlot:: pllim: Спецификация диапазона (x, -1,0) не имеет формы {x, xmin, xmax}." было более озадачивающим, Я думаю, что это объяснил Леонид, также в комментарии (вкратце, попробуйте ClearAttributes[Dynamic, ReadProtected] then ??Dynamic, и вы увидите, что есть определение Dynamic/:MakeBoxes[BoxForm`x$_Dynamic,StandardForm]:= и т.д.). Поскольку мое понимание интерфейса программирования пренебрежимо мало, я не буду пытаться объяснить это здесь, поэтому, если кто-нибудь опубликует ответ, объясняющий это, было бы полезно.

4b9b3361

Ответ 1

Как обсуждалось в комментариях к вопросу, код работает нормально, если Dynamic удаляются из диапазонов во втором DensityPlot. Dynamic обычно не нужны в теле Manipulate, поскольку он автоматически завернут в динамическую конструкцию. Хотя для более тонкого управления некоторыми частями обновления выражения может быть полезно использовать Dynamic внутри Manipulate.

Причина, по которой была создана ошибка, заключалась в том, что диапазон графика должен иметь вид {x, xmin, xmax} с x a Symbol и xmin и xmax числовой. Обтекание Dynamic вокруг списка изменяет голову и разбивает график.

Причина, по которой ошибка не была очевидна, заключается в том, что сообщение об ошибке было немного запутанным:

Спецификация диапазона {x, -1,0} не имеет вида {x, xmin, xmax}.

Что на первый взгляд выглядит сумасшедшим, но имеет смысл, как только вы осознаете (как отметил Леонид), что Dynamic - это обертка, которая имеет определение MakeBoxes, которое делает его невидимым при выводе на ноутбук. Чтобы увидеть это, посмотрите

In[1]:= FormatValues[Dynamic]
Out[1]= {HoldPattern[MakeBoxes[BoxForm`x$_Dynamic, StandardForm]] :> (DynamicModule; 
           DynamicDump`ControlToBoxes[BoxForm`x$, StandardForm]), 
        <<snip: same but for TraditionalForm>>}

и ControlToBoxes, в свою очередь, создает объект DynamicBox. Это также можно увидеть, введя Dynamic[x] и используя меню ячеек или ярлык на Показать выражение созданной выходной ячейки - вы также можете посмотреть в основном выражении сообщения об ошибке и см. конструкцию DynamicBox. Также возможно Unprotect и удалить определение MakeBoxes Dynamic, но это нарушает большинство динамических функций в Mathematica...


Наконец, вот моя версия кода:

mndpt = Compile[{{c, _Complex}, {maxiter, _Integer}},
   Module[{z = c, iters = 0.0},
    While[(iters < maxiter) && ([email protected] < 2), iters++; z = z^2 + c];
    Sqrt[iters/maxiter]], CompilationTarget -> "C", 
   RuntimeOptions -> "Speed"];

opts = Sequence[PlotPoints -> 80, ColorFunction -> "Rainbow", 
   ImageSize -> Medium, ImagePadding -> {{30, 5}, {20, 5}}];

fixed = DensityPlot[mndpt[x + y*I, 200], {x, -2, 1}, {y, -1.5, 1.5}, 
   PlotPoints -> 120, Evaluate[opts]];

Manipulate[Grid[{{fixed, DensityPlot[mndpt[x + y*I, 200],
   {x, p[[1, 1]], p[[2, 1]]}, {y, p[[1, 2]], p[[2, 2]]}, Evaluate[opts]]}}],
 {{p, {{-1, -1}, {0, 1}}}, Locator, ContinuousAction -> False}]

output of the above