Я выполняю поиск грубой силы для «градиентных экстремалей» в следующем примере функции
fv[{x_, y_}] = ((y - (x/4)^2)^2 + 1/(4 (1 + (x - 1)^2)))/2;
Это включает в себя нахождение следующих нулей
gecond = With[{g = D[fv[{x, y}], {{x, y}}], h = D[fv[{x, y}], {{x, y}, 2}]},
g.RotationMatrix[Pi/2].h.g == 0]
Что Reduce
с радостью делает для меня:
geyvals = y /. Cases[List@ToRules@Reduce[gecond, {x, y}], {y -> _}];
geyvals
— это три корня кубического многочлена, но выражение здесь слишком велико.
Теперь к моему вопросу: для разных значений x
разные числа этих корней являются реальными, и я хотел бы выбрать значения x
, где разветвляются решения, чтобы собрать воедино экстремали градиента вдоль дна долины (из fv
) . В данном случае, поскольку многочлен только кубический, я, вероятно, мог бы сделать это вручную, но я ищу простой способ заставить Mathematica сделать это за меня?
Правка: поясняю: экстремумы градиента — это просто фон и простой способ решить сложную задачу. Меня интересует не столько конкретное решение этой проблемы, сколько общий ручной способ определения точек ветвления для полиномиальных корней. Добавили ответ ниже с рабочим подходом.
Редактировать 2: Поскольку кажется, что реальная проблема намного интереснее, чем корневое ветвление: rcollyer предлагает использовать ContourPlot
непосредственно на gecond
, чтобы получить экстремали градиента. Чтобы сделать это полным, нам нужно разделить долины и хребты, что делается путем просмотра собственного значения гессиана, перпендикулярного градиенту. Поставив галочку на «долины» как RegionFunction
, мы останемся только с линией долины:
valleycond = With[{
g = D[fv[{x, y}], {{x, y}}],
h = D[fv[{x, y}], {{x, y}, 2}]},
g.RotationMatrix[Pi/2].h.RotationMatrix[-Pi/2].g >= 0];
gbuf["gevalley"]=ContourPlot[gecond // Evaluate, {x, -2, 4}, {y, -.5, 1.2},
RegionFunction -> Function[{x, y}, Evaluate@valleycond],
PlotPoints -> 41];
Что дает только линию дна долины. Включая некоторые контуры и седловую точку:
fvSaddlept = {x, y} /. First@Solve[Thread[D[fv[{x, y}], {{x, y}}] == {0, 0}]]
gbuf["contours"] = ContourPlot[fv[{x, y}],
{x, -2, 4}, {y, -.7, 1.5}, PlotRange -> {0, 1/2},
Contours -> fv@fvSaddlept (Range[6]/3 - .01),
PlotPoints -> 41, AspectRatio -> Automatic, ContourShading -> None];
gbuf["saddle"] = Graphics[{Red, Point[fvSaddlept]}];
Show[gbuf /@ {"contours", "saddle", "gevalley"}]
В итоге получаем такой сюжет:
gecond
дает тебе экстремалов? Я просто не вижу этого. - person rcollyer   schedule 15.12.2010gecond
. - person rcollyer   schedule 15.12.2010ContourPlot[g.RotationMatrix[Pi/2].h.g == 0]
. - person rcollyer   schedule 16.12.2010RegionFunction
, что это было? - person rcollyer   schedule 17.12.2010PlotRange
, я включу полный код сюжета выше. - person Janus   schedule 22.12.2010