提交 ae415c3b authored 作者: Frederic Bastien's avatar Frederic Bastien

make some stability opt being executed in the stabilization phase. And fix associated test.

上级 fa82588d
......@@ -2608,6 +2608,26 @@ register_canonicalize(local_one_minus_erfc, name='local_one_minus_erfc')
register_stabilize(local_one_minus_erfc, name='local_one_minus_erfc')
register_specialize(local_one_minus_erfc, name='local_one_minus_erfc')
local_one_minus_erfc2 = gof.PatternSub((T.add,
1,
(T.neg, (T.erfc, 'x'))),
(T.erf, 'x'),
allow_multiple_clients = True,
name='local_one_minus_erfc2')
register_canonicalize(local_one_minus_erfc2)
register_stabilize(local_one_minus_erfc2)
register_specialize(local_one_minus_erfc2)
local_one_minus_erfc3 = gof.PatternSub((T.add,
1,
(T.mul, -1, (T.erfc, 'x'))),
(T.erf, 'x'),
allow_multiple_clients = True,
name='local_one_minus_erfc3')
register_canonicalize(local_one_minus_erfc3)
register_stabilize(local_one_minus_erfc3)
register_specialize(local_one_minus_erfc3)
#1+(-erfc(x)) => erf(x)
#This is a different graph then the previous as the canonicalize don't work completly
local_one_add_neg_erfc = gof.PatternSub((T.add,
......@@ -2629,6 +2649,18 @@ register_canonicalize(local_erf_neg_minus_one, name='local_erf_neg_minus_one')
register_stabilize(local_erf_neg_minus_one, name='local_erf_neg_minus_one')
register_specialize(local_erf_neg_minus_one, name='local_erf_neg_minus_one')
#(-1)+erfc(-1*x)=>erf(x)
local_erf_neg_minus_one2 = gof.PatternSub((T.add,
dict(pattern='y', constraint = _is_minus1),
(T.erfc, (T.mul,-1,'x'))),
(T.erf, 'x'),
allow_multiple_clients = True,
name = 'local_erf_neg_minus_one2')
register_canonicalize(local_erf_neg_minus_one2)
register_stabilize(local_erf_neg_minus_one2)
register_specialize(local_erf_neg_minus_one2)
#Stability optimization
#log(erfc(x)) => when x>threashold, -x**2-log(x)-.5*log(pi)+log(1-1/(2*x**2)+3/(4*x**4)-15/(8*x**6))
#for float64: threshold=26.641747557 was choosed with: [(i,numpy.log(scipy.special.erfc(numpy.asarray([i],dtype='float64')))) for i in numpy.arange(26.641747557,26.6417475571,.00000000001)]
......
......@@ -1787,23 +1787,21 @@ class T_local_erfc(unittest.TestCase):
f = theano.function([x],T.log(T.erfc(x)), mode=mode)
#theano.printing.debugprint(f)
assert len(f.maker.env.nodes)==22, len(f.maker.env.nodes)
assert len(f.maker.env.nodes)==23, len(f.maker.env.nodes)
assert f.maker.env.outputs[0].dtype==theano.config.floatX
assert not any([hasattr(n.op,'scalar_op') and n.op.scalar_op==scal.pow for n in f.maker.env.nodes])
assert all(numpy.isfinite(f(val)))
f = theano.function([x],T.log(T.erfc(-x)), mode=mode)
#theano.printing.debugprint(f)
assert len(f.maker.env.nodes)==23, len(f.maker.env.nodes)
assert len(f.maker.env.nodes)==24, len(f.maker.env.nodes)
assert f.maker.env.outputs[0].dtype==theano.config.floatX
assert not any([hasattr(n.op,'scalar_op') and n.op.scalar_op==scal.pow for n in f.maker.env.nodes])
assert all(numpy.isfinite(f(-val)))
f = theano.function([x],T.log(T.erfc(x)), mode=mode_fusion)
assert len(f.maker.env.nodes)==1, len(f.maker.env.nodes)
assert f.maker.env.outputs[0].dtype==theano.config.floatX
assert len(f.maker.env.toposort()[0].env.toposort()[0].op.scalar_op.env.nodes)==4,len(f.maker.env.toposort()[0].env.toposort()[0].op.scalar_op.env.nodes)
assert not any([hasattr(n.op,'scalar_op') and n.op.scalar_op==scal.pow for n in f.maker.env.nodes])
#TODO: fix this problem
if theano.config.floatX=="float32" and theano.config.mode in ["DebugMode", "DEBUG_MODE"]:
raise KnownFailureTest("the python code upcast somewhere internally some value of float32 to python float for part of its computation. That make that the c and python code don't generate the same value. You can ignore this error.")
assert all(numpy.isfinite(f(val)))
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论