Wolfram mathematica 极大值在相对简单的积分上崩溃

Wolfram mathematica 极大值在相对简单的积分上崩溃,wolfram-mathematica,maxima,Wolfram Mathematica,Maxima,我正试图最大化我的Mathematica box期权公式 (https://github.com/barrycarter/bcapps/blob/master/box-option-value.m) 但Maxima在一个相当简单的集成上崩溃了: load(distrib); pdflp(x, p0, v, p1, p2, t1, t2) := pdf_normal(x,log(p0),sqrt(t1)*v); cdfmaxlp(x, p0, v, p1, p2, t1, t2) := 1-

我正试图最大化我的Mathematica box期权公式 (https://github.com/barrycarter/bcapps/blob/master/box-option-value.m) 但Maxima在一个相当简单的集成上崩溃了:

load(distrib); 
pdflp(x, p0, v, p1, p2, t1, t2) := pdf_normal(x,log(p0),sqrt(t1)*v); 
cdfmaxlp(x, p0, v, p1, p2, t1, t2) := 1-erf(x/(v*sqrt(t2-t1)/sqrt(2))); 

upandin(p0, v, p1, p2, t1, t2) :=  
 integrate( 
 float( 
 pdflp(x, p0, v, p1, p2, t1, t2)* 
 cdfmaxlp(log(p1)-x, p0, v, p1, p2, t1, t2) 
 ), 
 x, minf, log(p1)); 
在具有特定值的情况下评估upandin:

upandin(1, .15, 1.01, 1.02, 1/365.2425, 2/365.2425); 

rat: replaced -.00995033085316809 by -603/60601 = -.00995033085262619 

rat: replaced 2.718281828459045 by 23225/8544 = 2.718281835205993 

rat: replaced 8116.5 by 16233/2 = 8116.5 

rat: replaced 2.718281828459045 by 23225/8544 = 2.718281835205993 

rat: replaced -8116.5 by -16233/2 = -8116.5 

rat: replaced 1.0 by 1/1 = 1.0 

rat: replaced 1.792882852833688 by 4484/2501 = 1.792882846861255 

rat: replaced 180.1832400641081 by 126849/704 = 180.1832386363636 

rat: replaced 2.718281828459045 by 23225/8544 = 2.718281835205993 

rat: replaced -8116.5 by -16233/2 = -8116.5 

rat: replaced -1.0 by -1/1 = -1.0 

rat: replaced 1.792882852833688 by 4484/2501 = 1.792882846861255 

rat: replaced 180.1832400641081 by 126849/704 = 180.1832386363636 

rat: replaced 2.718281828459045 by 23225/8544 = 2.718281835205993 

rat: replaced -8116.5 by -16233/2 = -8116.5 

rat: replaced 1.0 by 1/1 = 1.0 

rat: replaced -1.0 by -1/1 = -1.0 
Maxima encountered a Lisp error: 

 The value 16090668801 is not of type FIXNUM. 
如果upandin中没有float(),则Maxima只保留upandin中的积分 原始形式

有人能帮忙吗?我想把Mathematica转换成Maxima会很有趣 很简单,但现在我不太确定

Mathematica版本运行良好:

pdflp[x_, p0_, v_, p1_, p2_, t1_, t2_] :=  
 PDF[NormalDistribution[Log[p0],Sqrt[t1]*v]][x] 

cdfmaxlp[x_, p0_, v_, p1_, p2_, t1_, t2_] := 1-Erf[x/(v*Sqrt[t2-t1]/Sqrt[2])]; 

(* NIntegrate below "equivalent" to Maximas float(); no closed form *) 

upandin[p0_, v_, p1_, p2_, t1_, t2_] :=  
 NIntegrate[pdflp[x, p0, v, p1, p2, t1, t2]* 
           cdfmaxlp[Log[p1]-x, p0, v, p1, p2, t1, t2], 
{x, -Infinity, Log[p1]}] 

upandin[1, .15, 1.01, 1.02, 1/365.2425, 2/365.2425] 

0.0998337 
编辑:有没有类似Mathematica的开源程序 这个函数的数值近似?我真的很想公开发行 开源平台的源代码

(我可能没必要回答这个问题,但是…)

只是一个猜测,但似乎integrate想要再次精确输入,并且可能正在进行一些涉及有理算术的困难bignum计算。它使你的近似值e(欧拉数)合理化,这意味着它的行为可能不同于积分(0)和精确输入

我可能想检查一下

用于专用数字代码,例如来自Quadpack

(我还在想为什么我要回答这个问题。在堆栈溢出方面一定有Maxima的专业知识。)

丹尼尔·利奇布劳
Wolfram Research

我知道Maxima非常努力地避免浮点数,我认为这就是它在这里试图做的,但我不足以解释如何防止浮点数。几乎任何数字都可以处理这个问题,尽管你可能必须打破间隔或手动转换被积函数。请注意,你说它相当简单很简单,但它非常陡峭:对于这些参数,被积函数在0.1处为~6*10^(-34),在-0.1处为~3*10^(-206)。这足够大的范围来提供许多简单的积分算法

无论如何,在Sage中,您可以在幕后使用scipy和gsl提供的工具轻松实现这一点:

import scipy.stats

def pdflp(x,p0,v,t1):
    return scipy.stats.norm(log(p0), sqrt(t1)*v).pdf(x)

def cdfmaxlp(x,v,t1,t2):
    return (1-erf(x/(v*sqrt(t2-t1)/sqrt(2.))))

def upandin(p0, v, p1, p2, t1, t2):
    integrand = lambda x: (pdflp(x,p0,v,t1) * cdfmaxlp(log(p1)-x,v,t1,t2))
    return numerical_integral(integrand, -Infinity, log(p1))

sage: upandin(1, .15, 1.01, 1.02, 1/365.2425, 2/365.2425)
(0.099833725578983457, 7.5174412058308382e-07)

如果需要任意精度,也可以使用mpmath的quad。[我猜这里的“正确”值是多少,但因为我们没有那么多精度,这有点傻。]

Maxima的“integrate”函数进行符号而不是数字的积分。当它从积分返回名词形式时,这意味着它无法执行(符号)运算将表达式的参数从精确更改为浮点(使用“float”)不会改变这一点

我认为您正在寻找的是一个数值积分例程——Maxima提供了各种各样的方法,从最基本的romberg到各种Quadpack方法(请尝试?quad以获取文档)


PS至于“这个蹩脚的‘开源’东西”--是什么导致的?你可能想看看维基百科文章中Macsyma/Maxima的历史,了解一些观点。

使用quad_qagi在无限区间上数值逼近一个积分。?quad_显示了有关Quadpack函数的信息

load (distrib);
pdflp (x, p0, v, p1, p2, t1, t2) := pdf_normal (x, log(p0), sqrt(t1)*v); 
cdfmaxlp (x, p0, v, p1, p2, t1, t2) := 1 - erf(x/(v * sqrt(t2 - t1)/sqrt(2))); 

upandin (p0, v, p1, p2, t1, t2) := block ([integrand],
   integrand : pdflp (x, p0, v, p1, p2, t1, t2) * cdfmaxlp (log(p1) - x, p0, v, p1, p2, t1, t2),
   quad_qagi (integrand, x, minf, log(p1))); 

upandin (1, .15, 1.01, 1.02, 1/365.2425, 2/365.2425);
 => [.09983372557898755, 2.839204848435967E-10, 225, 0]

抱歉,回复太晚了。请留下这个,以防有人通过搜索找到它。

在我的机器上,当我评估它说“太大,无法表示为双浮点:”,然后给出一个9774位整数。我实际上不熟悉Maxima,但也许你可以在早期阶段将所有内容转换为浮点?奇怪的是“老鼠:”暗示浮动的信息被转换回理性,这可能会让事情变得更糟。而且Maxima没有任意精度的数字?!也许你可以把问题发到上,因为很多微积分仍然使用Maxima。你甚至还签了公司的名字?嘘!正确答案应该是“看,这就是为什么你需要买Mathematica,而不是胡闹这些蹩脚的‘开源’东西"@Timo我与Maxima没有任何争执,无论是项目还是实施者。此外,我认为领导这项工作的Robert Dodier有时会问或回答MathGroup上发布的问题。他总是友好且尊重,所以我有动机不打扰他。我只希望他回答你的问题。所有这些都说明,你是对的,我是我可能愚蠢地在公司的名字上签名。应该加上我不是发言人…@巴里道歉,我指的是你,而不是蒂莫(当时还在考虑早些时候的回答,不同的问题)。你回答这个问题的努力应该得到更多尊重。继续前进!我相当肯定“糟糕的‘开源’东西”这只不过是对公司代表的一种嘲弄,与此相反,这是对丹尼尔方法的赞扬。
load (distrib);
pdflp (x, p0, v, p1, p2, t1, t2) := pdf_normal (x, log(p0), sqrt(t1)*v); 
cdfmaxlp (x, p0, v, p1, p2, t1, t2) := 1 - erf(x/(v * sqrt(t2 - t1)/sqrt(2))); 

upandin (p0, v, p1, p2, t1, t2) := block ([integrand],
   integrand : pdflp (x, p0, v, p1, p2, t1, t2) * cdfmaxlp (log(p1) - x, p0, v, p1, p2, t1, t2),
   quad_qagi (integrand, x, minf, log(p1))); 

upandin (1, .15, 1.01, 1.02, 1/365.2425, 2/365.2425);
 => [.09983372557898755, 2.839204848435967E-10, 225, 0]