def test_sqrt(self): f, p = lambda x: x**2 - 2, lambda x: 2 * x self.assertEqual(imath.sqrt(2), interval[1.4142135623730949, 1.4142135623730951]) self.assertEqual(imath.sqrt(4), interval[2]) self.assertEqual(imath.sqrt(interval[-3, -1]), interval()) self.assertEqual(imath.sqrt(interval[-1, 4]), interval([0.0, 2])) self.assertEqual(imath.sqrt(interval([-3.14, 2], [4,9], [25, 64])), interval([0, 1.4142135623730951], [2, 3], [5, 8]))
def test_sqrt(self): assert imath.sqrt(2) == interval[1.4142135623730949, 1.4142135623730951] assert imath.sqrt(4) == interval[2] assert imath.sqrt(interval[-3, -1]) == interval() assert imath.sqrt(interval[-1, 4]) == interval([0.0, 2]) assert imath.sqrt(interval([-3.14, 2], [4, 9], [25, 64])) == interval( [0, 1.4142135623730951], [2, 3], [5, 8])
def test_sqrt(self): f, p = lambda x: x**2 - 2, lambda x: 2 * x self.assertEqual(imath.sqrt(2), interval[1.4142135623730949, 1.4142135623730951]) self.assertEqual(imath.sqrt(4), interval[2]) self.assertEqual(imath.sqrt(interval[-3, -1]), interval()) self.assertEqual(imath.sqrt(interval[-1, 4]), interval([0.0, 2])) self.assertEqual(imath.sqrt(interval([-3.14, 2], [4, 9], [25, 64])), interval([0, 1.4142135623730951], [2, 3], [5, 8]))
def fg3_assume23(mu, nu, a3, mn, v, g_pos=True): f3num = ((a3 + 2 * nu) * mu) & (-POS) g3num = ((a3 + 2 * mu) * nu) & (-POS) denom = (a3 * v + 2 * mn) & (-POS) f3 = imath.sqrt((f3num / denom) & UNIT_INT) & UNIT_INT g3 = imath.sqrt((g3num / denom) & GEQ_ONE) & GEQ_ONE if g_pos: return f3, g3 return f3, -g3
def fg2_assume2N4(mu, nu, a2, mn, v, g_pos=True): f2num = ((a2 - 2 * nu) * mu) & POS g2num = ((a2 - 2 * mu) * nu) & POS denom = (a2 * v - 2 * mn) & POS f2 = imath.sqrt((f2num / denom) & GEQ_ONE) & GEQ_ONE g2 = imath.sqrt((g2num / denom) & UNIT_INT) & UNIT_INT if g_pos: return f2, g2 return f2, -g2
def test_cospi(self): assert imath.cospi(fpu.infinity) == interval[-1, 1] assert imath.cospi(-fpu.infinity) == interval[-1, 1] assert imath.cospi(interval[0.5, 1.5]) == interval[-1, 0] assert imath.cospi(interval[-0.5, 0.5]) == interval[0, 1] assert imath.cospi(1/interval[3]) == interval[helpers.nudge(0.5,-2), helpers.nudge(0.5, 1)] assert imath.cospi(-1/interval[3]) == interval[helpers.nudge(0.5,-2), helpers.nudge(0.5, 1)] assert imath.cospi(2/interval[3]) == interval[helpers.nudge(-0.5,-2), helpers.nudge(-0.5,2)] assert imath.cospi(interval[6]**-1) == imath.sqrt(3)/2
def mu_nu_feasible(mu, nu, u): if ((u - SPR_MAX) & POS) == NULL_INT: return False if ((SPR_UPP - u) & POS) == NULL_INT: return False if ((imath.sqrt(mu * (interval(1) - mu)) + nu) & POS) == NULL_INT: return False return True
def __fwd_eval(self, n_id, box): n = self.dag[n_id] fwd = self.__fwd rec = self.__fwd_eval if n[0] == '+': rec(n[1], box) rec(n[2], box) fwd[n_id] = fwd[n[1]] + fwd[n[2]] elif n[0] == '-': rec(n[1], box) rec(n[2], box) fwd[n_id] = fwd[n[1]] - fwd[n[2]] elif n[0] == '*': rec(n[1], box) rec(n[2], box) fwd[n_id] = fwd[n[1]] * fwd[n[2]] elif n[0] == '/': rec(n[1], box) rec(n[2], box) fwd[n_id] = fwd[n[1]] / fwd[n[2]] elif n[0] == '^': rec(n[1], box) i = self.dag[n[2]][1] fwd[n_id] = fwd[n[1]]**i elif n[0] == 'exp': rec(n[1], box) fwd[n_id] = imath.exp(fwd[n[1]]) elif n[0] == 'sqrt': rec(n[1], box) fwd[n_id] = imath.sqrt(fwd[n[1]]) elif n[0] == 'sin': rec(n[1], box) fwd[n_id] = imath.sin(fwd[n[1]]) elif n[0] == 'cos': rec(n[1], box) fwd[n_id] = imath.cos(fwd[n[1]]) elif n[0] == 'C': fwd[n_id] = interval[n[1]] elif n[0] == 'V': fwd[n_id] = box[n[1]] else: print('unsupported node: ' + n) assert (False)
def test_cospi(self): assert imath.cospi(fpu.infinity) == interval[-1, 1] assert imath.cospi(-fpu.infinity) == interval[-1, 1] assert imath.cospi(interval[0.5, 1.5]) == interval[-1, 0] assert imath.cospi(interval[-0.5, 0.5]) == interval[0, 1] assert imath.cospi(1 / interval[3]) == interval[helpers.nudge(0.5, -2), helpers.nudge(0.5, 1)] assert imath.cospi(-1 / interval[3]) == interval[helpers.nudge(0.5, -2), helpers.nudge(0.5, 1)] assert imath.cospi(2 / interval[3]) == interval[helpers.nudge(-0.5, -2), helpers.nudge(-0.5, 2)] assert imath.cospi(interval[6]**-1) == imath.sqrt(3) / 2
def test_sqrt(self): assert imath.sqrt(2) == interval[1.4142135623730949, 1.4142135623730951] assert imath.sqrt(4) == interval[2] assert imath.sqrt(interval[-3, -1]) == interval() assert imath.sqrt(interval[-1, 4]) == interval([0.0, 2]) assert imath.sqrt(interval([-3.14, 2], [4, 9], [25, 64])) == interval([0, 1.4142135623730951], [2, 3], [5, 8])
from interval import interval, inf, imath, fpu SPR_MAX = imath.sqrt(interval[4] / 3) SPR_UPP = (interval(1) + imath.sqrt(interval(2))) / interval(2) NULL_INT = interval() UNIT_INT = interval[0, 1] GEQ_ONE = interval[1, inf] POS = interval[0, inf] # These are helper methods meant to be used when # handling cases that share formulas # Every method begins with the variable to be returned # and ends with a string indicating assumptions made # most often, the string is a list of indices w/ weight # assumed to be positive # when weights are assumed 0, the string corresponds to # an interval in increasing order; in the interval: # any number in {1, ..., 7} indicates a positive weight # N indicates the weight is assumed 0 # X (wildcard) indicates no assumption on the weight # Always, we assume that: # u = mu - nu, # v = mu + nu, and # mn = mu*nu # All other variables are self-evident # Formulas are written to both minimize FLOPs and accumulated # error when possible
def __eval(self, n_id, box): n = self.__dag[n_id] rec = self.__eval if n[0] == '+': v1 = rec(n[1], box) v2 = rec(n[2], box) return v1 + v2 elif n[0] == '-': v1 = rec(n[1], box) v2 = rec(n[2], box) return v1 - v2 elif n[0] == '*': v1 = rec(n[1], box) v2 = rec(n[2], box) return v1 * v2 elif n[0] == '/': v1 = rec(n[1], box) v2 = rec(n[2], box) return v1 / v2 elif n[0] == '^': v = rec(n[1], box) i = self.__dag[n[2]][1] return v**i elif n[0] == 'exp': v = rec(n[1], box) return imath.exp(v) elif n[0] == 'log': v = rec(n[1], box) return imath.log(v) elif n[0] == 'sqrt': v = rec(n[1], box) return imath.sqrt(v) elif n[0] == 'sin': v = rec(n[1], box) return imath.sin(v) elif n[0] == 'cos': v = rec(n[1], box) return imath.cos(v) elif n[0] == 'tan': v = rec(n[1], box) return imath.tan(v) elif n[0] == 'asin': v = rec(n[1], box) return imath.asin(v) elif n[0] == 'acos': v = rec(n[1], box) return imath.acos(v) elif n[0] == 'atan': v = rec(n[1], box) return imath.atan(v) elif n[0] == 'sinh': v = rec(n[1], box) return imath.sinh(v) elif n[0] == 'cosh': v = rec(n[1], box) return imath.cosh(v) elif n[0] == 'tanh': v = rec(n[1], box) return imath.tanh(v) elif n[0] == 'C': return interval[n[1]] elif n[0] == 'V': return box[n[1]] else: print('unsupported node: ' + str(n)) assert (False)
from interval import interval, inf, imath, fpu SPR_MAX = imath.sqrt(interval[4] / 3) NULL_INT = interval() UNIT_INT = interval[0, 1] GEQ_ONE = interval[1, inf] POS = interval[0, inf] MAX_DEPTH = 50 # these are helper methods meant to be used when # handling cases that share formulas # every method begins with the variable to be returned # and ends with a string indicating assumptions made # most often, the string is a list of indices w/ weight # assumed to be positive # when weights are assumed 0, the string corresponds to # an interval in increasing order; in the interval: # any number in {1, ..., 7} indicates a positive weight # N indicates the weight is assumed 0 # X (wildcard) indicates no assumption on the weight # always, we assume that: # u = mu - nu, # v = mu + nu, and # mn = mu*nu # all other variables are self-evident # formulas are written to minimize FLOPs and accumulated