Wolfram mathematica 在mathematica中如何进行这种替换

Wolfram mathematica 在mathematica中如何进行这种替换,wolfram-mathematica,Wolfram Mathematica,如果我不想使用mma的Erf或Erf函数,我想定义自己的函数 myErf[x_] := Integrate[Exp[-y^2/2], {y, -Infinity, x}]; 然后我希望mma用myErf[x]代替积分的任何求值,例如: Integrate[Exp[-y^2+y/2], {y, x, Infinity}] 如何做到这一点?或者一般来说,如何要求mma使用我希望它使用的函数来计算表达式,而不是它自己的内置函数?有没有办法做到这一点 非常感谢。我在评论中的意思是 Unprotect

如果我不想使用mma的Erf或Erf函数,我想定义自己的函数

myErf[x_] := Integrate[Exp[-y^2/2], {y, -Infinity, x}];
然后我希望mma用myErf[x]代替积分的任何求值,例如:

Integrate[Exp[-y^2+y/2], {y, x, Infinity}]
如何做到这一点?或者一般来说,如何要求mma使用我希望它使用的函数来计算表达式,而不是它自己的内置函数?有没有办法做到这一点


非常感谢。

我在评论中的意思是

Unprotect[Integrate];
Integrate[Exp[-y_^2], {y_, -\[Infinity], x_}] := myErf[x]
试图截取某些集成评估不起作用

事实上它确实有效

In[]:= Integrate[Exp[-y^2],{y,-Infinity,z}]
Out[]= myErf[z]
这将教会我在午夜回答如此问题。 因此,也许您不需要下面给出的myIntegrate函数

无论如何。。。评论中给出的两个备选方案是:

1您可以使用以下内容编写自己的Erf积分器

In[1]:= myErf[x_?NumericQ]:=NIntegrate[Exp[-y^2],{y,-\[Infinity],x}] 
(* sames as Erf up to constant and scaling *)

In[2]:= Clear[myIntegrate]
        myIntegrate[a_. Exp[b_. y_^2], {y_, -\[Infinity], x_}] /; FreeQ[{a, b}, y] := ConditionalExpression[myErf[x], b < 0]
        myIntegrate[a_. Exp[b_. y_^2], {y_, xx_, x_}] := myIntegrate[a Exp[b y^2], {y, -\[Infinity], x}] - myIntegrate[a Exp[b y^2], {y, -\[Infinity], xx}]
        myIntegrate[a_ + b_, lims__] := myIntegrate[a, lims] + myIntegrate[b, lims] (* assuming this is ok *)
        myIntegrate[expr_, lims__] := Integrate[expr, lims]

In[8]:= myIntegrate[a Exp[x]+b Exp[-b x^2],{x,2y,z}]
Out[8]= ConditionalExpression[a (-E^(2 y)+E^z) - myErf[2 y] + myErf[z], b > 0]
显然,您可以为myErf函数选择自己的约定

编辑: 由于Leonid做了你想做的事情,最简单、也许是最安全/最柔软的方法就是阻塞[{Erf=…},…],让Mathematica积分器完成所有工作。 例如,您的myErf被指定为

In[1]:= myErf[x] == Integrate[Exp[-y^2/2], {y, -Infinity, x}]
Out[1]= myErf[x]==Sqrt[Pi/2] (1+Erf[x/Sqrt[2]])
所以要解决你原来帖子中的积分问题

In[2]:= Block[{Erf = (Sqrt[2/Pi]*myErf[Sqrt[2] #] - 1 &)}, 
          Integrate[Exp[-y^2 + y/2], {y, x, Infinity}]]
Out[2]= (E^(1/16)(Sqrt[\[Pi]] (-1 + 4 x + Sqrt[(-1 + 4 x)^2]) + 
          Sqrt[2] (1 - 4 x) myErf[Sqrt[2] Sqrt[(-(1/4) + x)^2]])
        )/(2 Sqrt[(1 - 4 x)^2])
编辑2: 也许你只需要能够翻译myErf表达式。 这意味着它不是自动的,而是灵活的。试一试

In[1]:= toMyErf=(FunctionExpand[#]/.Erf:>(Sqrt[2/Pi]*myErf[Sqrt[2] #]-1&)&);
        fromMyErf=(#/.myErf:>(Sqrt[Pi/2] (1+Erf[#/Sqrt[2]])&)&);

In[3]:= Integrate[Exp[-y^2+y/2],{y,x,Infinity}]//toMyErf
Out[3]= 1/2 E^(1/16) Sqrt[\[Pi]] (2-Sqrt[2/\[Pi]] myErf[Sqrt[2] (-(1/4)+x)])
In[4]:= D[x*myErf[x+x^2],x]//fromMyErf//toMyErf
Out[4]= E^(-(1/2) (x+x^2)^2) x (1+2 x)+myErf[x+x^2]

注意,FunctionExpand命令用于将Erfc[x]重写为1-Erf[x]。您可能希望更好地实现该部分。

我在评论中的意思是

Unprotect[Integrate];
Integrate[Exp[-y_^2], {y_, -\[Infinity], x_}] := myErf[x]
试图截取某些集成评估不起作用

事实上它确实有效

In[]:= Integrate[Exp[-y^2],{y,-Infinity,z}]
Out[]= myErf[z]
这将教会我在午夜回答如此问题。 因此,也许您不需要下面给出的myIntegrate函数

无论如何。。。评论中给出的两个备选方案是:

1您可以使用以下内容编写自己的Erf积分器

In[1]:= myErf[x_?NumericQ]:=NIntegrate[Exp[-y^2],{y,-\[Infinity],x}] 
(* sames as Erf up to constant and scaling *)

In[2]:= Clear[myIntegrate]
        myIntegrate[a_. Exp[b_. y_^2], {y_, -\[Infinity], x_}] /; FreeQ[{a, b}, y] := ConditionalExpression[myErf[x], b < 0]
        myIntegrate[a_. Exp[b_. y_^2], {y_, xx_, x_}] := myIntegrate[a Exp[b y^2], {y, -\[Infinity], x}] - myIntegrate[a Exp[b y^2], {y, -\[Infinity], xx}]
        myIntegrate[a_ + b_, lims__] := myIntegrate[a, lims] + myIntegrate[b, lims] (* assuming this is ok *)
        myIntegrate[expr_, lims__] := Integrate[expr, lims]

In[8]:= myIntegrate[a Exp[x]+b Exp[-b x^2],{x,2y,z}]
Out[8]= ConditionalExpression[a (-E^(2 y)+E^z) - myErf[2 y] + myErf[z], b > 0]
显然,您可以为myErf函数选择自己的约定

编辑: 由于Leonid做了你想做的事情,最简单、也许是最安全/最柔软的方法就是阻塞[{Erf=…},…],让Mathematica积分器完成所有工作。 例如,您的myErf被指定为

In[1]:= myErf[x] == Integrate[Exp[-y^2/2], {y, -Infinity, x}]
Out[1]= myErf[x]==Sqrt[Pi/2] (1+Erf[x/Sqrt[2]])
所以要解决你原来帖子中的积分问题

In[2]:= Block[{Erf = (Sqrt[2/Pi]*myErf[Sqrt[2] #] - 1 &)}, 
          Integrate[Exp[-y^2 + y/2], {y, x, Infinity}]]
Out[2]= (E^(1/16)(Sqrt[\[Pi]] (-1 + 4 x + Sqrt[(-1 + 4 x)^2]) + 
          Sqrt[2] (1 - 4 x) myErf[Sqrt[2] Sqrt[(-(1/4) + x)^2]])
        )/(2 Sqrt[(1 - 4 x)^2])
编辑2: 也许你只需要能够翻译myErf表达式。 这意味着它不是自动的,而是灵活的。试一试

In[1]:= toMyErf=(FunctionExpand[#]/.Erf:>(Sqrt[2/Pi]*myErf[Sqrt[2] #]-1&)&);
        fromMyErf=(#/.myErf:>(Sqrt[Pi/2] (1+Erf[#/Sqrt[2]])&)&);

In[3]:= Integrate[Exp[-y^2+y/2],{y,x,Infinity}]//toMyErf
Out[3]= 1/2 E^(1/16) Sqrt[\[Pi]] (2-Sqrt[2/\[Pi]] myErf[Sqrt[2] (-(1/4)+x)])
In[4]:= D[x*myErf[x+x^2],x]//fromMyErf//toMyErf
Out[4]= E^(-(1/2) (x+x^2)^2) x (1+2 x)+myErf[x+x^2]
注意,FunctionExpand命令用于将Erfc[x]重写为1-Erf[x]。您可能希望更好地实现该部分。

更柔和的方法是使用UpValues:

在我们自定义的动态作用域构造之外,一切都将正常工作。把代码放在你想让它发生的地方。而且,从未对整合做出任何改变,这可能是危险的。这里我们所冒的风险是Exp不会求值,但我想它的大多数符号转换规则都是局部规则

编辑:

为了回答一般问题,如果你想改变Mathematica评估事物的标准方式,你有几个选择。在前面的回答中已经提到了其中的一些,我只想在更抽象的层次上对它们进行总结。给定一个表达式f[g[something]],通常可以:

重新定义g的DownValues-如果您希望将g重写为其他内容,这将起作用 在f看到它之前,但前提是f不把它的参数保持在g[某物]的位置 站立

针对表达式f[g[]]或类似值,为g添加一个UpValue。如果你愿意,这会有用的 想要以一种软的方式改变f的行为,也就是说,只对与 在这种情况下,UpValue定义f[g[]]。要使其工作,g和g都不应该 向下匹配g[something]的值,使其不进行计算,或者f应保持其值不变 论点这是一个典型的用例,当f是系统函数,g是用户定义的,因为 这是改变系统函数行为的最温和的方法-请注意 行为不同,规则附加到g

向f添加一个down值。这是一条艰难的道路。如果f保持其参数,或者 g[某事物]本身不会计算为其他事物,或者您必须临时添加 Hold-属性为f,这更具侵入性。如果f是一个系统函数,那么 方法是最后的手段。如果f是一个非平凡的或经常使用的 重要的内置功能,因为很难预测这样做的所有后果 修改,而许多系统功能正在顶层使用其他系统功能

编写自己的词法范围结构,它将以未计算的形式分析代码,并 进行适当的替换,然后才允许代码进行计算。这就需要你 可以完整地访问您的代码,也就是说,代码必须以您希望的形式存在于 开始,这是一个严格的限制,因此在实践中 在大多数情况下,n被排除在外

还有一个块技巧,它允许您通过将这种重新定义动态地局部化到您希望应用它们的代码块来定位损坏。在某些情况下,我觉得它是必不可少的,因为它允许非本地控制评估过程,而其他语言结构不容易复制这些过程。

更柔和的方法是使用UpValues:

在我们自定义的动态作用域构造之外,一切都将正常工作。把代码放在你想让它发生的地方。而且,从未对整合做出任何改变,这可能是危险的。这里我们所冒的风险是Exp不会求值,但我想它的大多数符号转换规则都是局部规则

编辑:

为了回答一般问题,如果你想改变Mathematica评估事物的标准方式,你有几个选择。在前面的回答中已经提到了其中的一些,我只想在更抽象的层次上对它们进行总结。给定一个表达式f[g[something]],通常可以:

重新定义g的DownValues-如果您希望将g重写为其他内容,这将起作用 在f看到它之前,但前提是f不把它的参数保持在g[某物]的位置 站立

针对表达式f[g[]]或类似值,为g添加一个UpValue。如果你愿意,这会有用的 想要以一种软的方式改变f的行为,也就是说,只对与 在这种情况下,UpValue定义f[g[]]。要使其工作,g和g都不应该 向下匹配g[something]的值,使其不进行计算,或者f应保持其值不变 论点这是一个典型的用例,当f是系统函数,g是用户定义的,因为 这是改变系统函数行为的最温和的方法-请注意 行为不同,规则附加到g

向f添加一个down值。这是一条艰难的道路。如果f保持其参数,或者 g[某事物]本身不会计算为其他事物,或者您必须临时添加 Hold-属性为f,这更具侵入性。如果f是一个系统函数,那么 方法是最后的手段。如果f是一个非平凡的或经常使用的 重要的内置功能,因为很难预测这样做的所有后果 修改,而许多系统功能正在顶层使用其他系统功能

编写自己的词法范围结构,它将以未计算的形式分析代码,并 进行适当的替换,然后才允许代码进行计算。这就需要你 可以完整地访问您的代码,也就是说,代码必须以您希望的形式存在于 开始,这是一个严格的限制,因此在实践中,在大多数情况下,此选项被排除在外


还有一个块技巧,它允许您通过将这种重新定义动态地局部化到您希望应用它们的代码块来定位损坏。在某些情况下,我觉得它是必不可少的,因为它允许非本地控制评估过程,而其他语言结构不容易复制这种过程。

对不起,我不知道您要找什么样的替代。你能发布期望的结果吗?我认为不可能轻易地覆盖Integrate的行为。我能想到的唯一两个选择是:1.编写自己的积分函数,搜索Erf类型的被积函数,然后将其余的传递回积分。2在mma的集成完成了它的魔力之后,你捕捉并重写Erf的。@Simon不管怎样,我想到的任何方法都有很多漏洞…@belisarius@李强:你能告诉我们你想这样做的动机吗?@belisarius:我相信在这种情况下你想要的结果是:1/Sqrt[2]*Exp[1/16]*myErf[Sqrt[2]*-1/4+x]对不起,我不知道你想要什么样的替代品。你能发布期望的结果吗?我认为不可能轻易地覆盖Integrate的行为。我能想到的唯一两个选择是:1.编写自己的积分函数,搜索Erf类型的被积函数,然后将其余的传递回积分。2在mma的集成完成了它的魔力之后,你捕捉并重写Erf的。@Simon不管怎样,我想到的任何方法都有很多漏洞…@belisarius@李强:你能告诉我们你想做这件事的动机吗?@belisarius:我相信在这种情况下你想要的结果是:1/Sqrt[2]*Exp[1/16]*myErf[Sqrt[2]*-1/4+x]+1,显示如何定义你自己的积分器的提示。不确定这个案子是否值得。不是你的错。非常感谢你的更新。它起作用了。但也许我要求太多了。如果我有另一个要求在myErf[x]上得到导数,例如,Block[{Erf=Sqrt[2/Pi]*myErf[Sqrt[2]]-1&},D[x*myErf[x+x^2],x]]不起作用怎么办。@Liang:请看新的加法。如果你能简单地在Erf和myErf函数之间进行转换,也许这是最好的。这太棒了。我接受了

我不知道你的答案。你能解释一下为什么你的意思是“如果你能简单地在Erf和myErf函数之间进行转换”。@李强:我只是指我在编辑2中写的东西。也就是说,您可以手动翻译,而不是自动翻译。+1用于显示有关如何定义自己的集成器的提示。不确定这个案子是否值得。不是你的错。非常感谢你的更新。它起作用了。但也许我要求太多了。如果我有另一个要求在myErf[x]上得到导数,例如,Block[{Erf=Sqrt[2/Pi]*myErf[Sqrt[2]]-1&},D[x*myErf[x+x^2],x]]不起作用怎么办。@Liang:请看新的加法。如果你能简单地在Erf和myErf函数之间进行转换,也许这是最好的。这太棒了。我接受你的回答。你能解释一下为什么你的意思是“如果你能简单地在Erf和myErf函数之间进行转换”。@李强:我只是指我在编辑2中写的东西。也就是说,你可以手动翻译,而不是自动翻译。软方法是为软的人准备的!那些关心代码可能产生的不必要的副作用的人+1@Simon我以前也是这样想的。直到有一天,我发现了一只虫子,花了我好几天的时间才弄明白,男孩觉得很难。这些天我更小心了,但不可否认的是我也更温柔了——所以你在某种程度上是对的:@Leonid:withMyErf[Integrate[Exp[-x^2+x/2],{x,-Infinity,t}]为什么不起作用?你能解释一下吗?非常感谢。@Qiang Li:显然,这种模式不够通用,它只在有平方项时才匹配,其他什么都不匹配。我的主要观点是说明如何使用UpValues实现这一点,而不是提供最通用的解决方案。您也可以扩展模式以匹配您的表达式,方法是在平方项模式中添加+c::1*x+d::0之类的内容,也许还可以将r.h.s.更改为相应的更一般的形式。@Simon,@Leonid:I仍然无法获得表达式Integrate[Exp[-y^2+y/2]所需的结果1/Sqrt[2]*Exp[1/16]*myErf[Sqrt[2]*-1/4+x],使用此方法。请您提供一个工作示例好吗?非常感谢。软的方式是为软的人!那些关心代码可能产生的不必要的副作用的人+1@Simon我以前也是这样想的。直到有一天,我发现了一只虫子,花了我好几天的时间才弄明白,男孩觉得很难。这些天我更小心了,但不可否认的是我也更温柔了——所以你在某种程度上是对的:@Leonid:withMyErf[Integrate[Exp[-x^2+x/2],{x,-Infinity,t}]为什么不起作用?你能解释一下吗?非常感谢。@Qiang Li:显然,这种模式不够通用,它只在有平方项时才匹配,其他什么都不匹配。我的主要观点是说明如何使用UpValues实现这一点,而不是提供最通用的解决方案。您也可以扩展模式以匹配您的表达式,方法是在平方项模式中添加+c::1*x+d::0之类的内容,也许还可以将r.h.s.更改为相应的更一般的形式。@Simon,@Leonid:I仍然无法获得表达式Integrate[Exp[-y^2+y/2]所需的结果1/Sqrt[2]*Exp[1/16]*myErf[Sqrt[2]*-1/4+x],使用此方法。请您提供一个工作示例好吗?非常感谢。