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: A \to B$. 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.