Частичная оценка в Mathematica

У меня есть дифференциальный оператор, который действует на две функции. Для упрощения задачи допустим, что мой оператор

A[F_,G_] := D[F,x] D[G,y]

Я хочу иметь возможность, если я знаю F, определить дифференциальный оператор AF так, что AF[G] равен A[F,G]. Очевидный способ

AF[G_] := A[F,G]

который работает без проблем. Но мне бы очень хотелось устроить так, чтобы при вызове AF с разными аргументами G1, G2,... производная D[F,x] вычислялась не каждый раз, а только один раз. Более того, я бы хотел, чтобы определение AF не зависело от конкретной формы A, так как A передается в качестве аргумента моей функции.

Я прочитал справку по Hold, HoldAll, Evaluate и т. д., но не могу совместить эти вещи, чтобы получить то, что хочу. Я даже не знаю, возможно ли то, что я хочу, в Mathematica.


person cefstat    schedule 29.09.2009    source источник


Ответы (2)


С проблемой, которую вы описываете, я не вижу прямого способа сделать это. Одна вещь, которую вы могли бы сделать, чтобы переделать его, чтобы сделать его значительно проще, - это переопределить A, чтобы он был функцией производных от F и G. Если у вас есть

A[{dFdx_,dFdy_}, {dGdx_,dGdy_}] := dFdx*dFdy 

вы будете в очень хорошем положении, чтобы вычислить производные от F, которые вам нужны, а затем определить AF способом, который является общим по отношению к A, например так:

With[{ dFdx = D[F,x], dFdy = D[F,y] },
  AF[G_] := A[{dFdx, dFdy}, {D[G, x], D[G, y]}]]

Вы можете использовать With для замены оцененных частей в неоцененной правой части формы SetDelayed (определение с использованием ":="), как показано. Однако, если вы не сможете внести это изменение, все станет запутанным, и вам придется сделать некоторые предположения о том, что такое A.

Если A является символом с определенными для него значениями DownValues ​​и имеет простое определение, то вы можете выполнить частичную оценку, которую хотите, используя Hold, выполнив замену правил, а затем выполнив ReleaseHold, например:

ReleaseHold[
  Hold[AF[G_] := A[F, G]] /. DownValues[A] /. 
    HoldPattern[D[F, var_]] :> With[{eval = D[F, var]}, eval /; True]]

Бит With[...] во втором правиле — это уловка для принудительной оценки чего-то, соответствующего шаблону внутри Hold, называемого "метод Тротта-Стшебонского", малопонятный, но чрезвычайно полезный для подобных задач. Однако этот путь действительно ограничивает ваш интерфейс, а это означает, что вы не можете, скажем, передать чистую функцию для A, а с более сложным определением этот трюк, вероятно, тоже не сработает. Если вам удастся указать, что ваша дифференциальная форма будет функцией реальных производных, я настоятельно рекомендую это сделать.

EDIT: я придумал более общий и надежный способ сделать это.

Хитрость заключается в том, чтобы временно подавить определение D (оператор производной) с помощью Block, чтобы производные в определении A остались невычисленными, а затем использовать замену правил, чтобы подставить значения для производных от F, одновременно завершая все. в чистой функции, чтобы получить правильную замену имени, например:

With[{fRules =
 {HoldPattern[D[F, x]] :> Evaluate[D[F, x]]}},
   Block[{D},
     With[{fn = Function[G, Evaluate[A[F, G] /. fRules]]},
       AF[G_] := fn[G]]]]
person Pillsy    schedule 29.09.2009
comment
Спасибо! Это сработало отлично. Я сделал несколько несущественных изменений, чтобы учесть возможность наличия более одной переменной x, y и т. д. Таким образом, я использовал код AF = With[ {fRules = {HoldPattern[D[F, x_]] :› Вычислить[D[F, x]]}}, Блок[{D}, Функция[G, Вычислить[A[F, G]] /. fПравила]]]]; - person cefstat; 29.09.2009

Разве вы не можете просто сделать:

A[F_] := With[{DF = D[F, x]}, Function[{G}, DF D[G, y]]]

Это похоже на каррирование в реальном функциональном языке программирования, таком как F#, где вы должны написать:

let a f =
  let df = d f x
  fun g -> df * d g y
person J D    schedule 22.04.2010
comment
Если A известно и приведено в виде функции производных от F и G заранее, это работает нормально. Но если это не так, вам нужно отложить оценку производных от G, принудительно оценивая производные от F, что требует дополнительных шагов. - person Pillsy; 23.04.2010