【发布时间】:2015-07-09 22:24:05
【问题描述】:
下面两个并联电阻的代数等效公式:
par1(r1, r2) = (r1 * r2) / (r1 + r2), or
par2(r1, r2) = 1 / (1/r1 + 1/r2)
以下两个python函数,每个函数计算parallel_resistors公式:
def par1(r1, r2):
return div_interval(mul_interval(r1, r2), add_interval(r1, r2))
def par2(r1, r2):
one = interval(1, 1)
rep_r1 = div_interval(one, r1)
rep_r2 = div_interval(one, r2)
return div_interval(one, add_interval(rep_r1, rep_r2))
以下是上述函数par1 和par2 使用的区间算术抽象。
def interval(a, b):
"""Construct an interval from a to b. """
return (a, b)
def lower_bound(x):
"""Return the lower bound of interval x. """
return x[0]
def upper_bound(x):
"""Return the upper bound of interval x. """
return x[1]
def div_interval(x, y):
"""Return the interval that contains the quotient of any value in x divided
by any value in y.
Division is implemented as the multiplication of x by the reciprocal of y.
>>> str_interval(div_interval(interval(-1, 2), interval(4, 8)))
'-0.25 to 0.5'
"""
assert (lower_bound(y) > 0 or upper_bound(y) < 0), "what it means to divide by an interval that spans zero"
reciprocal_y = interval(1/upper_bound(y), 1/lower_bound(y))
return mul_interval(x, reciprocal_y)
def str_interval(x):
"""Return a string representation of interval x.
>>> str_interval(interval(-1, 2))
'-1 to 2'
"""
return '{0} to {1}'.format(lower_bound(x), upper_bound(x))
def add_interval(x, y):
"""Return an interval that contains the sum of any value in interval x and
any value in interval y.
>>> str_interval(add_interval(interval(-1, 2), interval(4, 8)))
'3 to 10'
"""
lower = lower_bound(x) + lower_bound(y)
upper = upper_bound(x) + upper_bound(y)
return interval(lower, upper)
def mul_interval(x, y):
"""Return the interval that contains the product of any value in x and any
value in y.
>>> str_interval(mul_interval(interval(-1, 2), interval(4, 8)))
'-8 to 16'
"""
p1 = lower_bound(x) * lower_bound(y)
p2 = lower_bound(x) * upper_bound(y)
p3 = upper_bound(x) * lower_bound(y)
p4 = upper_bound(x) * upper_bound(y)
return interval(min(p1, p2, p3, p4), max(p1, p2, p3, p4))
测试结果:
>>> r1 = interval(1, 2)
>>> r2 = interval(3, 4)
>>> par1(r1, r2)
(0.5, 2.0)
>>> par2(r1, r2)
(0.75, 1.3333333333333333)
我们注意到 par1 和 par2 的不同结果,它们通过不同但代数等效的表达式进行计算。
对于上面给定的输入 r1 和 r2,下面是计算。
par1 --> return mul_interval((3, 8), (1/6, 1/4)) = (1/2, 2)
=======
rep_r1 = div_interval((1, 1), (1, 2)) = (1/2, 1)
rep_r2 = div_interval((1, 1), (3, 4)) = (1/4, 1/3)
par2 --> return div_interval((1, 1), (3/4, 4/3)) = (3/4, 4/3)
不同间隔的原因是由于 IEEE 浮点格式,其中每个 div_interval 都会丢失精度。
我的理解正确吗?
【问题讨论】:
-
上限应该是
x[-1]我猜? -
@anmol_uppal 请测试并找到您问题的答案。
-
就个人而言,我正在为使用“间隔”来描述电阻器的概念而苦苦挣扎。为什么你需要两个数字来描述具有数量的东西,阻力,可以表示为一个数字?
-
@SiHa 好的。在现实世界中提到了设备的电阻,例如
3.5 ohms with +/- 0.15 tolerance。所以,我们需要(3.35, 3.65)之间的所有值,包括端点。 -
@overexchange 啊。这更有意义。不过,对于如此简单的操作,这段代码似乎仍然非常复杂。我会说,导致您出现不同结果的原因可能是因为所有代码中的某个地方都有错误,而不是浮点表示错误。
标签: python python-3.x floating-point intervals