我正在寻找算法来绘制可能具有或不具有奇异性的函数的标准2d图形。目的是编写一个“ Mini-CAS”,所以我对功能的类型没有先验知识,用户想画图。
这个问题很老,所以我想在文献中一定有一些标准算法。有一次,我没有太多通过谷歌找到参考文献的成功。
我确实找到了一种有趣的算法,即 “ YACAS-算法集”中的一种名为“自适应函数绘图” 的算法。
简而言之:
- 有标准算法吗?
- 是否有针对已知难以绘制功能的测试套件?
- 有哪些有趣的论文可供阅读?
我正在寻找算法来绘制可能具有或不具有奇异性的函数的标准2d图形。目的是编写一个“ Mini-CAS”,所以我对功能的类型没有先验知识,用户想画图。
这个问题很老,所以我想在文献中一定有一些标准算法。有一次,我没有太多通过谷歌找到参考文献的成功。
我确实找到了一种有趣的算法,即 “ YACAS-算法集”中的一种名为“自适应函数绘图” 的算法。
简而言之:
Answers:
我已经在GitHub上实现了Mathematica的自适应采样例程(这是一个C文件,转到头文件的源树)。很久以前,我在一本有关Mathematica的大书中找到了该例程的描述,并且一段时间以来,我一直在使用此实现的变体。它基本上在感兴趣的区域上进行了粗糙的线性采样,然后返回以细化高曲率区域。可能会遗漏一些非常鲜明的功能,但实际上,我发现这种情况极为罕见。该文件还包含并行版本。
Exclusions -> None
来隐藏函数的结构,也可以将其关闭。当我问这些更改时,这并不是我要指的。我相信算法会有所变化,因为v5和v6是在不同点采样的。现在,我无法再次在v5上进行测试。Plot
f[x_?NumericQ] := ...
了解其他CAS如何做到这一点可能会对您有所帮助。
从绘图域上的点按规则间隔的网格开始。(在Mathematica中,有一个参数控制取多少PlotPoints
。)
如果尚未达到迭代极限(MaxRecursion
在Mathematica中设置),请从步骤2开始重复。
其中的一些内容在Stan Wagon撰写的《 Mathematica in Action》一书中进行了讨论,您可以在Google图书上找到。
为了更好地控制计算函数的成本,我实施了该算法。这是步骤2的Mathematica代码:
nd[{points_, values_}] :=
Transpose@{(Drop[points, 1] + Drop[points, -1])/2,
Differences[values]/Differences[points]}
subdivide1d[result_, resolution_, maxAngle_: 10] :=
Module[
{deriv, angle, dangle, pos, nf},
deriv = nd[result\[Transpose]];
angle = ArcTan[#2] & @@@ deriv;
dangle = Differences[angle];
pos = Flatten@Position[dangle, d_ /; Abs[d] > maxAngle/180 Pi];
pos = Union[pos, pos + 1];
nf = Nearest[result[[All, 1]]];
Select[deriv[[pos, 1]], Abs[# - First@nf[#]] > resolution &]
]
函数图上的MathWorld网页包含对几篇论文的引用,这些论文似乎与自适应函数图有关。引用页面:
绘制图形的良好例程使用自适应算法,该算法在函数变化最快的区域中绘制更多点(Wagon 1991,Math Works 1992,Heck 1993,Wickham-Jones 1994)。Tupper(1996)开发了一种算法[...]
另一方面,我在Google上偶然发现了一篇论文
www.cs.uic.edu/~wilkinson/Publications/plotfunc.pdf
解释了如何正确选择域和其他内容。我希望它们对您有用。