Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 并联电阻的计算_Python_Python 3.x_Floating Point_Intervals - Fatal编程技术网

Python 并联电阻的计算

Python 并联电阻的计算,python,python-3.x,floating-point,intervals,Python,Python 3.x,Floating Point,Intervals,以下是并联电阻器的两个代数等效公式: par1(r1, r2) = (r1 * r2) / (r1 + r2), or par2(r1, r2) = 1 / (1/r1 + 1/r2) 下面是两个python函数,每个函数都计算并行公式: def par1(r1, r2): return div_interval(mul_interval(r1, r2), add_interval(r1, r2)) def par2(r1, r2): one = interval(1, 1

以下是并联电阻器的两个代数等效公式:

par1(r1, r2) = (r1 * r2) / (r1 + r2), or

par2(r1, r2) = 1 / (1/r1 + 1/r2)
下面是两个python函数,每个函数都计算并行公式:

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))
我们注意到
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\u间隔
都会丢失精度


我的理解正确吗?

恐怕你对这两个函数给出不同结果的理由是不正确的。浮点舍入可能是一个真正的问题,但对于大多数计算(包括这里的计算),误差非常非常小。只有在测试精确相等性或组合了大量浮点计算时,错误才会变得显著

这里真正的问题是,在
par1
中,您的
r1
r2
间隔都出现在除法运算的两侧。当除法函数计算第二个参数的倒数时,它会反转区间边界的顺序,因此输入的上界会影响输出的下界

当除数和被除数的间隔相同时,你会得到一个比你应该得到的更宽的间隔。这是因为代码不知道区间的一个副本的一个极端的结果也意味着另一个副本的相同极端

考虑计算区间
r=(a,b)
r/r
。您的
div\u interval
函数将计算结果为
(a/b,b/a)
,当使用基本代数时,我们知道结果应为
(1,1)
(因为任何数字除以自身就是1)。然而,除法代码必须假设它的每个参数彼此独立。如果除数在其区间的最大界限(
b
),则它可能在其最小界限(
a
)处除数。它不知道这两件事不能同时发生


第二个公式通过使每个输入间隔仅出现在一个位置来避免此问题。实际上,您可以允许一点复制。只要没有包含负边界的区间的减法、除法或乘法,就应该没有问题。

为了证明这不是舍入误差,这里有一些代码使用这两种方法来计算并联电阻。它不是为了简洁,也不是为了特别有效,只是为了表明这两种计算方法产生完全相同的结果

def par1(r1,r2):
    r1lower = float(r1[0])
    r1upper = float(r1[1])
    r2lower = float(r2[0])
    r2upper = float(r2[1])
    low = 1/((1/r1lower)+(1/r2lower))
    high = 1/((1/r1upper)+(1/r2upper))
    return(low, high)

def par2(r1,r2):
    r1lower = float(r1[0])
    r1upper = float(r1[1])
    r2lower = float(r2[0])
    r2upper = float(r2[1])
    low = (r1lower * r2lower) / (r1lower + r2lower)
    high = (r1upper * r2upper) / (r1upper + r2upper)
    return(low, high)

if __name__ == '__main__':
    print par1((1,2),(3,4))
    print par2((1,2),(3,4))
输出:

(0.75, 1.3333333333333333)
(0.75, 1.3333333333333333)
[Finished in 0.1s]
代码中的某个地方出现了错误…

多个并联阻抗-万无一失 若干阻抗的总阻抗等于这些阻抗的总阻抗除以并联阻抗的数目

from scipy import stats

def par(array):
    """Calculate the impedance of an array of parallel impedances"""
    return stats.hmean(array)/len(array)

In [1]: par([2.7, 3.3, 10])
Out[1]: 1.29299

上限应该是
x[-1]
我想是吧?@anmol\u uppal请测试并找到你问题的答案。就我个人而言,我一直在苦苦思考用“间隔”来描述电阻器的概念。你到底为什么需要两个数字来描述一个具有量的东西,电阻,可以用一个数字来表示?@SiHa OK。例如,在现实世界中,设备的电阻被称为+/-0.15公差的
3.5欧姆。所以,我们需要
(3.35,3.65)
之间的所有值,包括端点。@overexchange啊。这更有道理。不过,对于这样一个简单的操作,这段代码似乎仍然非常复杂。我想说,导致结果不同的原因可能是所有代码中的某个地方存在错误,而不是浮点表示错误。如果我将其设置为
倒数y=interval(1/下限(y),1/上限(y))
则没有任何区别。因为我们在
mul_interval
中选择了
min
max
,这是真的,乘法代码取边界乘积的最小值和最大值,但如果边界都为正,则最小值将是输入下界的乘积,最大值是输入上界的乘积。在计算倒数时不反转值会给你一个伪区间(下限会大于上限)。我们如何更改
par1
par2
以获得类似的结果?@overexchange:
par2
已经是
par1
的固定版本了。你不需要让他们给出相同的答案,只要理解为什么
par1
会出错就行了。阅读问题初稿的作业文本,伊娃基本上是对的。多个引用是par1中的问题,但不是所有有多个引用的公式都会引起问题。通过“basic”,我指的是非区间算术。这是合适的,因为间隔只是指定单个实数的不确定性的一种方式
r/r
将是
1
,不管我们测量它时有多大误差。你应该学习的问题是区间算法不能很好地处理这种情况。避免在公式中的多个位置使用相同的间隔是解决此限制的一种方法。par1/par2来自您的代码为
par2
获得正确的结果(使用问题中的
par1
公式),因为它假定(正确,事实证明)输出的下界来自两个输入区间的下界的组合(上界也是如此)。不过,对于间隔操作来说,情况并非总是如此。
a/b的上限<
from scipy import stats

def par(array):
    """Calculate the impedance of an array of parallel impedances"""
    return stats.hmean(array)/len(array)

In [1]: par([2.7, 3.3, 10])
Out[1]: 1.29299