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

Вычисление графика для создания векторных функций черного ящика в Mathematica

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

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

Затем я могу использовать его в Plot, как обычно, но Plot не распознает, что функция возвращает пару, и окрашивает оба кривых одного цвета. Как сказать 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

4b9b3361

Ответ 1

Одна из возможностей:

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

enter image description here

Изменить

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

Например:

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

Ответ 2

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

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

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

Ответ 3

Если возможно для вашего реального приложения, один из способов - позволить 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}]