def energy_mode(A, b, m, S, sDyn): """ ENERGY MODE [Description] Energy for the double-well SDE, and related quantities (including gradients). [Input] A : variational linear parameters (N x 1). b : variational offset parameters (N x 1). m : narginal means (N x 1). S : marginal variances (N x 1). sDyn : structure containing additional parameters. [Output] Esde : total energy of the sde. Ef : average drift (N x 1). Edf : average differentiated drift (N x 1). dEsde_dm : gradient of Esde w.r.t. the means (N x 1). dEsde_dS : gradient of Esde w.r.t. the covariance (N x 1). dEsde_dth : gradient of Esde w.r.t. the parameter theta. dEsde_dSig: gradient of Esde w.r.t. the parameter Sigma. NOTE: The equation numbers correspond to the paper: @CONFERENCE{Archambeau2007b, author = {Cedric Archambeau, Manfred Opper, Yuan Shen, Dan Cornford and J. Shawe-Taylor},title = {Variational Inference for Diffusion Processes}, booktitle = {Annual Conference on Neural Information Processing Systems}, year = {2007} } Copyright (c) Michail D. Vrettas, PhD - November 2015. Last Updated: November 2015. """ # Find the time step. dt = sDyn['dt'] # Extract the drift parameter. theta = sDyn['theta'] # Inverse noise variance. SigInv = 1.0 / sDyn['Sig'] # Observation times. idx = sDyn['obsX'] # Higher order Gaussian Moments. Ex2 = momGauss(m, S, 2) # Precompute these quantities only once. Q1 = (theta - A)**2 Q2 = A * b # Energy from the sDyn: Eq(7) varQ = Ex2 * Q1 + 2 * m * (theta - A) * b + b**2 Esde = 0.5 * SigInv * mytrapz(varQ, dt, idx) # Average drift. Ef = -theta * m # Average gradient of drift. Edf = -theta * np.ones(m.shape) # Gradients of Esde w.r.t. 'm' and 'S'. dEsde_dm = SigInv * (m * (theta - A)**2 + theta * b - Q2) dEsde_dS = 0.5 * SigInv * Q1 # Gradients of Esde w.r.t. 'Theta'. dEsde_dth = SigInv * mytrapz(Ex2 * (theta - A) + m * b, dt, idx) # Gradients of Esde w.r.t. 'Sigma'. dEsde_dSig = -SigInv * Esde # ---> return Esde, Ef, Edf, dEsde_dm, dEsde_dS, dEsde_dth, dEsde_dSig
def energy_mode(A, b, m, S, sDyn): """ ENERGY MODE: [Description] Energy for the stocastic Lorenz 63 DE (3 dimensional) and related quantities (including gradients). [Input] A : variational linear parameters (N x D x D). b : variational offset parameters (N x D). m : narginal means (N x D). S : marginal variances (N x D x D). sDyn : structure containing additional parameters. [Output] Esde : total energy of the sde. Ef : average drift (N x D). Edf : average differentiated drift (N x D). dEsde_dm : gradient of Esde w.r.t. the means (N x D). dEsde_dS : gradient of Esde w.r.t. the covariance (N x D x D). dEsde_dth : gradient of Esde w.r.t. the parameter theta. dEsde_dSig: gradient of Esde w.r.t. the parameter Sigma. NOTE: The equation numbers correspond to the paper: @CONFERENCE{Archambeau2007b, author = {Cedric Archambeau and Manfred Opper and Yuan Shen and Dan Cornford and J. Shawe-Taylor}, title = {Variational Inference for Diffusion Processes}, booktitle = {Annual Conference on Neural Information Processing Systems}, year = {2007} } Copyright (c) Michail D. Vrettas, PhD - November 2015. Last Updated: November 2015. """ # {N}umber of discretised points N = sDyn['N'] # Time discretiastion step. dt = sDyn['dt'] # Inverse System Noise. SigInv = np.linalg.inv(sDyn['Sig']) # Observation times. idx = sDyn['obsX'] # Diagonal elements of inverse Sigma. diagSigI = np.diag(SigInv) # Energy from the sde. Esde = np.zeros((N, 1), dtype='float64') # Average drift. Ef = np.zeros((N, 3), dtype='float64') # Average gradient of drift. Edf = np.zeros((N, 3, 3), dtype='float64') # Gradients of Esde w.r.t. 'm' and 'S'. dEsde_dm = np.zeros((N, 3), dtype='float64') dEsde_dS = np.zeros((N, 3, 3), dtype='float64') # Gradients of Esde w.r.t. 'Theta'. dEsde_dth = np.zeros((N, 3), dtype='float64') # Gradients of Esde w.r.t. 'Sigma'. dEsde_dSig = np.zeros((N, 3), dtype='float64') # Drift parameters. vS, vR, vB = sDyn['theta'] # Compute the quantities iteratively. for t in range(N): # Get the values at time 't'. At = A[t, :, :] bt = b[t, :] St = S[t, :, :] mt = m[t, :] # Compute the energy and the related gradients. Efg, Edm, EdS = Energy_dm_dS(At, bt, mt, St, diagSigI, sDyn) # Energy Esde(t): Esde[t] = 0.5 * diagSigI.dot(Efg) # Gradient dEsde(t)/dm(t): dEsde_dm[t, :] = Edm # Gradient dEsde(t)/dS(t): dEsde_dS[t, :, :] = EdS # Average drift: <f(Xt)> Ef[t,:] = np.array([(vS*(mt[1] - mt[0])),\ (vR*mt[0] - mt[1] - St[2,0] - mt[0]*mt[2]),\ (St[1,0] + mt[0]*mt[1] - vB*mt[2])]) # Average gradient of drift: <Df(Xt)> Edf[t,:,:] = np.array([[-vS, vS, 0], [(vR - mt[2]), -1, -mt[0]],\ [mt[1], mt[0], -vB]]) # Gradients of Esde w.r.t. 'Theta'. dEsde_dth[t, :] = Efg_drift_theta(At, bt, mt, St, sDyn) # Gradients of Esde w.r.t. 'Sigma'. dEsde_dSig[t, :] = Efg # ... # Compute energy using numerical integration. Esde = mytrapz(Esde, dt, idx) # Final adjustments for the (hyper)-parameters. dEsde_dth = diagSigI * mytrapz(dEsde_dth, dt, idx) # Final adjustments for the System noise. dEsde_dSig = -0.5 * SigInv.dot(np.diag(mytrapz(dEsde_dSig, dt, idx))).dot(SigInv) # ---> return Esde, Ef, Edf, dEsde_dm, dEsde_dS, dEsde_dth, dEsde_dSig
def energy_mode(A, b, m, S, sDyn): """ ENERGY MODE [Description] Energy for the double-well SDE and related quantities (including gradients). [Input] A : variational linear parameters (N x 1). b : variational offset parameters (N x 1). m : narginal means (N x 1). S : marginal variances (N x 1). sDyn : structure containing additional parameters. [Output] Esde : total energy of the sde. Ef : average drift (N x 1). Edf : average differentiated drift (N x 1). dEsde_dm : gradient of Esde w.r.t. the means (N x 1). dEsde_dS : gradient of Esde w.r.t. the covariance (N x 1). dEsde_dth : gradient of Esde w.r.t. the parameter theta. dEsde_dSig: gradient of Esde w.r.t. the parameter Sigma. NOTE: The equation numbers correspond to the paper: @CONFERENCE{Archambeau2007b, author = {Cedric Archambeau and Manfred Opper and Yuan Shen and Dan Cornford and J. Shawe-Taylor}, title = {Variational Inference for Diffusion Processes}, booktitle = {Annual Conference on Neural Information Processing Systems}, year = {2007} } Copyright (c) Michail D. Vrettas, PhD - November 2015. Last Updated: November 2015. """ # Find the time step. dt = sDyn['dt'] # Extract the drift parameter. theta = sDyn['theta'] # Observation times. idx = sDyn['obsX'] # Constant value. c = 4.0 * theta + A # Auxiliary constant. c2 = c**2 # Iverse of noise variance. SigInv = 1.0 / sDyn['Sig'] # Higher order Gaussian Moments. Ex2 = momGauss(m, S, 2) Ex3 = momGauss(m, S, 3) Ex4 = momGauss(m, S, 4) Ex6 = momGauss(m, S, 6) # Energy from the sDyn: Eq(7) varQ = 16.0 * Ex6 - 8.0 * c * Ex4 + 8.0 * b * Ex3 + c2 * Ex2 - 2.0 * b * c * m + b**2 Esde = 0.5 * SigInv * mytrapz(varQ, dt, idx) # Average drift {i.e. Eq(20) : f(t,x) = 4*x*(theta -x^2) }. Ef = 4.0 * (theta * m - Ex3) # Average gradient of drift {i.e df(t,x)_dx = 4*theta - 12*x^2}. Edf = 4.0 * (theta - 3 * Ex2) # Derivatives of higher order Gaussian moments w.r.t. 'm' and 'S'. Dm2 = momGauss(m, S, 2, 'Dm') DS2 = momGauss(m, S, 2, 'DS') # --- Dm3 = momGauss(m, S, 3, 'Dm') DS3 = momGauss(m, S, 3, 'DS') # --- Dm4 = momGauss(m, S, 4, 'Dm') DS4 = momGauss(m, S, 4, 'DS') # --- Dm6 = momGauss(m, S, 6, 'Dm') DS6 = momGauss(m, S, 6, 'DS') # Gradients of Esde w.r.t. 'm' and 'S'. dEsde_dm = 0.5 * SigInv * (16.0 * Dm6 - 8.0 * c * Dm4 + 8.0 * b * Dm3 + c2 * Dm2 - 2.0 * b * c) dEsde_dS = 0.5 * SigInv * (16.0 * DS6 - 8.0 * c * DS4 + 8.0 * b * DS3 + c2 * DS2) # Gradients of Esde w.r.t. 'Theta'. dEsde_dth = 4.0 * SigInv * mytrapz(c * Ex2 - 4.0 * Ex4 - b * m, dt, idx) # Gradients of Esde w.r.t. 'Sigma'. dEsde_dSig = -Esde * SigInv # ---> return Esde, Ef, Edf, dEsde_dm, dEsde_dS, dEsde_dth, dEsde_dSig