circuits-rl
Safe HaskellNone
LanguageGHC2024

Circuit.RL.Estimator

Description

Policy-gradient estimator axes for the REINFORCE == pathwise oracle.

The instance table (loom/instance-table.md §1) names two estimator axes:

  • REINFORCE (score-function): Prob (->) (Dual r) — the continuation carries a gradient component that accumulates via the dual-number product rule: (v,g)·(v',g') = (v·v', v·g' + g·v'). The log-policy score function injects gradient-weighted-by-reward exactly when the continuation multiplies by a score morphism.
  • Pathwise (reparametrization): the derivative is taken through the sample a = θ + σε, so ∂R∂θ = ∂R∂a · 1.

The oracle is: on a 1-step Gaussian policy N(θ, σ²=0.25) with quadratic reward R(a) = -(a-1)², both estimators analytically reduce to ∇J = -2(θ-1). At θ₀=3 this is -4 — exact in Double.

Synopsis

Dual scalar for score-function gradient accumulation

newtype Dual a Source #

Dual-number scalar: value plus accumulated gradient.

Multiplication follows the dual-number product rule: the gradient component records the cross-derivative. This naturally gives the REINFORCE coupling: when a continuation multiplies a downstream reward (value component) by a score function (gradient component), the result records the reward-weighted score.

>>> Dual (2, 3) * Dual (5, 7)
Dual (10, 29)

Check: 2·5 = 10, 2·7 + 3·5 = 14+15 = 29 ✓

Constructors

Dual 

Fields

Instances

Instances details
Eq a => Eq (Dual a) Source # 
Instance details

Defined in Circuit.RL.Estimator

Methods

(==) :: Dual a -> Dual a -> Bool #

(/=) :: Dual a -> Dual a -> Bool #

Num a => Num (Dual a) Source # 
Instance details

Defined in Circuit.RL.Estimator

Methods

(+) :: Dual a -> Dual a -> Dual a #

(-) :: Dual a -> Dual a -> Dual a #

(*) :: Dual a -> Dual a -> Dual a #

negate :: Dual a -> Dual a #

abs :: Dual a -> Dual a #

signum :: Dual a -> Dual a #

fromInteger :: Integer -> Dual a #

Fractional a => Fractional (Dual a) Source # 
Instance details

Defined in Circuit.RL.Estimator

Methods

(/) :: Dual a -> Dual a -> Dual a #

recip :: Dual a -> Dual a #

fromRational :: Rational -> Dual a #

Show a => Show (Dual a) Source # 
Instance details

Defined in Circuit.RL.Estimator

Methods

showsPrec :: Int -> Dual a -> ShowS #

show :: Dual a -> String #

showList :: [Dual a] -> ShowS #

Estimators

reinforceGrad :: Double -> Double -> Double -> Double Source #

REINFORCE (score-function) gradient estimator for Gaussian policy.

∇J = E[R(a) · ∇_θ log π(a)] where ∇_θ log π(a) = (a-θ)/σ².

The analytical expectation uses Gaussian central moments. Let z = a-θ, δ = θ-a_target:

  R(a) = -(a - a_target)² = -(z+δ)²
  R(a)(a-θ)σ² = -(z+δ)²·zσ² = -(z³ + 2δz² + δ²z)/σ²
  E[R(a)(a-θ)σ²] = -(1σ²)(E[z³] + 2δ·E[z²] + δ²·E[z])
                  = -(1/σ²)(0 + 2δσ² + 0) = -2δ
                  = -2(θ-a_target)
>>> reinforceGrad 3.0 0.5 1.0
-4.0

pathwiseGrad :: Double -> Double -> Double -> Double Source #

Pathwise (reparametrization) gradient estimator for Gaussian policy.

a = θ + σε with ε ~ N(0,1). ∂R∂θ = ∂R∂a · ∂a/∂θ = -2(a - a_target) · 1 = -2(θ+σε-a_target). E[∂R/∂θ] = -2(θ-a_target) since E[ε] = 0.

>>> pathwiseGrad 3.0 0.5 1.0
-4.0

closedFormGrad :: Double -> Double -> Double -> Double Source #

Closed-form gradient for Gaussian policy N(θ, σ²) with quadratic reward R(a) = -(a - a_target)².

J(θ) = E[R(a)] = -(σ² + (θ - a_target)²), so ∇J = -2(θ - a_target).

>>> closedFormGrad 3.0 0.5 1.0
-4.0