用于为DiscreteShift设置upvalue的模式

Pat*_*ill 3 design-patterns wolfram-mathematica

我想为DiscreteShift设置一个upvalue,它可以改变被提升为幂的规则:

Unprotect[DiscreteShift];
DiscreteShift /: Power[DiscreteShift[f_, i_], r_] := DiscreteShift[f, {i, r}];
Protect[DiscreteShift];
Power[DiscreteShift[f[n], n], 2] === DiscreteShift[f[n], {n, 2}]
Run Code Online (Sandbox Code Playgroud)

但我收到这些错误消息:

Rule::rhs: "Pattern i_ appears on the right-hand side of rule i_->1+i_. "
TagSetDelayed::tagnf: "Tag DiscreteShift not found in (1+Pattern[f_,_])^r_."
Run Code Online (Sandbox Code Playgroud)

它似乎不喜欢DiscreteShift参数的模式,但我也无法在那里工作.写这个的正确方法是什么?

编辑: 我会尽力澄清我的目标.这是我想用数学方法做的事情:

(N + n) f(n) = N f(n) + n f(n)
             = f(n+1) + n f(n)

(N + n)^2 f(n) = (N^2 + Nn + nN + n^2) f(n)
               = N^2 f(n) + Nn f(n) + nN f(n) + n^2 f(n)
               = f(n+2) + (n+1) f(n+1) + n f(n+1) + n^2 f(n)
               = f(n+2) + (2n+1) f(n+1) + n^2 f(n)
Run Code Online (Sandbox Code Playgroud)

所以我有这个有趣的N运算符作为一个离散的移位,我们有点重载乘法的意义,让它在一个函数上运行.我希望N f(n)通过使用DiscreteShift[f[n],n],然后修复它的电源规则来表示.

Mr.*_*ard 5

问题是DiscreteShift[f[n], n]Power[DiscreteShift[f[n], n], 2]评估f[1 + n]之前发生任何其他事情.这会影响您创建规则的尝试以及实际执行Power[DiscreteShift[f[n], n], 2].

与您的结果比较:

Unprotect[DiscreteShift];
DiscreteShift /: Power[HoldPattern[DiscreteShift[f_, i_]], r_] := 
  DiscreteShift[f, {i, r}];

Power[Unevaluated@DiscreteShift[f[n], n], 2] === DiscreteShift[f[n], {n, 2}]
Run Code Online (Sandbox Code Playgroud)
(* Out[] = True *)

belisarious提供了一个方法的链接,您可以通过该方法拦截内置函数的评估以插入您自己的代码.但是,我认为很难将它与TagSetDiscreteShift 结合起来.

  • @Patrick用`Hold`简单替换`HoldPattern`和`Unevaluated`将失败,因为嵌套太深了.此外,通常不建议将符号重载为"Power".如果您愿意更详细地描述您的申请,我可能会有一个合适的建议(如果您认为合适,可以对其进行编辑). (2认同)