def test_truediv_and_rtruediv_basic_functionality_mixed(self): for i, j in linspace(-10, 10): tape = nd.GradientTape() with tape: # testing basic functionality with mismatched keys d1 = nd.NumDict({1: i}, default=i) d2 = nd.NumDict({1: j, 2: j}, default=1) if(d1[1]*d1.default*d2[1]*d2[2] == 0): with self.assertRaises(ZeroDivisionError): if(d1[1]*d1[2] == 0): d2/d1 else: d1/d2 with self.assertRaises(ZeroDivisionError): if(d1[1]*d1[2] == 0): NumDict.__truediv__(d2, d1) else: NumDict.__truediv__(d1, d2) with self.assertRaises(ZeroDivisionError): if(d1[1]*d1[2] == 0): NumDict.__rtruediv__(d1, d2) else: NumDict.__rtruediv__(d2, d1) else: d3 = d1/d2 self.assertAlmostEqual(d3[1], d1[1]/d2[1]) self.assertAlmostEqual(d3[2], d1.default/d2[2]) d3 = NumDict.__truediv__(d1, d2) self.assertAlmostEqual(d3[1], (d1/d2)[1]) self.assertAlmostEqual(d3[2], (d1/d2)[2]) self.assertAlmostEqual(d3.default, d1.default/d2.default) self.assertAlmostEqual(NumDict.__truediv__( d1, d2), NumDict.__rtruediv__(d2, d1))
def test_threshold_mixed(self): d = nd.NumDict(default=5, data={1: 1, 2: 2, 3: 3, 4: 4, 5: 5}) with GradientTape() as t: d1 = threshold(d, th=3) self.assertAlmostEqual(d1.default, 5) for i in range(5): if(i <= 3): self.assertTrue(d1[i] == d1.default) else: self.assertAlmostEqual(d1[i], i) d = nd.NumDict(default=2, data={1: 1, 2: 2, 3: 3, 4: 4, 5: 5}) with GradientTape() as t: d1 = threshold(d, th=3) d1 = d1*1 self.assertTrue(d1.default == None) for i in range(5): if(i <= 3): self.assertTrue(d1.get(i) == None) else: self.assertAlmostEqual(d1[i], i) d1, g = t.gradients(d1, d) self.assertAlmostEqual(g.get(1), 0) self.assertAlmostEqual(g.get(2), 0) self.assertAlmostEqual(g.get(3), 0) self.assertAlmostEqual(g.get(4), 1) self.assertAlmostEqual(g.get(5), 1)
def test_subtraction_basic_functionality_defaults(self): for i, j in linspace(-10, 10): # testing basic functionality for default d1 = nd.NumDict(default=i) d2 = nd.NumDict(default=j) self.assertAlmostEqual((d1-d2).default, d1.default-d2.default) self.assertAlmostEqual((d2-d1).default, d2.default-d1.default)
def test_truediv_and_rtruediv_basic_functionality_defaults(self): for i, j in linspace(-10, 10): tape = nd.GradientTape() with tape: # testing basic functionality for default d1 = nd.NumDict(default=i) d2 = nd.NumDict(default=j) if(d1.default*d2.default == 0): with self.assertRaises(ZeroDivisionError): if(d1.default == 0): d2/d1 else: d1/d2 with self.assertRaises(ZeroDivisionError): if(d1.default == 0): NumDict.__truediv__(d2, d1) else: NumDict.__truediv__(d1, d2) with self.assertRaises(ZeroDivisionError): if(d1.default == 0): NumDict.__rtruediv__(d1, d2) else: NumDict.__rtruediv__(d2, d1) else: self.assertAlmostEqual( (d1/d2).default, d1.default/d2.default) self.assertAlmostEqual(NumDict.__truediv__( d1, d2).default, (d1/d2).default) self.assertAlmostEqual(NumDict.__truediv__( d1, d2).default, NumDict.__rtruediv__(d2, d1).default)
def test_truediv_and_rtruediv_basic_functionality_keys(self): for i, j in linspace(-10, 10): tape = nd.GradientTape() with tape: # testing basic functionality for elements d1 = nd.NumDict({1: i, 2: (i+j)}) d2 = nd.NumDict({1: j, 2: (i-j)}) if(d1[1]*d1[2]*d2[1]*d2[2] == 0): with self.assertRaises(ZeroDivisionError): if(d1[1]*d1[2] == 0): d2/d1 else: d1/d2 with self.assertRaises(ZeroDivisionError): if(d1[1]*d1[2] == 0): NumDict.__truediv__(d2, d1) else: NumDict.__truediv__(d1, d2) with self.assertRaises(ZeroDivisionError): if(d1[1]*d1[2] == 0): NumDict.__rtruediv__(d1, d2) else: NumDict.__rtruediv__(d2, d1) else: d3 = d1/d2 self.assertAlmostEqual(d3[1], d1[1]/d2[1]) self.assertAlmostEqual(d3[2], d1[2]/d2[2]) d3 = NumDict.__truediv__(d1, d2) self.assertAlmostEqual(d3[1], (d1/d2)[1]) self.assertAlmostEqual(d3[2], (d1/d2)[2]) self.assertAlmostEqual(NumDict.__truediv__( d1, d2), NumDict.__rtruediv__(d2, d1))
def test_addition_basic_functionality_nodefault(self): for i, j in linspace(-10, 10): # testing basic functionality with no default and a default d1 = nd.NumDict({1: i, 3: i}, default=i) d2 = nd.NumDict({1: j, 2: j}) with self.assertRaises(KeyError): d1+d2
def test_pow_and_rpow_basic_functionality_nodefault(self): for i, j in linspace(-10, 10): # testing basic functionality with mismatched keys d1 = nd.NumDict({1: i, 3: i}, default=i) d2 = nd.NumDict({1: j, 2: j}) if (d1[1] >= 0 and d1.default > 0) or ((d1[1] < 0 and d2[1].is_integer()) and (d1.default < 0 and d2[2].is_integer())): with self.assertRaises(KeyError): d1**d2
def test_subtraction_basic_functionality_keys(self): for i, j in linspace(-10, 10): # testing basic functionality for elements d1 = nd.NumDict({1: i, 2: (i+j)}) d2 = nd.NumDict({1: j, 2: (i-j)}) d3 = d1-d2 self.assertAlmostEqual(d3[1], d1[1]-d2[1]) self.assertAlmostEqual(d3[2], d1[2]-d2[2])
def test_truediv_and_rtruediv_basic_functionality_nodefault(self): for i, j in linspace(-10, 10): # testing basic functionality with mismatched keys d1 = nd.NumDict({1: i, 3: i}, default=i) d2 = nd.NumDict({1: j, 2: j}) if(d1[1]*d1.default*d2[1]*d2[2] != 0): with self.assertRaises(KeyError): d1/d2
def test_subtraction_basic_functionality_mixed(self): for i, j in linspace(-10, 10): # testing basic functionality with mismatched keys d1 = nd.NumDict({1: i}, default=i) d2 = nd.NumDict({1: j, 2: j}, default=0) d3 = d1-d2 self.assertAlmostEqual(d3[1], d1[1]-d2[1]) self.assertAlmostEqual(d3[2], d1.default-d2[2]) self.assertAlmostEqual(d3.default, d1.default-d2.default)
def test_addition_basic_functionality_defaults(self): for i, j in linspace(-10, 10): # testing basic functionality for defaults d1 = nd.NumDict(default=i) d2 = nd.NumDict(default=j) self.assertAlmostEqual((d1+d2).default, d1.default+d2.default) d3 = nd.NumDict(default=3.0) self.assertAlmostEqual((d2+d1+d3).default, (d3+d1+d2).default) self.assertAlmostEqual((d3+d1+d2).default, (d1+d2+d3).default)
def test_check_inputs_accepts_good_input_structure(self): process = clb.Process( expected=[clb.buffer("wm"), clb.terminus("selection")]) inputs = { clb.buffer("wm"): nd.NumDict(default=0), clb.terminus("selection"): nd.NumDict(default=0), clb.terminus("selection2"): nd.NumDict(default=0) } process.check_inputs(inputs)
def test_threshold_default(self): d = nd.NumDict(default=5) with GradientTape() as t: #d1 = sum_by(d,keyfunc=[1,2]) d1 = threshold(d, th=3) self.assertAlmostEqual(d1.default, 5) d1, g = t.gradients(d1, d) self.assertAlmostEqual(g.default, 1) d = nd.NumDict(default=2) with GradientTape() as t: d1 = threshold(d, th=3) self.assertTrue(d1.default == None)
def test_productRule(self): for i, j in linspace(-10, 10): t1 = nd.GradientTape() with t1: # testing differentiation for default d1 = nd.NumDict(default=i) d2 = nd.NumDict(default=j) d3 = nd.NumDict(default=i+j) d4 = (d1+d2)*d3 d4, grad = t1.gradients(d4, (d1, d2, d3)) self.assertAlmostEqual(grad[0].default, d3.default) self.assertAlmostEqual(grad[1].default, d3.default) self.assertAlmostEqual(grad[2].default, d1.default+d2.default)
def test_multiplication_basic_functionality_default(self): for i, j in linspace(-10, 10): # testing basic functionality for default d1 = nd.NumDict(default=i) d2 = nd.NumDict(default=j) self.assertAlmostEqual((d1*d2).default, d1.default*d2.default) # testing multiplying by 0 d0 = nd.NumDict(default=0.0) self.assertAlmostEqual((d2*d0).default, 0.0) self.assertAlmostEqual((d1*d0).default, 0.0) # testing communative d3 = nd.NumDict(default=3.0) self.assertAlmostEqual((d2*d1*d3).default, (d3*d1*d2).default) self.assertAlmostEqual((d1*d2*d3).default, (d1*d2*d3).default)
def test_pow_and_rpow_basic_functionality_keys(self): for i, j in linspace(-10, 10): # testing basic functionality for elements d1 = nd.NumDict({1: i, 2: (i+j)}) d2 = nd.NumDict({1: j, 2: (i-j)}) if (d1[1] >= 0 and d1[2] >= 0) or ((d1[1] < 0 and d2[1].is_integer()) and (d1[2] < 0 and d2[2].is_integer())): d3 = d1 ** d2 self.assertAlmostEqual(d3[1], d1[1] ** d2[1]) self.assertAlmostEqual(d3[2], d1[2] ** d2[2]) self.assertAlmostEqual(NumDict.__pow__(d1, d2)[1], d3[1]) self.assertAlmostEqual(NumDict.__pow__(d1, d2)[2], d3[2]) self.assertAlmostEqual(NumDict.__pow__(d1, d2)[1], NumDict.__rpow__(d2, d1)[1]) self.assertAlmostEqual(NumDict.__pow__(d1, d2)[2], NumDict.__rpow__(d2, d1)[2])
def test_check_inputs_rejects_incomplete_input(self): process = clb.Process( expected=[clb.chunks("in"), clb.terminus("selection")]) with self.assertRaises(RuntimeError): inputs = { # clb.buffer("wm"): nd.NumDict(default=0), clb.terminus("selection"): nd.NumDict(default=0), clb.terminus("selection2"): nd.NumDict(default=0) } process.check_inputs(inputs)
def test_structure_output_is_correctly_formed(self): agent = clb.Structure(name=clb.agent("agent"), assets=None) with agent: clb.Construct(name=clb.buffer("sensory"), process=clb.Process()) clb.Construct(name=clb.buffer("wm"), process=clb.Process()) nacs = clb.Structure(name=clb.subsystem("nacs"), assets=None) with nacs: clb.Construct(name=clb.chunks("in"), process=clb.Process()) clb.Construct(name=clb.flow_tt("associative_rules"), process=clb.Process()) clb.Construct(name=clb.chunks("out"), process=clb.Process()) clb.Construct(name=clb.terminus("selection"), process=clb.Process()) nacs_expected = { clb.chunks("in"): nd.NumDict(default=0), clb.flow_tt("associative_rules"): nd.NumDict(default=0), clb.chunks("out"): nd.NumDict(default=0), clb.terminus("selection"): nd.NumDict(default=0) } agent_expected = { clb.buffer("sensory"): nd.NumDict(default=0), clb.buffer("wm"): nd.NumDict(default=0), (clb.subsystem("nacs"), clb.chunks("in")): nd.NumDict(default=0), (clb.subsystem("nacs"), clb.flow_tt("associative_rules")): nd.NumDict(default=0), (clb.subsystem("nacs"), clb.chunks("out")): nd.NumDict(default=0), (clb.subsystem("nacs"), clb.terminus("selection")): nd.NumDict(default=0) } self.assertEqual(nacs.output, nacs_expected, "failed on nacs") self.assertEqual(agent.output, agent_expected, "failed on agent")
def test_persistent(self): for i, j in linspace(-10, 10): t1 = nd.GradientTape(persistent=True) with t1: d1 = nd.NumDict(default=i) d2 = nd.NumDict(default=j) d3 = d1*d1*d2*d2 d4, g1 = t1.gradients(d3, (d1, d2), forward=False) self.assertAlmostEqual( g1[0].default, 2*d1.default*d2.default*d2.default) self.assertAlmostEqual( g1[1].default, 2*d2.default*d1.default*d1.default) d4, g1 = t1.gradients(d3, (d2, d1), forward=False) self.assertAlmostEqual( g1[1].default, 2*d1.default*d2.default*d2.default) self.assertAlmostEqual( g1[0].default, 2*d2.default*d1.default*d1.default)
def test_pow_and_rpow_basic_functionality_mixed(self): for i, j in linspace(-10, 10): # testing basic functionality for elements d1 = nd.NumDict({1: i}, default=i) d2 = nd.NumDict({1: j, 2: j}, default=1) if (d1[1] >= 0 and d1.default > 0) or ((d1[1] < 0 and d2[1].is_integer()) and (d1.default < 0 and d2[2].is_integer())): d3 = d1 ** d2 self.assertAlmostEqual(d3[1], d1[1] ** d2[1]) self.assertAlmostEqual(d3[2], d1[2] ** d2[2]) self.assertAlmostEqual(d3.default, d1.default**d2.default) self.assertAlmostEqual( NumDict.__pow__(d1, d2)[1], d3[1]) self.assertAlmostEqual( NumDict.__pow__(d1, d2)[2], d3[2]) self.assertAlmostEqual(NumDict.__pow__(d1, d2)[1], NumDict.__rpow__(d2, d1)[1]) self.assertAlmostEqual(NumDict.__pow__(d1, d2)[2], NumDict.__rpow__(d2, d1)[2])
def test_parse_commands_runtime_error(self): test_interface = clb.Interface(cmds=( feature("down", 1), feature("down", 0), feature("up", 0), feature("up", 1), ), ) with self.subTest(msg="unexpected default strength"): data = nd.NumDict({ feature("down", 1): 1.0, feature("up", 0): 1.0 }, default=1) with self.assertRaises(ValueError): res = test_interface.parse_commands(data) with self.subTest(msg="Encounter non-integral cmd strength"): data = nd.NumDict({ feature("down", 1): 0.5, feature("up", 0): 1.0 }, default=0) with self.assertRaises(ValueError): res = test_interface.parse_commands(data) with self.subTest(msg="Encounter multiple values from a single dim"): data = nd.NumDict( { feature("down", 1): 1.0, feature("down", 0): 1.0, feature("down", 2): 1.0, feature("up", 0): 1.0 }, default=0) with self.assertRaises(ValueError): res = test_interface.parse_commands(data)
def test_transform_keys(self):#TODO FIX d = nd.NumDict(data={1: 1, 2: 2, 3: 3, 4: 4, 5: 5}) with GradientTape() as t: d1 = transform_keys(d, self.dummyfunc1) for i in range(1, 10): if(d1.get(i) != None): self.assertAlmostEqual(d1.get(i), i/2) d1, g1 = t.gradients(d1, d) for i in range(1, 5): if(d1.get(i) != None): self.assertAlmostEqual(g1[i], 1)
def test_truediv_and_rtruediv_differentiation(self): for i, j in linspace(-10, 10): tape = nd.GradientTape() with tape: # testing differentiation for truediv and default d1 = nd.NumDict(default=i) d2 = nd.NumDict(default=j) if(d2.default != 0): d3 = NumDict.__truediv__(d1, d2) if(d2.default != 0): d3, grads = tape.gradients(d3, (d1, d2)) self.assertAlmostEqual(grads[0].default, 1/d2.default) self.assertAlmostEqual(grads[1].default, (-d1.default)/(d2.default**2)) with tape: # testing differentiation for rtruediv and default d1 = nd.NumDict(default=i) d2 = nd.NumDict(default=j) if(d1.default != 0): d4 = NumDict.__rtruediv__(d1, d2) if(d1.default != 0): d4, grads = tape.gradients(d4, (d1, d2)) self.assertAlmostEqual(grads[0].default, (-d2.default)/(d1.default**2)) self.assertAlmostEqual(grads[1].default, 1/d1.default) tape = nd.GradientTape() with tape: # testing differentiation for truediv and elements d1 = nd.NumDict({1: i, 2: (i+j)}) d2 = nd.NumDict({1: j, 2: (i-j)}) if(d2[1]*d2[2] != 0): d3 = NumDict.__truediv__(d1, d2) if(d2[1]*d2[2] != 0): d3, grads = tape.gradients(d3, (d1, d2)) self.assertAlmostEqual(grads[0][1], 1/d2[1]) self.assertAlmostEqual(grads[0][2], 1/d2[2]) self.assertAlmostEqual(grads[1][1], (-d1[1])/(d2[1]**2)) self.assertAlmostEqual(grads[1][2], (-d1[2])/(d2[2]**2)) tape = nd.GradientTape() with tape: # testing differentiation for rtruediv and elements d1 = nd.NumDict({1: i, 2: (i+j)}) d2 = nd.NumDict({1: j, 2: (i-j)}) if(d1[1]*d1[2] != 0): d3 = NumDict.__rtruediv__(d1, d2) if(d1[1]*d1[2] != 0): d3, grads = tape.gradients(d3, (d1, d2)) self.assertAlmostEqual(grads[0][1], (-d2[1])/(d1[1]**2)) self.assertAlmostEqual(grads[0][2], (-d2[2])/(d1[2]**2)) self.assertAlmostEqual(grads[1][1], 1/d1[1]) self.assertAlmostEqual(grads[1][2], 1/d1[2])
def test_pow_and_rpow_basic_functionality_defaults(self): for i, j in linspace(-10, 10): # testing basic functionality for default d1 = nd.NumDict(default=i) d2 = nd.NumDict(default=j) if(d1.default >= 0) or (d1.default < 0 and d2.default.is_integer()): if (d1.default != 0 or d2.default >= 0): self.assertAlmostEqual( (d1 ** d2).default, d1.default ** d2.default) self.assertAlmostEqual(NumDict.__pow__( d1, d2).default, (d1**d2).default) self.assertAlmostEqual(NumDict.__pow__( d1, d2).default, NumDict.__rpow__(d2, d1).default) else: with self.assertRaises(ZeroDivisionError): self.assertAlmostEqual( (d1 ** d2).default, d1.default ** d2.default) self.assertAlmostEqual(NumDict.__pow__( d1, d2).default, (d1**d2).default) self.assertAlmostEqual(NumDict.__pow__( d1, d2).default, NumDict.__rpow__(d2, d1).default)
def test_addition_differentiation(self): for i, j in linspace(-10, 10): tape = nd.GradientTape() with tape: # testing differentiation for defaults d1 = nd.NumDict(default=i) d2 = nd.NumDict(default=j) d4 = d1 + d2 d4, grads = tape.gradients(d4, (d1, d2)) self.assertAlmostEqual(grads[0].default, 1.0) self.assertAlmostEqual(grads[1].default, 1.0) tape = nd.GradientTape() with tape: # testing differentiation for elements d1 = nd.NumDict({1: i, 2: (i+j)}) d2 = nd.NumDict({1: j, 2: (i-j)}) d3 = d1+d2 d3, grads = tape.gradients(d3, (d1, d2)) self.assertAlmostEqual(grads[0][1], 1.0) self.assertAlmostEqual(grads[0][2], 1.0) self.assertAlmostEqual(grads[1][1], 1.0) self.assertAlmostEqual(grads[1][2], 1.0)
def test_drop_keys(self): d = nd.NumDict(data={1: 1, 2: 2, 3: 3, 4: 4, 5: 5}) testCollection = {1: True} with GradientTape() as t: d1 = drop(d, self.dummyfunc, testCollection) for i in range(1, 5): if(i % 2 == 0 or i == 1): self.assertTrue(d1.get(i) == None) else: self.assertAlmostEqual(d1[i], i) d1, g = t.gradients(d1, d) for i in range(1, 5): if(i % 2 == 0 or i == 1): self.assertAlmostEqual(g.get(i), 0) else: self.assertAlmostEqual(g[i], 1)
def test_multiplication_differentiation(self): for i, j in linspace(-10, 10): tape = nd.GradientTape() with tape: # testing differentiation for default d1 = nd.NumDict(default=i) d2 = nd.NumDict(default=j) d3 = d1*d2 d3, grads = tape.gradients(d3, (d1, d2)) self.assertAlmostEqual(grads[0].default, d2.default) self.assertAlmostEqual(grads[1].default, d1.default) tape = nd.GradientTape() with tape: # testing differentiation for multiple NumDicts d1 = nd.NumDict(default=i) d2 = nd.NumDict(default=j) d3 = d1*d1*d2 d3, grads = tape.gradients(d3, (d1, d2)) self.assertAlmostEqual(grads[0].default, d2.default*d1.default*2) self.assertAlmostEqual(grads[1].default, d1.default*d1.default) tape = nd.GradientTape() with tape: # testing differentiation with non NumDict elements d1 = nd.NumDict(default=i) d2 = nd.NumDict(default=j) d3 = d1*d2 d4 = i*d3 d3, grads = tape.gradients(d4, (d1, d2)) self.assertAlmostEqual(grads[0].default, i*d2.default) self.assertAlmostEqual(grads[1].default, i*d1.default) tape = nd.GradientTape() with tape: # testing differentiation for elements d1 = nd.NumDict({1: i, 2: (i+j)}) d2 = nd.NumDict({1: j, 2: (i-j)}) d3 = d1*d2 d3, grads = tape.gradients(d3, (d1, d2)) self.assertAlmostEqual(grads[0][1], d2[1]) self.assertAlmostEqual(grads[0][2], d2[2]) self.assertAlmostEqual(grads[1][1], d1[1]) self.assertAlmostEqual(grads[1][2], d1[2])
def test_clip_keys(self): d = nd.NumDict(data={1: 1, 2: 2, 3: 3, 4: 4, 5: 5}) with GradientTape() as t: d1 = clip(d, 2, 4) for i in range(1, 5): if(i < 2): self.assertAlmostEqual(d1[i], 2) elif(i > 4): self.assertAlmostEqual(d1[i], 4) else: self.assertAlmostEqual(d1[i], i) d1, g = t.gradients(d1, d) for i in range(1, 5): if(i <= 2): self.assertAlmostEqual(g[i], 0) elif(i >= 4): self.assertAlmostEqual(g[i], 0) else: self.assertAlmostEqual(g[i], 1)
def test_parse_commands(self): with self.subTest(msg="classic test"): test_interface = clb.Interface(cmds=(feature("up", 0), feature("up", 1), feature("down", 0), feature("down", 1)), ) data = nd.NumDict({ feature("up", 1): 1.0, feature("down", 0): 1.0 }, default=0) res = test_interface.parse_commands(data) self.assert_parse_result( [feature("up", 1), feature("down", 0)], res) with self.subTest(msg="different order in cmds doesn't matter"): test_interface = clb.Interface(cmds=(feature("down", 1), feature("down", 0), feature("up", 0), feature("up", 1)), ) data = nd.NumDict({ feature("down", 1): 1.0, feature("up", 0): 1.0 }, default=0) res = test_interface.parse_commands(data) self.assert_parse_result( [feature("down", 1), feature("up", 0)], res) with self.subTest(msg="more randomness in cmds"): test_interface = clb.Interface(cmds=( feature("down", 1), feature("down", 0), feature("up", 0), feature("up", 1), feature("left", 1), feature("left", 0), feature("right", 0), feature("right", 1), ), ) data = nd.NumDict( { feature("down", 1): 1.0, feature("up", 0): 1.0, feature("left", 0): 1.0, feature("right", 0): 1.0 }, default=0) res = test_interface.parse_commands(data) self.assert_parse_result([ feature("down", 1), feature("up", 0), feature("left", 0), feature("right", 0) ], res) with self.subTest(msg="cmds size == 1"): test_interface = clb.Interface(cmds=(feature("up", 1), ), ) data = nd.NumDict({feature("up", 0): 1.0}, default=0) res = test_interface.parse_commands(data) self.assert_parse_result([feature("up", 1)], res) with self.subTest(msg="cmds size == 0"): test_interface = clb.Interface(cmds=(), ) data = nd.NumDict({}, default=0) res = test_interface.parse_commands(data) self.assert_parse_result([], res)
def test_pow_and_rpow_differentiation(self): for i, j in linspace(-1, 10): tape = nd.GradientTape() with tape: # testing differentiation for default with normal operator d1 = nd.NumDict(default=i) d2 = nd.NumDict(default=j) if(d1.default >= 0) or (d1.default < 0 and d2.default.is_integer()): if(d1.default != 0 and d2.default != 0): d3 = d1 ** d2 if(d1.default >= 0) or (d1.default < 0 and d2.default.is_integer()): if(d1.default != 0 and d2.default != 0): d3, grads1 = tape.gradients(d3, (d1, d2)) self.assertAlmostEqual( grads1[0].default, (d1.default**(d2.default-1))*d2.default) if(d1.default < 0): self.assertTrue(math.isnan(grads1[1].default)) else: self.assertAlmostEqual(grads1[1].default, d1.default ** d2.default*math.log(d1.default)) tape = nd.GradientTape() with tape: # testing differentiation for default with __pow__ d1 = nd.NumDict(default=i) d2 = nd.NumDict(default=j) if(d1.default >= 0) or (d1.default < 0 and d2.default.is_integer()): if(d1.default != 0 and d2.default != 0): d3 = NumDict.__pow__(d1, d2) if(d1.default >= 0) or (d1.default < 0 and d2.default.is_integer()): if(d1.default != 0 and d2.default != 0): d3, grads2 = tape.gradients(d3, (d1, d2)) self.assertAlmostEqual(grads2[0].default, d1.default**(d2.default-1)*d2.default) if(d1.default < 0): self.assertTrue(math.isnan(grads2[1].default)) else: self.assertAlmostEqual(grads2[1].default, d1.default ** d2.default*math.log(d1.default)) tape = nd.GradientTape() with tape: # testing differentiation for default with __rpow__ d1 = nd.NumDict(default=i) d2 = nd.NumDict(default=j) if(d1.default >= 0) or (d1.default < 0 and d2.default.is_integer()): if(d1.default != 0 and d2.default != 0): d3 = NumDict.__rpow__(d2, d1) if(d1.default >= 0) or (d1.default < 0 and d2.default.is_integer()): if(d1.default != 0 and d2.default != 0): d3, grads3 = tape.gradients(d3, (d1, d2)) self.assertAlmostEqual(grads3[0].default, d1.default**(d2.default-1)*d2.default) if(d1.default < 0): self.assertTrue(math.isnan(grads3[1].default)) else: self.assertAlmostEqual(grads3[1].default, d1.default ** d2.default*math.log(d1.default)) # verifying that all differentiation is equal to one another if(math.isnan(grads1[0].default) or math.isnan(grads1[0].default) or math.isnan(grads2[0].default) or math.isnan(grads2[0].default) or math.isnan(grads3[0].default) or math.isnan(grads3[1].default)): self.assertTrue(math.isnan(grads1[0].default) == math.isnan( grads2[0].default) == math.isnan(grads3[0].default)) self.assertTrue(math.isnan(grads1[1].default) == math.isnan( grads2[1].default) == math.isnan(grads3[1].default)) else: self.assertAlmostEqual(grads1[0].default, grads2[0].default) self.assertAlmostEqual(grads1[1].default, grads2[1].default) self.assertAlmostEqual(grads2[0].default, grads3[0].default) self.assertAlmostEqual(grads2[1].default, grads3[1].default) with tape: # testing differentiation for elements with normal operator d1 = nd.NumDict({1: i, 2: (i+j)}) d2 = nd.NumDict({1: j, 2: (i-j)}) if (d1[1] >= 0 and d1[2] >= 0) or ((d1[1] < 0 and d2[1].is_integer()) and (d1[2] < 0 and d2[2].is_integer())): d3 = d1 ** d2 if (d1[1] > 0 and d1[2] > 0) or ((d1[1] < 0 and d2[1].is_integer()) and (d1[2] < 0 and d2[2].is_integer())): d3, grads = tape.gradients(d3, (d1, d2)) self.assertAlmostEqual( grads[0][1], (d1[1]**(d2[1]-1))*d2[1]) if(d1[1] < 0): self.assertTrue(math.isnan(grads[1][1])) else: self.assertAlmostEqual(grads[1][1], d1[1] ** d2[1]*math.log(d1[1])) self.assertAlmostEqual( grads[0][2], (d1[2]**(d2[2]-1))*d2[2]) if(d1[2] < 0): self.assertTrue(math.isnan(grads[1][2])) else: self.assertAlmostEqual(grads[1][2], d1[2] ** d2[2]*math.log(d1[2]))