为了测试连续函数是否具有根,给定区间[x0,x1]中的一个简单根相对容易:根据Intermediate value theorem当x0处的函数值的符号时与x1处的符号相反,有(至少)一个根。
例如,给定二次函数:
g(x): a*x**2 + b*x + c = 0
测试看起来像:
if sign of g(x0) is opposite of sign of g(x1)
then return true
else return false
对于多变量情况,有Poincaré–Miranda theorem但是我在阅读链接文章时正确实施测试有点困难。
给出两个二次双变量函数:
g1(x, y): a1*x**2 + b1*y**2 + c1*x*y + d1*x + e1*y + f1 = 0
g2(x, y): a2*x**2 + b2*y**2 + c2*x*y + d2*x + e2*y + f2 = 0
和一个矩形区域[x0,x1] x [y0,y1],如何检查区域中是否至少有一个根?
我的意思是,我认为测试应该看起来有点像(这不起作用):
if (sign of g1(x0, y0) is opposite of sign of g1(x1, y0) and
sign of g1(x0, y1) is opposite of sign of g1(x0, y1) and
sign of g2(x0, y0) is opposite of sign of g2(x1, y0) and
sign of g2(x0, y1) is opposite of sign of g2(x0, y1))
then return true
else return false
请问,是否有人知道要检查的功能对,间隔终点和逻辑运算符以及按什么顺序排列?
答案 0 :(得分:1)
首先,您的原始"中间值"基于代码并没有完全按照广告宣传的方式执行:
测试连续函数是否在给定区间[x0,x1]中具有根是相对容易的:根据中间值定理,当x0处的函数值的符号与x1处的符号相反时,存在(at)至少)一个根。
测试看起来像:
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
或者其他......
关于庞加莱米兰达定理,在更高的维度上比较几点的符号并没有给你足够的信息来应用这个定理。
考虑
n
变量的n
个连续函数。假设对于每个变量x_i
,函数f_i
在x_i = 0
时始终为负,在x_i = 1
时始终为正。然后在n
- 维单位立方体中有一个点,其中所有函数同时等于0
。
如果连续功能是“不断消极的”,则没有黑盒测试。在一些地区。
你需要假设更多的东西,比如,你认为它实际上是一个低次多项式,你可以在足够的点上对它进行采样以发现它的系数等。
如果我们假设你说我们有两个二元正方形,我们实际上有(或推论)系数......这是可能的。
我会做的只是,根据需要在每个函数中替换x_i
的值,因此它减少为单变量二次,然后使用像我们这样的二次公式求解其根(如果有的话)在小学里学到的。然后检查它们是否出现在感兴趣的区域。然后测试根之间的点以确定符号。然后你就会知道是否可以应用这个定理。
您可以以封闭形式解决精确条件,但我不确定这是否真的有助于您编写更好(更简单/更有效)的实现。
这是一些伪代码:
def quadratic_positive_in_region(p, x_0, x_1)
ASSERT(p is univariate)
ASSERT(x_0 <= x_1)
// If one of the roots lies in the region then
// we are zero there, and thus not positive
def roots = quadratic_formula(p)
for r in roots:
if x_0 <= r and r <= x_1 then return false
// If there are no roots in the region then
// we are either always positive or always negative,
// so test a single point to determine.
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)
我在这里使用了一些符号,其中-
运算符可以应用于多项式,|
符号表示在多项式中替换变量的值。
答案 1 :(得分:1)
你需要检查你的双变量函数
proc sort data=sashelp.cars out=cars;
by make;
run;
ods select PearsonCorr;
proc corr data=cars;
by make;
var mpg_highway invoice;
ods output PearsonCorr=corr_table;
run;
data corr_table;
set corr_table;
by make;
if first.make;
if PInvoice< 0.05 then flag_significant=1;
else flag_significant=0;
run;
proc print data=corr_table;
run;
满足
g1(x, y): a1*x**2 + b1*y**2 + c1*x*y + d1*x + e1*y + f1 = 0
g2(x, y): a2*x**2 + b2*y**2 + c2*x*y + d2*x + e2*y + f2 = 0
和
I). g1(x0,y) < 0, for all y in [y0,y1]
II). g2(x,y0) < 0, for all x in [x0,x1]
您的函数是二次函数,因此可以在不对4个案例的所有4个边界采样值的情况下完成此操作。例如,对于g1(x0,y)的第一个条件,只需插入x0代表x,在y中获得二次方程式:
III). g1(x1,y) > 0, for all y in [y0,y1]
IV). g2(x,y1) > 0, for all x in [x0,x1]
我们需要检查[y0,y1]中的G1是否为y。由于G1是二次方,因此它的最大值出现在{G1&#39; = 0,G1&#39;&#39; &LT; 0}或在端点。所以:
G1(y) = b1*y**2 + c1*x0*y + e1*y + (f1 + d1*x0 + a1*x0**2)
如果您的函数通过了这些测试而没有破坏,那么您已满足上述4个条件(I)中的第一个条件。
可以以类似的方式测试条件(II-IV)。如果所有条件都成立,则Miranda测试成立并且您具有两个函数的重合根。如果没有,那么你就在&#34;也许&#34; case - 函数可能仍然有一个共同的根,但你必须使用不同的方法来证明存在。