<p>如果你想知道事物是如何计算的,<code>pdb</code>确实是一种解决方案。在</p>
<p>但是,使用像<code>pdb</code>这样的调试器,很难从较高的层次了解正在发生的事情。这就是为什么阅读代码也是有用的。例如,如果您想知道<code>a+b</code>做什么,可以检查<code>type(a).__add__</code>是否存在,因为如果存在,它将处理加法。不确定性一揽子计划就是这样。在</p>
<p>也就是说,<code>__add__</code>确实是通过一个通用的机制实现的,而不是专门为其编码的,所以我可以告诉你它实现背后的想法,因为这正是你最终要寻找的。在</p>
<p>在您的示例中,<code>a</code>和{<cd7>}是<code>Variable</code>对象:</p>
<pre><code>>>> from uncertainties import ufloat
>>> a = ufloat(1, 3)
>>> b = ufloat(2, 4)
>>> type(a)
<class 'uncertainties.Variable'>
</code></pre>
<p>那么<code>c = a + b</code>实际上是<code>a</code>和{<cd7>}的一个线性函数,由其关于<code>a</code>和{<cd7>}的导数表示:</p>
^{pr2}$
<p>如果你知道一个函数相对于它的变量的导数,你很容易得到一个<a href="http://en.wikipedia.org/wiki/Propagation_of_uncertainty" rel="nofollow">approximation of its standard deviation from the standard deviations of its variables</a>。在</p>
<p>因此,<a href="http://pythonhosted.org/uncertainties/" rel="nofollow">uncertainties package</a>实现背后的主要思想是,值是:</p>
<ul>
<li>随机变量,如x=3.14±0.0.1和y=0±0.01(<code>Variable</code>对象),用它们的标准差来描述</li>
<li>或者函数的线性近似(<code>AffineScalarFunc</code>对象:“仿射”是因为它们是线性的,“标量”是因为它们的值是实的,“func”是因为它们是函数)。在</li>
</ul>
<p>举一个更复杂的例子,z=2*x+sin(y)在(x,y)=(3.14,0)中近似为2*x+y。在实现中,由于近似是线性的,因此只存储关于变量的导数:</p>
<pre><code>>>> x = ufloat(3.14, 0.01)
>>> y = ufloat(0, 0.01)
>>> from uncertainties.umath import sin
>>> z = 2*x + sin(y)
>>> type(z)
<class 'uncertainties.AffineScalarFunc'>
>>> z.derivatives
{3.14+/-0.01: 2.0, 0.0+/-0.01: 1.0}
</code></pre>
<p>因此,不确定性软件包的主要工作是计算任何涉及变量的函数的导数。这是通过<a href="http://pythonhosted.org/uncertainties/tech_guide.html#differentiation-method" rel="nofollow">automatic differentiation</a>的有效方法实现的。具体地说,当您执行类似<code>a+b</code>的操作时,Python会自动调用<code>Variable.__add__()</code>方法,该方法通过计算<code>a+b</code>相对于其变量的导数来创建一个新的线性函数(导数都是一个,因为{<cd6>}相对于{<cd6>}的导数是一个,而{<cd7>}的导数也是一个)。更一般地说,添加<em>函数</em>,而不是纯变量:<code>f(a,b) + g(a,b)</code>相对于{<cd6>}和{<cd7>}的导数是用链式规则计算的。这就是自动微分的工作原理,这也是不确定性包中实现的。这里的关键函数是<code>uncertainties.wrap()</code>。它是整个包中最大、最复杂的函数,但是代码大部分是注释的,并且<a href="http://pythonhosted.org/uncertainties/tech_guide.html#differentiation-method" rel="nofollow">details on the method</a>是可用的。在</p>
<p>导数然后给出最终函数的标准差,作为变量标准差的函数(代码<code>AffineScalarFunc.std_dev()</code>非常简单:更困难的任务是自动计算导数)。在</p>