Рассказывая заговор для стилизации векторных функций черного ящика в Mathematica - PullRequest
11 голосов
/ 08 апреля 2011

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

fun[x_?InexactNumberQ] := Module[{f = Sin[x]}, {Re[f], Im[f]}]

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

screen-shot of plot with both curves being the same color

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

gr = Plot[fun[x + I], {x, -1, 1}, ImageSize -> 250];
k = 1;
{gr, gr /. {el_Line :> {ColorData[1][k++], el}}}

two images, one with styling applied

Ответы [ 3 ]

7 голосов
/ 08 апреля 2011

Возможны следующие варианты:

Plot[{#[[1]], #[[2]]}, {x, -1, 1}, PlotStyle -> {{Red}, {Blue}}] &@ fun[x + I]  

enter image description here

Редактировать

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

Например:

fun[x_?InexactNumberQ] := Module[{f = Sin[3  x]}, {Re[f], Im[f]}];
Plot[{#[[1]], #[[2]]}, {x, -1, 1}, Mesh -> All, 
   PlotStyle -> {{Red}, {Blue}}] &@fun[x + I]  

enter image description here

3 голосов
/ 08 апреля 2011

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

Причина, по которой вы, возможно, не захотите делать то, что предложил @belisarius, заключается в том, что она будет вычислять функцию дважды (вдвое медленнее).

Тем не менее, вы можете использовать мемоизацию, чтобы избежать этого (то есть конструкцию f [x_]: = f [x] = ...), и пойти с его решением. Но это может быстро заполнить вашу память, если вы работаете с реальными функциями. Чтобы предотвратить это, вы можете попробовать то, что я написал о кэшировании только ограниченного числа значений, чтобы избежать заполнения памяти: http://szhorvat.net/pelican/memoization-in-mathematica.html

0 голосов
/ 08 апреля 2011

Если возможно для вашего реального применения, один из способов - разрешить fun принимать символьный ввод в дополнение к обычному числовому, а затем Evaluate его внутри Plot:

fun2[x_] := Module[{f = Sin[x]}, {Re[f], Im[f]}]

Plot[Evaluate[fun2[x + I]], {x, -1, 1}]

enter image description here

Это имеет тот же эффект, как если бы вы вместо этого оценивали:

Plot[{-Im[Sinh[1 - I x]], Re[Sinh[1 - I x]]}, {x, -1, 1}]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...