Обнаружение и стилизация нескольких функций в сюжете Mathematica - PullRequest
12 голосов
/ 09 апреля 2011

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

Рассмотрим:

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

enter image description here

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

Ответы [ 2 ]

9 голосов
/ 09 апреля 2011

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

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}}]]

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

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

8 голосов
/ 09 апреля 2011

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

...