首先,您原始的基于“中间值”的代码并没有完全实现它所宣传的功能:
To test whether a continuous function has a root in a given interval [x0, x1] is relatively easy: according to Intermediate value theorem when the sign of function value at x0 is opposite to the sign at x1, there is (at least) one root.
The test looks like:
if sign of g(x0) is opposite of sign of g(x1)
then return true
else return false
这个“测试”存在单向误差,正如David Eisenstat所指出的那样。如果符号确实相反,则
return true
是可以的,但如果符号不相反,则
return false
可能应该是
return maybe
或其他类似的东西...
其次,关于Poincare Miranda定理,在高维度中仅比较几个点的符号不足以提供足够的信息应用该定理。
考虑n个变量的n个连续函数。假设对于每个变量xi,当xi=0时函数fi恒为负,当xi=1时函数fi恒为正。那么在n维单位立方体中存在一个点,使得所有函数同时等于0。
如果一个连续函数在某个区域内“恒为负”,则没有黑盒测试可用。
你需要假设更多的内容,例如,你假设它实际上是一个低次多项式,并在足够多的点上对其进行采样以发现其系数等。
如果我们像您所说的假设我们有两个双变量二次方程,并且我们实际上有(或推断出)系数...这是可能的。
我会简单地将
x_i
的值替换到每个函数中,使其化简为单变量二次方程,然后使用我们在小学学习的二次公式解决其根(如果有)。然后检查它们是否出现在感兴趣的区域内。然后测试根之间的点以确定符号。然后你就会知道定理是否适用。
有可能你可以求解一个封闭形式的精确条件,但我不确定这是否会真正帮助你编写更好(更简单/更高效)的实现。
以下是伪代码:
def quadratic_positive_in_region(p, x_0, x_1)
ASSERT(p is univariate)
ASSERT(x_0 <= x_1)
def roots = quadratic_formula(p)
for r in roots:
if x_0 <= r and r <= x_1 then return false
if p(x_0 + x_1 / 2) > 0 then return true
return false
def poincare_miranda(g1, g2, x_0, x_1, y_0, y_1)
return quadratic_positive_in_region(-g1 | y = y_0, x_0, x_1) and
quadratic_positive_in_region( g1 | y = y_1, x_0, x_1) and
quadratic_positive_in_region(-g2 | x = x_0, y_0, y_1) and
quadratic_positive_in_region( g2 | x = x_1, y_0, y_1)
def generalized_test(g1, g2, x_0, x_1, y_0, y_1)
return poincare_miranda( g1, g2, x_0, x_1, y_0, y_1) or
poincare_miranda(-g1, g2, x_0, x_1, y_0, y_1) or
poincare_miranda(-g1, -g2, x_0, x_1, y_0, y_1) or
poincare_miranda( g1, -g2, x_0, x_1, y_0, y_1)
我在这里使用一些符号,其中
-
运算符可应用于多项式,而
|
符号表示将值替换为多项式中的变量。