Processing math: 100%

Simple optimization

This is to test and illustrate a very basic case of optimization, with types A and B, a term a:A and a function f:AB. We have f(a) as a generator initially, but this should drop out if we have high weight for entropy.

In [1]:
import $cp.bin.`provingground-core-jvm-4d3ce04.fat.jar`
Out[1]:
import $cp.$                                           
In [2]:
import provingground._ , interface._, HoTT._, learning._
Out[2]:
import provingground._ , interface._, HoTT._, learning._ 
In [3]:
repl.pprinter() = {
  val p = repl.pprinter()
  p.copy(
    additionalHandlers = p.additionalHandlers.orElse {
      translation.FansiShow.fansiHandler
    }
  )
}
In [4]:
val A = "A" :: Type
val B = "B" :: Type
val a = "a" :: A
val f = "f"  :: (A ->: B)
Out[4]:
A: Typ[Term] = A
B: Typ[Term] = B
a: Term = a
f: Func[Term, Term] = f
In [5]:
val ts = TermState(FiniteDistribution.unif(a, f, f(a)), FiniteDistribution.unif(A, B))
Out[5]:
ts: TermState = TermState(
  FiniteDistribution(
    Vector(
      Weighted(a, 0.3333333333333333),
      Weighted(f, 0.3333333333333333),
      Weighted(f(a), 0.3333333333333333)
    )
  ),
  FiniteDistribution(Vector(Weighted(A, 0.5), Weighted(B, 0.5))),
  Vector(),
  FiniteDistribution(Vector()),
  FiniteDistribution(Vector()),
  Empty
)
In [6]:
val lp = LocalProver(ts).noIsles
Out[6]:
lp: LocalProver = LocalProver(
  TermState(
    FiniteDistribution(
      Vector(
        Weighted(a, 0.3333333333333333),
        Weighted(f, 0.3333333333333333),
        Weighted(f(a), 0.3333333333333333)
      )
    ),
    FiniteDistribution(Vector(Weighted(A, 0.5), Weighted(B, 0.5))),
    Vector(),
    FiniteDistribution(Vector()),
    FiniteDistribution(Vector()),
    Empty
  ),
  TermGenParams(
    0.1,
    0.1,
    0.1,
    0.0,
    0.0,
    0.05,
    0.05,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.3,
    0.7,
    0.5,
    0.0,
    0.0,
    0.0
  ),
  1.0E-4,
  12 minutes,
  1.01,
  1.0,
...
In [7]:
val tunedT = lp.tunedGenerators
Out[7]:
tunedT: monix.eval.Task[FiniteDistribution[Term]] = Map(
  Suspend(
    monix.tail.internal.IterantFoldLeftL$$$Lambda$2587/1046500047@6baca90b
  ),
  provingground.learning.LocalProverStep$$Lambda$2588/322700629@53fe9479,
  0
)
In [8]:
import monix.execution.Scheduler.Implicits.global
val tunedF = tunedT.runToFuture
In [9]:
lp.nextState.runToFuture
In [10]:
lp.expressionEval.map(_.entropy()).runToFuture
In [11]:
lp.expressionEval.flatMap(_.generatorIterant(1, 1, 0.0001).headOptionL).runToFuture
In [12]:
lp.expressionEval.flatMap(_.generatorIterant(1, 1, 0.0001).take(1000).lastOptionL).runToFuture
In [13]:
lp.expressionEval.flatMap(_.generatorIterant(1, 10, 0.0001).take(1000).lastOptionL).runToFuture
In [14]:
lp.expressionEval.flatMap(_.generatorIterant(0.01, 10, 0.000001).take(1000).lastOptionL).runToFuture
In [15]:
val lp0 = LocalProver(TermState(FiniteDistribution.unif(a, f(a)), FiniteDistribution.unif(A, B)), TermGenParams.zero)
Out[15]:
lp0: LocalProver = LocalProver(
  TermState(
    FiniteDistribution(Vector(Weighted(a, 0.5), Weighted(f(a), 0.5))),
    FiniteDistribution(Vector(Weighted(A, 0.5), Weighted(B, 0.5))),
    Vector(),
    FiniteDistribution(Vector()),
    FiniteDistribution(Vector()),
    Empty
  ),
  TermGenParams(
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.3,
    0.7,
    0.5,
    0.0,
    0.0,
    0.0
  ),
  1.0E-4,
  12 minutes,
  1.01,
  1.0,
  10000,
  10,
  1.0,
  1.0
)
In [16]:
lp0.tunedGenerators.runToFuture
In [17]:
val lp1 = LocalProver(TermState(FiniteDistribution(a -> 0.8, f(a) -> 0.2), FiniteDistribution.unif(A, B)), TermGenParams.zero)
Out[17]:
lp1: LocalProver = LocalProver(
  TermState(
    FiniteDistribution(Vector(Weighted(a, 0.8), Weighted(f(a), 0.2))),
    FiniteDistribution(Vector(Weighted(A, 0.5), Weighted(B, 0.5))),
    Vector(),
    FiniteDistribution(Vector()),
    FiniteDistribution(Vector()),
    Empty
  ),
  TermGenParams(
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.3,
    0.7,
    0.5,
    0.0,
    0.0,
    0.0
  ),
  1.0E-4,
  12 minutes,
  1.01,
  1.0,
  10000,
  10,
  1.0,
  1.0
)
In [18]:
lp1.tunedGenerators.runToFuture
In [19]:
val lp2 = LocalProver(TermState(FiniteDistribution(a -> 0.8, f(a) -> 0.2), FiniteDistribution.unif(A, B)), TermGenParams.zero, klW = 0.00001)
Out[19]:
lp2: LocalProver = LocalProver(
  TermState(
    FiniteDistribution(Vector(Weighted(a, 0.8), Weighted(f(a), 0.2))),
    FiniteDistribution(Vector(Weighted(A, 0.5), Weighted(B, 0.5))),
    Vector(),
    FiniteDistribution(Vector()),
    FiniteDistribution(Vector()),
    Empty
  ),
  TermGenParams(
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.3,
    0.7,
    0.5,
    0.0,
    0.0,
    0.0
  ),
  1.0E-4,
  12 minutes,
  1.01,
  1.0,
  10000,
  10,
  1.0,
  1.0E-5
)
In [20]:
lp2.tunedGenerators.runToFuture
In [21]:
val lp3 = LocalProver(TermState(FiniteDistribution(a -> 0.8, f(a) -> 0.2), FiniteDistribution.unif(A, B)), TermGenParams.zero, klW = 0.1)
Out[21]:
lp3: LocalProver = LocalProver(
  TermState(
    FiniteDistribution(Vector(Weighted(a, 0.8), Weighted(f(a), 0.2))),
    FiniteDistribution(Vector(Weighted(A, 0.5), Weighted(B, 0.5))),
    Vector(),
    FiniteDistribution(Vector()),
    FiniteDistribution(Vector()),
    Empty
  ),
  TermGenParams(
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.3,
    0.7,
    0.5,
    0.0,
    0.0,
    0.0
  ),
  1.0E-4,
  12 minutes,
  1.01,
  1.0,
  10000,
  10,
  1.0,
  0.1
)
In [22]:
lp3.tunedGenerators.runToFuture
In [23]:
val lp4 = LocalProver(TermState(FiniteDistribution(a -> 0.8, f(a) -> 0.2), FiniteDistribution.unif(A, B)), TermGenParams.zero, klW = 0.4)
Out[23]:
lp4: LocalProver = LocalProver(
  TermState(
    FiniteDistribution(Vector(Weighted(a, 0.8), Weighted(f(a), 0.2))),
    FiniteDistribution(Vector(Weighted(A, 0.5), Weighted(B, 0.5))),
    Vector(),
    FiniteDistribution(Vector()),
    FiniteDistribution(Vector()),
    Empty
  ),
  TermGenParams(
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.3,
    0.7,
    0.5,
    0.0,
    0.0,
    0.0
  ),
  1.0E-4,
  12 minutes,
  1.01,
  1.0,
  10000,
  10,
  1.0,
  0.4
)
In [24]:
lp4.tunedGenerators.runToFuture
In [25]:
lp.expressionEval.flatMap(_.generatorIterant(0.0001, 10, 0.000001).take(1000).lastOptionL).runToFuture
In [26]:
lp.expressionEval.flatMap(_.generatorIterant(0.00001, 10, 0.00000001).take(1000).lastOptionL).runToFuture

The code seems correct, but there seems to almost be a phase transition, and for far more unequal weights than expected. The above seems to be the stable case.

In [27]:
val ts = TermState(FiniteDistribution.unif(a, f), FiniteDistribution(A -> 0.01, B -> 0.99))
val lp5 = LocalProver(ts,  hW = 0.0001).noIsles
Out[27]:
ts: TermState = TermState(
  FiniteDistribution(Vector(Weighted(a, 0.5), Weighted(f, 0.5))),
  FiniteDistribution(Vector(Weighted(A, 0.01), Weighted(B, 0.99))),
  Vector(),
  FiniteDistribution(Vector()),
  FiniteDistribution(Vector()),
  Empty
)
lp5: LocalProver = LocalProver(
  TermState(
    FiniteDistribution(Vector(Weighted(a, 0.5), Weighted(f, 0.5))),
    FiniteDistribution(Vector(Weighted(A, 0.01), Weighted(B, 0.99))),
    Vector(),
    FiniteDistribution(Vector()),
    FiniteDistribution(Vector()),
    Empty
  ),
  TermGenParams(
    0.1,
    0.1,
    0.1,
    0.0,
    0.0,
    0.05,
    0.05,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.3,
    0.7,
    0.5,
    0.0,
    0.0,
    0.0
  ),
  1.0E-4,
  12 minutes,
  1.01,
  1.0,
  10000,
  10,
  1.0E-4,
  1.0
)
In [28]:
lp5.tunedGenerators.runToFuture
In [29]:
val lp6 = LocalProver(ts,  hW = 0.1).noIsles
Out[29]:
lp6: LocalProver = LocalProver(
  TermState(
    FiniteDistribution(Vector(Weighted(a, 0.5), Weighted(f, 0.5))),
    FiniteDistribution(Vector(Weighted(A, 0.01), Weighted(B, 0.99))),
    Vector(),
    FiniteDistribution(Vector()),
    FiniteDistribution(Vector()),
    Empty
  ),
  TermGenParams(
    0.1,
    0.1,
    0.1,
    0.0,
    0.0,
    0.05,
    0.05,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.3,
    0.7,
    0.5,
    0.0,
    0.0,
    0.0
  ),
  1.0E-4,
  12 minutes,
  1.01,
  1.0,
  10000,
  10,
  0.1,
  1.0
)
In [30]:
lp6.tunedGenerators.runToFuture
In [31]:
val ts1 = TermState(FiniteDistribution.unif(a, f), FiniteDistribution(A -> 0.05, B -> 0.95))
val lp7 = LocalProver(ts1,  hW = 0.0001).noIsles
Out[31]:
ts1: TermState = TermState(
  FiniteDistribution(Vector(Weighted(a, 0.5), Weighted(f, 0.5))),
  FiniteDistribution(Vector(Weighted(A, 0.05), Weighted(B, 0.95))),
  Vector(),
  FiniteDistribution(Vector()),
  FiniteDistribution(Vector()),
  Empty
)
lp7: LocalProver = LocalProver(
  TermState(
    FiniteDistribution(Vector(Weighted(a, 0.5), Weighted(f, 0.5))),
    FiniteDistribution(Vector(Weighted(A, 0.05), Weighted(B, 0.95))),
    Vector(),
    FiniteDistribution(Vector()),
    FiniteDistribution(Vector()),
    Empty
  ),
  TermGenParams(
    0.1,
    0.1,
    0.1,
    0.0,
    0.0,
    0.05,
    0.05,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.3,
    0.7,
    0.5,
    0.0,
    0.0,
    0.0
  ),
  1.0E-4,
  12 minutes,
  1.01,
  1.0,
  10000,
  10,
  1.0E-4,
  1.0
)
In [32]:
lp7.tunedGenerators.runToFuture
In [33]:
lp7.expressionEval.map(_.initTerms).runToFuture
In [34]:
lp7.expressionEval.map(_.vars).runToFuture
In [35]:
val ts2 = TermState(FiniteDistribution.unif(a, f, f(a)), FiniteDistribution(A -> 0.01, B -> 0.99))
val lp8 = LocalProver(ts2,  hW = 0.0001).noIsles
Out[35]:
ts2: TermState = TermState(
  FiniteDistribution(
    Vector(
      Weighted(a, 0.3333333333333333),
      Weighted(f, 0.3333333333333333),
      Weighted(f(a), 0.3333333333333333)
    )
  ),
  FiniteDistribution(Vector(Weighted(A, 0.01), Weighted(B, 0.99))),
  Vector(),
  FiniteDistribution(Vector()),
  FiniteDistribution(Vector()),
  Empty
)
lp8: LocalProver = LocalProver(
  TermState(
    FiniteDistribution(
      Vector(
        Weighted(a, 0.3333333333333333),
        Weighted(f, 0.3333333333333333),
        Weighted(f(a), 0.3333333333333333)
      )
    ),
    FiniteDistribution(Vector(Weighted(A, 0.01), Weighted(B, 0.99))),
    Vector(),
    FiniteDistribution(Vector()),
    FiniteDistribution(Vector()),
    Empty
  ),
  TermGenParams(
    0.1,
    0.1,
    0.1,
    0.0,
    0.0,
    0.05,
    0.05,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.3,
    0.7,
    0.5,
    0.0,
    0.0,
    0.0
  ),
  1.0E-4,
  12 minutes,
  1.01,
  1.0,
...
In [36]:
lp8.tunedGenerators.runToFuture
In [37]:
val ts3 = TermState(FiniteDistribution.unif(a, f, f(a)), FiniteDistribution(A -> 0.05, B -> 0.95))
val lp9 = LocalProver(ts3,  hW = 0.0001).noIsles
val ts4 = TermState(FiniteDistribution.unif(a, f, f(a)), FiniteDistribution(A -> 0.1, B -> 0.9))
val lp10 = LocalProver(ts4,  hW = 0.0001).noIsles
Out[37]:
ts3: TermState = TermState(
  FiniteDistribution(
    Vector(
      Weighted(a, 0.3333333333333333),
      Weighted(f, 0.3333333333333333),
      Weighted(f(a), 0.3333333333333333)
    )
  ),
  FiniteDistribution(Vector(Weighted(A, 0.05), Weighted(B, 0.95))),
  Vector(),
  FiniteDistribution(Vector()),
  FiniteDistribution(Vector()),
  Empty
)
lp9: LocalProver = LocalProver(
  TermState(
    FiniteDistribution(
      Vector(
        Weighted(a, 0.3333333333333333),
        Weighted(f, 0.3333333333333333),
        Weighted(f(a), 0.3333333333333333)
      )
    ),
    FiniteDistribution(Vector(Weighted(A, 0.05), Weighted(B, 0.95))),
    Vector(),
    FiniteDistribution(Vector()),
    FiniteDistribution(Vector()),
    Empty
  ),
  TermGenParams(
    0.1,
    0.1,
    0.1,
    0.0,
    0.0,
    0.05,
    0.05,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.3,
    0.7,
    0.5,
    0.0,
    0.0,
    0.0
  ),
  1.0E-4,
  12 minutes,
  1.01,
  1.0,
...
ts4: TermState = TermState(
  FiniteDistribution(
    Vector(
      Weighted(a, 0.3333333333333333),
      Weighted(f, 0.3333333333333333),
      Weighted(f(a), 0.3333333333333333)
    )
  ),
  FiniteDistribution(Vector(Weighted(A, 0.1), Weighted(B, 0.9))),
  Vector(),
  FiniteDistribution(Vector()),
  FiniteDistribution(Vector()),
  Empty
)
lp10: LocalProver = LocalProver(
  TermState(
    FiniteDistribution(
      Vector(
        Weighted(a, 0.3333333333333333),
        Weighted(f, 0.3333333333333333),
        Weighted(f(a), 0.3333333333333333)
      )
    ),
    FiniteDistribution(Vector(Weighted(A, 0.1), Weighted(B, 0.9))),
    Vector(),
    FiniteDistribution(Vector()),
    FiniteDistribution(Vector()),
    Empty
  ),
  TermGenParams(
    0.1,
    0.1,
    0.1,
    0.0,
    0.0,
    0.05,
    0.05,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.3,
    0.7,
    0.5,
    0.0,
    0.0,
    0.0
  ),
  1.0E-4,
  12 minutes,
  1.01,
  1.0,
...
In [38]:
lp9.tunedGenerators.runToFuture
lp10.tunedGenerators.runToFuture
In [39]:
val lp11 = LocalProver(ts2,  hW = 0.01).noIsles
Out[39]:
lp11: LocalProver = LocalProver(
  TermState(
    FiniteDistribution(
      Vector(
        Weighted(a, 0.3333333333333333),
        Weighted(f, 0.3333333333333333),
        Weighted(f(a), 0.3333333333333333)
      )
    ),
    FiniteDistribution(Vector(Weighted(A, 0.01), Weighted(B, 0.99))),
    Vector(),
    FiniteDistribution(Vector()),
    FiniteDistribution(Vector()),
    Empty
  ),
  TermGenParams(
    0.1,
    0.1,
    0.1,
    0.0,
    0.0,
    0.05,
    0.05,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.3,
    0.7,
    0.5,
    0.0,
    0.0,
    0.0
  ),
  1.0E-4,
  12 minutes,
  1.01,
  1.0,
...
In [40]:
lp11.tunedGenerators.runToFuture
In [41]:
ts2
Out[41]:
res40: TermState = TermState(
  FiniteDistribution(
    Vector(
      Weighted(a, 0.3333333333333333),
      Weighted(f, 0.3333333333333333),
      Weighted(f(a), 0.3333333333333333)
    )
  ),
  FiniteDistribution(Vector(Weighted(A, 0.01), Weighted(B, 0.99))),
  Vector(),
  FiniteDistribution(Vector()),
  FiniteDistribution(Vector()),
  Empty
)
In [42]:
val lp12 = LocalProver(ts2,  hW = 0.00001, klW = 10).noIsles
Out[42]:
lp12: LocalProver = LocalProver(
  TermState(
    FiniteDistribution(
      Vector(
        Weighted(a, 0.3333333333333333),
        Weighted(f, 0.3333333333333333),
        Weighted(f(a), 0.3333333333333333)
      )
    ),
    FiniteDistribution(Vector(Weighted(A, 0.01), Weighted(B, 0.99))),
    Vector(),
    FiniteDistribution(Vector()),
    FiniteDistribution(Vector()),
    Empty
  ),
  TermGenParams(
    0.1,
    0.1,
    0.1,
    0.0,
    0.0,
    0.05,
    0.05,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.3,
    0.7,
    0.5,
    0.0,
    0.0,
    0.0
  ),
  1.0E-4,
  12 minutes,
  1.01,
  1.0,
...
In [43]:
lp12.tunedGenerators.runToFuture
In [44]:
lp12.nextState.runToFuture
In [45]:
lp12.tripleT.runToFuture
In [46]:
lp12.tripleTypT.runToFuture
In [47]:
val ts5 = TermState(FiniteDistribution.unif(a, f, f(a)), FiniteDistribution(A -> 0.001, B -> 0.999))
Out[47]:
ts5: TermState = TermState(
  FiniteDistribution(
    Vector(
      Weighted(a, 0.3333333333333333),
      Weighted(f, 0.3333333333333333),
      Weighted(f(a), 0.3333333333333333)
    )
  ),
  FiniteDistribution(Vector(Weighted(A, 0.001), Weighted(B, 0.999))),
  Vector(),
  FiniteDistribution(Vector()),
  FiniteDistribution(Vector()),
  Empty
)
In [48]:
val lp13 = LocalProver(ts5, hW = 0.0001, klW= 10).noIsles
Out[48]:
lp13: LocalProver = LocalProver(
  TermState(
    FiniteDistribution(
      Vector(
        Weighted(a, 0.3333333333333333),
        Weighted(f, 0.3333333333333333),
        Weighted(f(a), 0.3333333333333333)
      )
    ),
    FiniteDistribution(Vector(Weighted(A, 0.001), Weighted(B, 0.999))),
    Vector(),
    FiniteDistribution(Vector()),
    FiniteDistribution(Vector()),
    Empty
  ),
  TermGenParams(
    0.1,
    0.1,
    0.1,
    0.0,
    0.0,
    0.05,
    0.05,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.3,
    0.7,
    0.5,
    0.0,
    0.0,
    0.0
  ),
  1.0E-4,
  12 minutes,
  1.01,
  1.0,
...
In [49]:
lp13.tunedGenerators.runToFuture
In [50]:
val ts6 = TermState(FiniteDistribution.unif(a, f, f(a)), FiniteDistribution(A -> 0.0001, B -> 0.9999))
val lp14 = LocalProver(ts6, hW = 0.0001, klW= 10).noIsles
Out[50]:
ts6: TermState = TermState(
  FiniteDistribution(
    Vector(
      Weighted(a, 0.3333333333333333),
      Weighted(f, 0.3333333333333333),
      Weighted(f(a), 0.3333333333333333)
    )
  ),
  FiniteDistribution(Vector(Weighted(A, 1.0E-4), Weighted(B, 0.9999))),
  Vector(),
  FiniteDistribution(Vector()),
  FiniteDistribution(Vector()),
  Empty
)
lp14: LocalProver = LocalProver(
  TermState(
    FiniteDistribution(
      Vector(
        Weighted(a, 0.3333333333333333),
        Weighted(f, 0.3333333333333333),
        Weighted(f(a), 0.3333333333333333)
      )
    ),
    FiniteDistribution(Vector(Weighted(A, 1.0E-4), Weighted(B, 0.9999))),
    Vector(),
    FiniteDistribution(Vector()),
    FiniteDistribution(Vector()),
    Empty
  ),
  TermGenParams(
    0.1,
    0.1,
    0.1,
    0.0,
    0.0,
    0.05,
    0.05,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.3,
    0.7,
    0.5,
    0.0,
    0.0,
    0.0
  ),
  1.0E-4,
  12 minutes,
  1.01,
  1.0,
...
In [51]:
lp14.tunedGenerators.runToFuture

Conclusions

After experimentation with the rather simple generation, we find

  • qualitatively stuff works, so seems to not have bugs
  • however perhaps because of logarithmic scaling, it takes surprising effort to get changes: specifically to have f(a) in the generating set.
In [52]:
lp14.expressionEval.map(_.finalDist).runToFuture
In [53]:
import GeneratorVariables._, Expression._, TermRandomVars._
lp14.expressionEval.map(_.finalDist(FinalVal(Elem(f(a), Terms)))).runToFuture
In [54]:
lp14.expressionEval.map(_.entropy(0.0001, 10)).runToFuture
In [56]:
val epT = for {
    ev <- lp14.expressionEval
    q = ev.finalDist
    entp <- ev.WithP(q).entropyProjectionTask(lp14.hW, lp14.klW)
} yield entp
Out[56]:
epT: monix.eval.Task[Vector[Double]] = FlatMap(
  Map(
    Async(<function2>, false, true, true),
    ammonite.$sess.cmd55$Helper$$Lambda$3730/1927048972@4966d36a,
    0
  ),
  ammonite.$sess.cmd55$Helper$$Lambda$3731/1848353081@d29c2ee
)
In [59]:
val epF = epT.runToFuture
In [60]:
val entT = for {
    ev <- lp14.expressionEval
    q = ev.finalDist
    der <- ev.WithP(q).jetTask(ev.entropy(lp14.hW, lp14.klW))
} yield der
Out[60]:
entT: monix.eval.Task[spire.math.Jet[Double]] = FlatMap(
  Map(
    Async(<function2>, false, true, true),
    ammonite.$sess.cmd59$Helper$$Lambda$3757/374477152@d937b1a,
    0
  ),
  ammonite.$sess.cmd59$Helper$$Lambda$3758/1137030304@22abf70c
)
In [61]:
val entF = entT.runToFuture
In [62]:
val varT = for {
    ev <- lp14.expressionEval
    vs = ev.vars
} yield vs
Out[62]:
varT: monix.eval.Task[Vector[Expression]] = Map(
  Async(<function2>, false, true, true),
  scala.Function1$$Lambda$275/1928301845@48647e19,
  1
)
In [63]:
val varsF = varT.runToFuture
In [68]:
val klT0 = for {
    ev <- lp14.expressionEval
    q = ev.finalDist
    vs = ev.vars
    der <- ev.WithP(q).jetTask(ev.entropy(0, 1))
} yield der.infinitesimal.toVector.zip(vs)
Out[68]:
klT0: monix.eval.Task[Vector[(Double, Expression)]] = FlatMap(
  Map(
    Async(<function2>, false, true, true),
    ammonite.$sess.cmd67$Helper$$Lambda$3819/1270999907@423e2c4c,
    0
  ),
  ammonite.$sess.cmd67$Helper$$Lambda$3820/1258644324@1c4c4968
)
In [69]:
val klF0 = klT0.runToFuture
In [77]:
val entT0 = for {
    ev <- lp14.expressionEval
    q = ev.finalDist
    vs = ev.vars
    der <- ev.WithP(q).jetTask(ev.entropy(1, 0))
} yield der.infinitesimal.toVector.zip(vs)
Out[77]:
entT0: monix.eval.Task[Vector[(Double, Expression)]] = FlatMap(
  Map(
    Async(<function2>, false, true, true),
    ammonite.$sess.cmd76$Helper$$Lambda$3887/1263669105@75c4f276,
    0
  ),
  ammonite.$sess.cmd76$Helper$$Lambda$3888/1106007152@463b20c7
)
In [78]:
val entF0 = entT0.runToFuture
In [72]:
lp14.expressionEval.map(_.klExp).runToFuture
In [84]:
val shT = for {
    ev <- lp14.expressionEval
    q = ev.finalDist
    vs = ev.vars
    der <- ev.WithP(q).jetTask(ev.entropy(0, 1))
    gs = ev.gradShift(q, der.infinitesimal.toVector, 1).toVector.collect{case (k, v) if q(k) != v   => (k, q(k), v)}
} yield gs
Out[84]:
shT: monix.eval.Task[Vector[(Expression, Double, Double)]] = FlatMap(
  Map(
    Async(<function2>, false, true, true),
    ammonite.$sess.cmd83$Helper$$Lambda$4028/872933634@29ee3614,
    0
  ),
  ammonite.$sess.cmd83$Helper$$Lambda$4029/652523674@2f9bb5e1
)
In [85]:
val shF = shT.runToFuture

We note that the entropy shift increases the final value of the probability of f(a), as it should be. Next we check directly for the generator iterant, but in this case initially.

In [91]:
val probT = for {
    ev <- lp14.expressionEval
    prob <- ev.generatorIterant(0, 1, 0.000001, ev.finalDist).map(_(f(a))).take(20).toListL
} yield prob
Out[91]:
probT: monix.eval.Task[List[Double]] = FlatMap(
  Async(<function2>, false, true, true),
  ammonite.$sess.cmd90$Helper$$Lambda$4081/1982913167@232b117f
)
In [92]:
val probF = probT.runToFuture
In [93]:
val pshT = for {
    ev <- lp14.expressionEval
    q = ev.finalDist
    vs = ev.vars
    der <- ev.WithP(q).entropyProjectionTask(0, 1)
    gs = ev.gradShift(q, der, 1).toVector.collect{case (k, v) if q(k) != v   => (k, q(k), v)}
} yield gs
Out[93]:
pshT: monix.eval.Task[Vector[(Expression, Double, Double)]] = FlatMap(
  Map(
    Async(<function2>, false, true, true),
    ammonite.$sess.cmd92$Helper$$Lambda$4105/831437506@5b27c107,
    0
  ),
  ammonite.$sess.cmd92$Helper$$Lambda$4106/255065230@1b95d47e
)
In [94]:
val pshF = pshT.runToFuture
In [97]:
val prstshT = for {
    ev <- lp14.expressionEval
    q = ev.finalDist
    vs = ev.vars
    der <- ev.WithP(q).entropyProjectionTask(0, 1)
    gs = ev.stableGradShift(q, der, 1).toVector.collect{case (k @ InitialVal(Elem(_, Terms)), v) if q(k) != v   => (k, q(k), v)}
} yield gs
Out[97]:
prstshT: monix.eval.Task[Vector[(InitialVal[Any], Double, Double)]] = FlatMap(
  Map(
    Async(<function2>, false, true, true),
    ammonite.$sess.cmd96$Helper$$Lambda$4154/1771170652@20608417,
    0
  ),
  ammonite.$sess.cmd96$Helper$$Lambda$4155/1792142115@60fcba35
)
In [98]:
val prstshF = prstshT.runToFuture
In [99]:
import ExpressionEval._
Out[99]:
import ExpressionEval._
In [100]:
val ev14 = lp14.expressionEval
Out[100]:
ev14: monix.eval.Task[ExpressionEval] = Async(<function2>, false, true, true)
In [101]:
val gT = ev14.map(e => generators(e.finalDist))
val gF = gT.runToFuture
In [113]:
val gT = ev14.flatMap(e => e.generatorIterant(0, 1, 0.000001, e.finalDist).take(20).toListL)
Out[113]:
gT: monix.eval.Task[List[FiniteDistribution[Term]]] = FlatMap(
  Async(<function2>, false, true, true),
  ammonite.$sess.cmd112$Helper$$Lambda$4241/1657741802@67d07157
)
In [114]:
val gF = gT.runToFuture

Debug this:

This is not expected behaviour: one would expect the weight of f(a) to rise. Instead it rises for one step and then starts sinking. Should start with a clean notebook and track this down.

In [122]:
val lp0 = LocalProver(TermState(FiniteDistribution.unif(a, f(a), f), FiniteDistribution(A -> 0.01, B -> 0.99)), hW = 0, klW = 10).noIsles
Out[122]:
lp0: LocalProver = LocalProver(
  TermState(
    FiniteDistribution(
      Vector(
        Weighted(a, 0.3333333333333333),
        Weighted(f(a), 0.3333333333333333),
        Weighted(f, 0.3333333333333333)
      )
    ),
    FiniteDistribution(Vector(Weighted(A, 0.01), Weighted(B, 0.99))),
    Vector(),
    FiniteDistribution(Vector()),
    FiniteDistribution(Vector()),
    Empty
  ),
  TermGenParams(
    0.1,
    0.1,
    0.1,
    0.0,
    0.0,
    0.05,
    0.05,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.3,
    0.7,
    0.5,
    0.0,
    0.0,
    0.0
  ),
  1.0E-4,
  12 minutes,
  1.01,
  1.0,
...
In [125]:
val gT0 = lp0.expressionEval.flatMap(e => e.generatorIterant(0, 1, 0.000001, e.finalDist).take(100).toListL.map(_.zipWithIndex.filter(_._2 % 15 == 0)) )
Out[125]:
gT0: monix.eval.Task[List[(FiniteDistribution[Term], Int)]] = FlatMap(
  Async(<function2>, false, true, true),
  ammonite.$sess.cmd124$Helper$$Lambda$4309/1555064469@cfdaac4
)
In [126]:
val gF0 = gT0.runToFuture

Correction needed

  • One can always reduce Kullback-Liebler by increasing all probabilities. Normalizing only partly acts against this.
  • The best approach is probably to add total probability equations, at least for initial and final values of terms.