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

Обнаружение и стилизация нескольких функций в Mathematica Plot

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

Рассмотрим:

Plot[{1, Sequence[2, 3], 4}, {x, 0, 1}, PlotRange -> {0, 5}]

enter image description here

Я понимаю, что Plot сначала изначально содержит три элемента в списке, но как он "знает" стиль 2 и 3 одинаковый? Кажется, что есть память о том, в какой части исходного списка эти два элемента пришли. Как это работает?

4b9b3361

Ответ 1

Ну, он знает, что есть три аргумента именно так:

In[13]:= Function[x, Length[Unevaluated[x]], HoldAll][{1, 
  Sequence[2, 3], 4}]

Out[13]= 3

Если x разрешено оценивать, то

In[14]:= Function[x, Length[x], HoldAll][{1, Sequence[2, 3], 4}]

Out[14]= 4

РЕДАКТИРОВАТЬ: С этим лучше справиться:

In[15]:= Hold[{1, Sequence[2, 3], 4}]

Out[15]= Hold[{1, Sequence[2, 3], 4}]

Другими словами, для выравнивания последовательности требуется оценщик.

РЕДАКТИРОВАТЬ 2: Я явно пропустил реальный поставленный вопрос и попытаюсь ответить на него сейчас.

Как только Plot определяет количество аргументов, которые он создает {{style1, Line..}, {style2, Line..},...}. В случае {1, Sequence [2,3], 4} получаем следующую структуру:

In[23]:= Cases[
  Plot[{1, Sequence[2, 3], 4}, {x, 0, 1}, 
   PlotRange -> {0, 5}], {_Hue, __Line}, 
  Infinity] /. {x_Line :> Line, _Hue -> Hue}

Out[23]= {{Hue, Line}, {Hue, Line, Line}, {Hue, Line}}

При построении графика {1, {2,3}, 4} мы получаем другую структуру:

In[24]:= Cases[
  Plot[{1, List[2, 3], 4}, {x, 0, 1}, 
   PlotRange -> {0, 5}], {_Hue, __Line}, 
  Infinity] /. {x_Line :> Line, _Hue -> Hue}

Out[24]= {{Hue, Line}, {Hue, Line}, {Hue, Line}, {Hue, Line}}

потому что списки будут сплющены, просто не используя оценщика. Так как вы видите, что теги в том же цвете происходят, потому что Sequence [2,3] рассматривается как функция черного ящика, которая возвращает список из двух элементов:

In[25]:= g[x_?NumberQ] := {2, 3}

In[26]:= Cases[
  Plot[{1, g[x], 4}, {x, 0, 1}, PlotRange -> {0, 5}], {_Hue, __Line}, 
  Infinity] /. {x_Line :> Line, _Hue -> Hue}

Out[26]= {{Hue, Line}, {Hue, Line, Line}, {Hue, Line}}

Я пытался создать реализацию на высшем уровне, которая построила бы такую ​​структуру, но нужно бороться с оценщиком. Например:

In[28]:= Thread /@ Function[x,
   Thread[{Hold @@ {Range[Length[Unevaluated[x]]]}, Hold[x]}, Hold]
   , HoldAll][{1, Sequence[2, 3], 4}]

Out[28]= Hold[Thread[{{1, 2, 3}, {1, Sequence[2, 3], 4}}]]

Теперь мы должны оценить Thread, не оценивая его аргументы, что дало бы {{1, 1}, {2, Sequence [2,3]}, {3, 4}}, где первый элемент списка является тегом, а последующие один раз - это функции, которые должны быть выбраны.

Надеюсь, что это поможет.

Ответ 2

Не так сложно представить процесс, который приводит к этому результату. У меня нет дополнительных доказательств того, что это действительно то, что происходит, но разумно предположить, что Plot перебирает список переданных ему функций и связывает стиль с каждым. Затем он начинает оценивать каждую из них после установки значения переменной сюжета. Обычно каждая "функция" (элемент в списке, переданный в Plot), возвращает реальное число. Однако, начиная с версии 6, Mathematica может обрабатывать те, которые возвращают списки номеров тоже, с недостатком, что он использует тот же стиль для полного списка. Версия 5 будет выдавать ошибку для функций, которые возвращают списки.