#!/usr/bin/env python3 """ try to understand which transfer characteristics can be used to create stable logic. """ def fwd(offset: float, amp: float): return lambda x: min(1.0, offset + amp*x) def inv(offset: float, amp: float): return lambda x: max(0.0, 1.0 - offset - amp*x) def test_stability(fwd, inv): low = 0.0 high = 1.0 mid = 0.5 for i in range(32): low, high, mid = fwd(inv(high)), fwd(inv(low)), fwd(inv(mid)) print(f"low {low:.2f} high {high:.2f} bistable {mid:.2f}") print("stability: 0.2 + 2.0*x") test_stability(fwd(0.2, 2.0), inv(0.2, 2.0)) print("stability: 0.2 + 1.5*x") test_stability(fwd(0.2, 1.5), inv(0.2, 1.5)) print("stability: 0.2 + 1.1*x") test_stability(fwd(0.2, 1.1), inv(0.2, 1.1)) print("stability: 0.4 + 1.1*x") test_stability(fwd(0.4, 1.1), inv(0.4, 1.1)) print("stability: 0.5 + 2.0*x") test_stability(fwd(0.5, 2.0), inv(0.5, 2.0)) print("stability: 0.9*x") test_stability(fwd(0.0, 0.9), inv(0.0, 0.9)) print("stability: 0.2 + 1.5*x; 0.9 - 0.7*x") test_stability(fwd(0.2, 1.5), inv(0.1, 0.7)) print("stability: 0.1 + 1.3*x; 0.9 - 0.7*x") test_stability(fwd(0.1, 1.3), inv(0.1, 0.7)) print("""\ offset isn't a deal-breaker until it approaches 50%. for any offset < 0.5, amplification > 1.0, there is *some* stable pair of levels. as offset increases, the stable pairs become closer together """) def test_stability_inv(inv, mid=0.5): low = 0.0 high = 1.0 for i in range(32): low, high, mid = inv(high), inv(low), inv(mid) print(f"low {low:.2f} high {high:.2f} bistable {mid:.2f}") print("stability_inv: 0.2 + 2.0*x") test_stability_inv(inv(0.2, 2.0)) print("stability_inv: 0.2 + 1.1*x") test_stability_inv(inv(0.2, 1.1)) print("stability_inv: 0.5 + 1.1*x") test_stability_inv(inv(0.5, 1.1), 0.2) print("stability_inv: 0.7 + 1.1*x") test_stability_inv(inv(0.7, 1.1), 0.1) print("""\ inverter-only circuits can be stable, even if they ordinarily bias to just one direction... the same amp > 1.0 condition holds. importantly, offset > 0.5 becomes *fine* """)