我正在尝试Maxima-fy我的Mathematica盒子选项公式 (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 w /某些值崩溃:
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只留下积分 原始形式。
有人可以帮忙吗?我认为将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的程序
数值近似这个函数?我真的很想释放
源代码到开源平台。
答案 0 :(得分:6)
(我可能没有业务回答这个,但是......)
只是一个猜测,但似乎整合想要再次使输入准确,并且可能正在做一些涉及有理算术的困难的bignum计算。它使你的近似e(欧拉数)合理化,这意味着它的表现可能与积分不同(0表示精确输入。
可能想检查
http://eagle.cs.kent.edu/MAXIMA/maxima_21.html
或
http://www.delorie.com/gnu/docs/maxima/maxima_62.html
用于专用数字代码,例如Quadpack。
(仍然想知道为什么我甚至试图回答这个问题。必须在Stack Overflow上的某处有Maxima的专业知识。)
Daniel Lichtblau Wolfram Research
答案 1 :(得分:4)
我知道Maxima非常努力避免花车,我认为这就是它试图在这里做的事情,但我还不足以解释如何防止它的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的四边形。 [我在这里猜测了“正确”的值,但由于我们没有那么精确的开头,所以它有点傻。]
答案 2 :(得分:4)
使用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]
很抱歉迟到的回复。将此留在这里以防有人通过搜索找到它。
答案 3 :(得分:3)
Maxima的“集成”功能可以实现符号化,而不是数字化。当它从积分返回名词形式时,这意味着它不能执行(符号)积分。将表达式的参数从exact更改为float(使用'float')不会改变它。
我认为您正在寻找的是数字集成例程--Maxima提供了各种各样的功能,从最基本的romberg到各种Quadpack方法(尝试四元组文档) )。
-s
PS至于“这个蹩脚的'开源'的东西” - 是什么带来的?您可能希望从维基百科文章中查看Macsyma / Maxima的历史记录。