Skip to main content

Double Well (DoubleWell-v0)

The Double Well environment models a two-dimensional stochastic dynamical system on a double-well potential landscape. The control task is to drive the state to the origin despite additive state-dependent noise and the bi-stable potential.

Dynamics​

The continuous-time drift is

x˙1=4x1−4x13+ux˙2=−2x2+u\begin{aligned} \dot{x}_1 &= 4 x_1 - 4 x_1^3 + u \\ \dot{x}_2 &= -2 x_2 + u \end{aligned}

with additive stochastic diffusion:

dx=f(x,u) dt+σ(x) dWdx = f(x, u)\,dt + \sigma(x)\,dW

where σ(x)=(0.7x100.5)\sigma(x) = \begin{pmatrix} 0.7 & x_1 \\ 0 & 0.5 \end{pmatrix} and WW is a Wiener process. Integration uses the Euler–Maruyama scheme with Δt=0.01 s\Delta t = 0.01\,\text{s}.

Potential surface​

The uncontrolled potential is

V(x1,x2)=(x12−1)2+x22V(x_1, x_2) = (x_1^2 - 1)^2 + x_2^2

This has two stable wells at (±1,0)(\pm 1, 0) and a saddle at the origin. The control objective is to hold the state at the origin, which is an unstable equilibrium of the uncontrolled system.

Spaces and limits​

PropertyValue
State dimension2
Action dimension1
State range[−2,2]2[-2, 2]^2
Action range[−25,25][-25, 25]
Δt\Delta t0.01 s
Max episode steps2000 (20 s)

Cost function​

c(x,u)=x⊤Qx+u⊤Ru,Q=I2,R=I1c(x, u) = x^\top Q x + u^\top R u, \qquad Q = I_2, \quad R = I_1

Reference point: x∗=0x^* = \mathbf{0}.

Observation note​

During trajectory generation, Generator appends the potential V(x)V(x) as a third component, producing a 3-dimensional observation (x1,x2,V(x1,x2))(x_1, x_2, V(x_1, x_2)). The visualisation pipeline uses (x1,x2)(x_1, x_2) as the horizontal plane and VV as the vertical axis.

LQR linearisation​

Alin=(−800−2),Blin=(11)A_{\text{lin}} = \begin{pmatrix} -8 & 0 \\ 0 & -2 \end{pmatrix}, \qquad B_{\text{lin}} = \begin{pmatrix} 1 \\ 1 \end{pmatrix}

Usage​

uv run -m koopmanrl.soft_koopman_value_iteration --env_id DoubleWell-v0
uv run -m koopmanrl.soft_actor_koopman_critic \
--config_file configurations/sakc_double_well_hparams.json

Notes​

  • The stochastic diffusion σ(x)\sigma(x) is state-dependent: the off-diagonal term σ12=x1\sigma_{12} = x_1 couples noise into both state components.
  • Trajectories draw from pre-generated random numbers for efficiency; a fixed seed must be set before environment construction for fully reproducible rollouts.
  • Source: koopmanrl/environments/double_well.py