def make_vgc(alpha): # inputs x = amnet.Variable(2, name='x') # affine transformations zero1 = amnet.Constant(x, np.zeros(1)) e = amnet.atoms.select(x, 0) edot = amnet.atoms.select(x, 1) ae = amnet.Linear(np.array([[alpha, 0]]), x) neg_e = amnet.Linear(np.array([[-1, 0]]), x) neg_edot = amnet.Linear(np.array([[0, -1]]), x) or0 = amnet.atoms.gate_or(zero1, ae, neg_e, neg_edot) or1 = amnet.atoms.gate_or(or0, ae, e, edot) # create naming context of the retval ctx = amnet.vis.NamingContext(or1) ctx.rename(x, 'x') ctx.rename(zero1, 'zero') ctx.rename(e, 'e') ctx.rename(edot, 'edot') ctx.rename(ae, 'ae') ctx.rename(neg_e, 'neg_e') ctx.rename(neg_edot, 'neg_edot') ctx.rename(or0, 'or0') ctx.rename(or1, 'or1') return or1, ctx
def test_SmtEncoder_gates(self): xy_z1z2 = amnet.Variable(2+2+1+1, name='xyz1z2') x = amnet.Linear( np.eye(2, 6, 0), xy_z1z2 ) y = amnet.Linear( np.eye(2, 6, 2), xy_z1z2 ) z1 = amnet.atoms.select(xy_z1z2, 4) z2 = amnet.atoms.select(xy_z1z2, 5) phi_and = amnet.atoms.gate_and(x, y, z1, z2) phi_or = amnet.atoms.gate_or(x, y, z1, z2) phi_xor = amnet.atoms.gate_xor(x, y, z1, z2) phi_not = amnet.atoms.gate_not(x, y, z1) # check dimensions self.assertEqual(xy_z1z2.outdim, 6) self.assertEqual(x.outdim, 2) self.assertEqual(y.outdim, 2) self.assertEqual(z1.outdim, 1) self.assertEqual(z2.outdim, 1) self.assertEqual(phi_and.outdim, 2) self.assertEqual(phi_or.outdim, 2) self.assertEqual(phi_xor.outdim, 2) self.assertEqual(phi_not.outdim, 2) # true gate functions def true_and(fpin): return fpin[0:2] if (fpin[4] <= 0 and fpin[5] <= 0) else fpin[2:4] def true_or(fpin): return fpin[0:2] if (fpin[4] <= 0 or fpin[5] <= 0) else fpin[2:4] def true_xor(fpin): return fpin[0:2] if ((fpin[4] <= 0) != (fpin[5] <= 0)) else fpin[2:4] def true_not(fpin): # ignores last input return fpin[2:4] if (fpin[4] <= 0) else fpin[0:2] # evaluate vals = np.array([1, -2, -3, 4]) sels = itertools.product([-1, 0, 1], repeat=2) onvals = [np.concatenate((vals, sel), axis=0) for sel in sels] self.validate_outputs(phi=phi_and, onvals=onvals, true_f=true_and) self.validate_outputs(phi=phi_or, onvals=onvals, true_f=true_or) self.validate_outputs(phi=phi_xor, onvals=onvals, true_f=true_xor) self.validate_outputs(phi=phi_not, onvals=onvals, true_f=true_not)
def max_aff(A, b, phi): """ returns an AMN that evaluates to max_i(sum_j a_{ij} phi_j + b_i) """ (m, n) = A.shape assert len(b) == m assert phi.outdim == n assert m >= 1 and n >= 1 # OLD: inefficient #phi_aff = amnet.Affine( # A, # phi, # b #) #return max_all(phi_aff) outlist = [] for i in range(m): if b[i] == 0: outlist.append(amnet.Linear(A[i, :].reshape((1, n)), phi)) else: outlist.append( amnet.Affine(A[i, :].reshape((1, n)), phi, b[i].reshape( (1, )))) assert len(outlist) == m return max_list(outlist)
def sub2(x, y): assert x.outdim == y.outdim n = x.outdim xy = amnet.Stack(x, y) return amnet.Linear(np.concatenate((np.eye(n), -np.eye(n)), axis=1), xy)
def test_SmtEncoder_dag(self): xyz = amnet.Variable(3, name='xyz') x = amnet.atoms.select(xyz, 0) yz = amnet.Linear( np.array([[0, 1, 0], [0, 0, 1]]), xyz ) maxyz = amnet.atoms.max_all(yz) twoxp1 = amnet.Affine( np.array([[2]]), x, np.array([1]) ) twox = amnet.atoms.add2(x, x) threex = amnet.atoms.add2(x, twox) fivexp1 = amnet.atoms.add2(twoxp1, threex) phi = amnet.atoms.add2(fivexp1, maxyz) def true_dag(fpin): x, y, z = fpin return 5*x + 1 + max(y, z) self.validate_outputs( phi=phi, onvals=itertools.product(self.floatvals2, repeat=3), true_f=true_dag )
def test_stack(self): x = amnet.Variable(3, name='x') w1 = np.array([[1, -2, 3]]) b1 = np.zeros(1) w2 = np.array([[-5, 6, -7], [-8, 9, 10]]) b2 = np.array([11, -12]) w3 = np.array([[7, 8, 9]]) b3 = np.array([-1]) y1 = amnet.Linear(w1, x) y2 = amnet.Affine(w2, x, b2) y3 = amnet.Affine(w3, x, b3) y4 = x ystack = amnet.atoms.from_list([y1, y2, y3, y4]) self.assertEqual(ystack.outdim, 4+3) self.assertEqual(ystack.indim, 3) def ystack_true(xinp): y1v = np.dot(w1, xinp) + b1 y2v = np.dot(w2, xinp) + b2 y3v = np.dot(w3, xinp) + b3 y4v = xinp return np.concatenate((y1v, y2v, y3v, y4v), axis=0) for (xv0, xv1, xv2) in product(self.floatvals2, repeat=3): xinp = np.array([xv0, xv1, xv2]) ysv = ystack.eval(xinp) ytv = ystack_true(xinp) self.assertAlmostEqual(norm(ysv - ytv), 0)
def add2(x, y): """main n-d add method on which all add routines rely""" assert x.outdim == y.outdim n = x.outdim xy = amnet.Stack(x, y) return amnet.Linear(np.concatenate((np.eye(n), np.eye(n)), axis=1), xy)
def select(phi, k): """ returns kth component of phi """ assert (0 <= phi.outdim) and (k < phi.outdim) # optimization: prevent creating an affine transformation # if phi is one-dimensional if phi.outdim == 1 and k == 0: return phi # otherwise, select the appropriate component return amnet.Linear(np.eye(1, phi.outdim, k), phi)
def test_SmtEncoder_add_list(self): xyz = amnet.Variable(2+2+2, name='xyz') x = amnet.Linear(np.eye(2, 6, 0), xyz) y = amnet.Linear(np.eye(2, 6, 2), xyz) z = amnet.Linear(np.eye(2, 6, 4), xyz) phi_add_list = amnet.atoms.add_list([x, y, z]) self.assertEqual(x.outdim, 2) self.assertEqual(y.outdim, 2) self.assertEqual(z.outdim, 2) self.assertEqual(phi_add_list.outdim, 2) self.assertEqual(phi_add_list.indim, 6) def true_add(fpin): x, y, z = fpin[0:2], fpin[2:4], fpin[4:6] return x + y + z self.validate_outputs( phi=phi_add_list, onvals=itertools.product(self.floatvals3, repeat=phi_add_list.indim), true_f=true_add )
def test_max2_min2(self): xy = amnet.Variable(6, name='xy') x = amnet.Linear( np.eye(3,6,0), xy ) y = amnet.Linear( np.eye(3,6,3), xy ) max_xy = amnet.atoms.max2(x, y) min_xy = amnet.atoms.min2(x, y) def true_max2(xinp, yinp): return np.maximum(xinp, yinp) def true_min2(xinp, yinp): return np.minimum(xinp, yinp) for xyv in itertools.product(self.floatvals2, repeat=6): xyinp = np.array(xyv) xinp = xyinp[:3] yinp = xyinp[3:] max_xy_tv = true_max2(xinp, yinp) max_xy_v = max_xy.eval(xyinp) min_xy_tv = true_min2(xinp, yinp) min_xy_v = min_xy.eval(xyinp) self.assertEqual(len(max_xy_tv), 3) self.assertEqual(len(max_xy_v), 3) self.assertAlmostEqual(norm(max_xy_v - max_xy_tv), 0) self.assertEqual(len(min_xy_tv), 3) self.assertEqual(len(min_xy_v), 3) self.assertAlmostEqual(norm(min_xy_v - min_xy_tv), 0)
def identity(phi): """returns phi, wrapped in an identity affine transformation""" return amnet.Linear(np.eye(phi.outdim, phi.outdim), phi)
def neg(phi): """returns the negative of phi """ assert phi.outdim >= 1 # XXX: make more efficient by peeking inside Affine, Linear, Stack, and Mu return amnet.Linear(np.diag(-np.ones(phi.outdim)), phi)
def test_SmtEncoder_cmp(self): xyz = amnet.Variable(2+2+1, name='xyz') x = amnet.Linear( np.eye(2, 5, 0), xyz ) y = amnet.Linear( np.eye(2, 5, 2), xyz ) z = amnet.atoms.select(xyz, 4) phi_eq = amnet.atoms.cmp_eq(x, y, z) phi_neq = amnet.atoms.cmp_neq(x, y, z) phi_ge = amnet.atoms.cmp_ge(x, y, z) phi_gt = amnet.atoms.cmp_gt(x, y, z) phi_le = amnet.atoms.cmp_le(x, y, z) phi_lt = amnet.atoms.cmp_lt(x, y, z) # check dimensions self.assertEqual(xyz.outdim, 5) self.assertEqual(x.outdim, 2) self.assertEqual(y.outdim, 2) self.assertEqual(z.outdim, 1) self.assertEqual(phi_eq.outdim, 2) self.assertEqual(phi_neq.outdim, 2) self.assertEqual(phi_ge.outdim, 2) self.assertEqual(phi_gt.outdim, 2) self.assertEqual(phi_le.outdim, 2) self.assertEqual(phi_lt.outdim, 2) # true cmp functions def true_eq(fpin): x, y, z = fpin[0:2], fpin[2:4], fpin[4] return x if z == 0 else y def true_neq(fpin): x, y, z = fpin[0:2], fpin[2:4], fpin[4] return x if z != 0 else y def true_ge(fpin): x, y, z = fpin[0:2], fpin[2:4], fpin[4] return x if z >= 0 else y def true_gt(fpin): x, y, z = fpin[0:2], fpin[2:4], fpin[4] return x if z > 0 else y def true_le(fpin): x, y, z = fpin[0:2], fpin[2:4], fpin[4] return x if z <= 0 else y def true_lt(fpin): x, y, z = fpin[0:2], fpin[2:4], fpin[4] return x if z < 0 else y # evaluate vals = np.array([1, -2, -3, 4]) sels = itertools.product([-1.1, -0.5, 0, 0.0, 0.01, 1, 12.0], repeat=1) onvals = [np.concatenate((vals, sel), axis=0) for sel in sels] self.validate_outputs(phi=phi_eq, onvals=onvals, true_f=true_eq) self.validate_outputs(phi=phi_neq, onvals=onvals, true_f=true_neq) self.validate_outputs(phi=phi_ge, onvals=onvals, true_f=true_ge) self.validate_outputs(phi=phi_gt, onvals=onvals, true_f=true_gt) self.validate_outputs(phi=phi_le, onvals=onvals, true_f=true_le) self.validate_outputs(phi=phi_lt, onvals=onvals, true_f=true_lt)
import numpy as np import amnet import amnet.vis # a two-dimensional input variable x = amnet.Variable(2, name='x') # choose components x0 = amnet.Linear(np.array([[1, 0]]), x) x1 = amnet.Linear(np.array([[0, 1]]), x) # subtract x0 from x1 z = amnet.Linear(np.array([[-1, 1]]), x) # maximum of x0 and x1 phimax = amnet.Mu(x0, x1, z) print phimax print phimax.eval([1, -2]) # returns: 1 # visualize dot = amnet.vis.amn2gv(phimax, title='max2(var0)') dot.render(filename='max.gv', directory='vis') print dot