def expectedEmissionStats( self, t, ys, alphas, betas, conditionOnY=True ): # E[ x_t * x_t^T ], E[ y_t * x_t^T ] and E[ y_t * y_t^T ] # Find the expected sufficient statistic for N( y_t, x_t | Y ) J_x, h_x, _ = np.add( alphas[ t ], betas[ t ] ) if( conditionOnY == False ): J11 = self.J1Emiss J12 = -self._hy J22 = self.Jy + J_x D = J11.shape[ 0 ] J = np.block( [ [ J11, J12 ], [ J12.T, J22 ] ] ) h = np.hstack( ( np.zeros( D ), h_x ) ) # This is a block matrix with block E[ y_t * y_t^T ], E[ y_t * x_t^T ] # and E[ x_t * x_t^T ] E, _ = Normal.expectedSufficientStats( nat_params=( -0.5 * J, h ) ) Eyt_yt, Eyt_xt, Ext_xt = toBlocks( E, D ) else: Ext_xt, E_xt = Normal.expectedSufficientStats( nat_params=( -0.5 * J_x, h_x ) ) Eyt_yt = np.einsum( 'mi,mj->ij', ys[ :, t ], ys[ :, t ] ) Eyt_xt = np.einsum( 'mi,j->ij', ys[ :, t ], E_xt ) return Eyt_yt, Eyt_xt, Ext_xt
def Jv(self, X): self.draw_sample() mat_lin = self.C_perturbed mat = np.block([[np.zeros([self.d, self.d]), mat_lin], [-mat_lin.T, np.zeros([self.d, self.d])]]) noise = np.random.randn(2 * self.d) * self.sigma return mat, mat @ X + noise
def func7(x): Q1 = np.array([[12,8,7,6], [8,12,8,7], [7,8,12,8], [6,7,8,12], ]) Q2 = np.array([[3,2,1,0], [2,3,2,1], [1,2,3,2], [0,1,2,3], ]) Q3 = np.array([[2,1,0,0], [1,2,1,0], [0,1,2,1], [0,0,1,2], ]) Q4 = np.eye(4) Q = np.block([[Q1,Q2,Q3,Q4], [Q2,Q1,Q2,Q3], [Q3,Q2,Q1,Q2], [Q4,Q3,Q2,Q1], ]) b = -np.array([1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0]) xLen = np.shape(x)[0] qLen = np.shape(Q)[1] assert xLen == qLen, "Input should be a vector of length {}, received".format(qLen, xLen) a = 0.5*(np.transpose(x) @ Q @ x) c = + b @ x return a + c
def _rmsprop_filtered(g, x, callback=None, num_iters=200, alpha=lambda t: 0.1, gamma=lambda t: 0.9, eps=1e-8, sigma_Q=0.01, sigma_R=2.0): """ Implements the Kalman RMSProp algorithm from https://arxiv.org/pdf/1810.12273.pdf. """ # Initialize the Kalman filter N = len(x) dx = g(x) r = np.ones(len(x)) #should be ones. z_0 = np.hstack([r, x, dx]).reshape(3 * N, 1) Q = sigma_Q * np.eye(3 * N) #dynamics noise R = sigma_R * np.eye(N) #observation noise C = np.hstack([np.zeros((N, 2 * N)), np.eye(N)]) kf = Kalman(init_state=z_0, init_cov=np.eye(3 * N) * 0.01, C_t=C, Q_t=Q, R_t=R) for t in range(num_iters): # evaluate the gradient dx = g(x) #construct transition matrix beta_t = alpha(t) / np.sqrt((gamma(t) * r + (1 - gamma(t)) * (dx**2)) + eps) A_t = np.block([[ np.eye(N) * gamma(t), np.zeros((N, N)), (1 - gamma(t)) * np.diag(dx) ], [np.zeros((N, N)), np.eye(N), -beta_t * np.eye(N)], [np.zeros((N, N)), np.zeros((N, N)), np.eye(N)]]) #increment the kalman filter z_hat = kf.filter(dx.T.reshape(N, 1), A_t=A_t) r_hat, x_hat, dx_hat = z_hat[:N], z_hat[N:2 * N], z_hat[2 * N:] #perform the Kalman RMSProp update r = gamma(t) * r + (1 - gamma(t)) * dx_hat.flatten()**2 x += -alpha(t) / (np.sqrt(r) + eps) * dx_hat.flatten() if callback: callback(x, t, dx_hat.reshape(x.shape)) return x
def _momgd_filtered(g, x, callback=None, num_iters=200, alpha=lambda t: 0.1, mu=lambda t: 0.9, sigma_Q=0.01, sigma_R=2.0): """ Implements the Kalman Gradient Descent + momentum algorithm from https://arxiv.org/pdf/1810.12273.pdf. """ # Initialize the Kalman filter N = len(x) dx = g(x) v = np.zeros(len(x)) z_0 = np.hstack([v, x, dx]).reshape(3 * N, 1) Q = sigma_Q * np.eye(3 * N) #dynamics noise R = sigma_R * np.eye(N) #observation noise C = np.hstack([np.zeros((N, 2 * N)), np.eye(N)]) kf = Kalman(init_state=z_0, init_cov=np.eye(3 * N) * 0.01, C_t=C, Q_t=Q, R_t=R) for t in range(num_iters): # evaluate the gradient dx = g(x) #construct transition matrix A_t = np.block( [[np.eye(N) * mu(t), np.zeros((N, N)), (1 - mu(t)) * np.eye(N)], [ -alpha(t) * np.eye(N), np.eye(N), -alpha(t) * (1 - mu(t)) * np.eye(N) ], [np.zeros((N, N)), np.zeros((N, N)), np.eye(N)]]) #increment the kalman filter z_hat = kf.filter(dx.T.reshape(N, 1), A_t=A_t) v_hat, x_hat, dx_hat = z_hat[:N], z_hat[N:2 * N], z_hat[2 * N:] if callback: callback(x, t, dx_hat.reshape(x.shape)) #perform the KGD + momentum update v = mu(t) * v - (1 - mu(t)) * dx_hat.flatten( ) #don't flatte, use .reshpape(x.shape) x += alpha(t) * v return x
def setup_CPn_cost(D, n): """Cost using chordal metric on CPn.""" i_mtx = np.block([ [np.zeros((n, n)), -np.eye(n)], [np.eye(n), np.zeros((n, n))] ]) A = np.ones(D.shape) C = A - D def cost(X): F = np.linalg.norm((X.T @ X)**2 + (X.T @ (i_mtx@X))**2 - C)**2 return F return cost
def toJoint( cls, u=None, params=None, nat_params=None ): # Given the parameters for P( y | A, sigma, x, u ), # return the natural parameters for P( [ y, x ] | A, sigma, u ) assert ( params is None ) ^ ( nat_params is None ) n1, n2, n3 = nat_params if nat_params is not None else cls.standardToNat( *params ) _n1 = np.block( [ n1, 0.5 * n3.T ], [ 0.5 * n3, n2 ] ) if( u is None ): _n2 = np.zeros( n1.shape[ 0 ] ) else: _n2 = np.hstack( ( -2 * n1.dot( u ), -n3.dot( u ) ) ) return _n1, _n2
def step(self, x, dx, alpha=0.01, callback=None): N=self._N A_t=np.block( [[np.eye(N) , -alpha*np.eye(N)], # [np.zeros((N,N)) , 1-alpha*ddx]] [np.zeros((N,N)) , np.eye(N)]] ) z_hat = self.kf.filter(dx.T.reshape(N,1), A_t=A_t) x_hat, dx_hat=z_hat[:N], z_hat[N:] if callback: callback(x, t, dx_hat.reshape(x.shape)) # x+=-alpha*dx_hat.flatten() return x - alpha*dx_hat.flatten()
def expectedTransitionStatsBlock( self, t, alphas, betas, ys=None, u=None ): # E[ x_t * x_t^T ], E[ x_t+1 * x_t^T ] and E[ x_t+1 * x_t+1^T ] # Find the natural parameters for P( x_t+1, x_t | Y ) J11, J12, J22, h1, h2, _ = self.childParentJoint( t, alphas, betas, ys=ys, u=u ) J = np.block( [ [ J11, J12 ], [ J12.T, J22 ] ] ) h = np.hstack( ( h1, h2 ) ) # The first expected sufficient statistic for N( x_t+1, x_t | Y ) will # be a block matrix with blocks E[ x_t+1 * x_t+1^T ], E[ x_t+1 * x_t^T ] # and E[ x_t * x_t^T ] E, _ = Normal.expectedSufficientStats( nat_params=( -0.5 * J, h ) ) D = h1.shape[ 0 ] Ext1_xt1, Ext1_xt, Ext_xt = toBlocks( E, D ) return Ext1_xt1, Ext1_xt, Ext_xt
def step(self, x, dx, callback=None, alpha=0.01, gamma=0.9, eps=1e-8): r = self._r N = self._N beta_t= alpha / np.sqrt((gamma*r + (1-gamma)*(dx**2) + eps )) A_t=np.block( [[np.eye(N) * gamma , np.zeros((N,N)), (1-gamma)*np.diag(dx)], [np.zeros((N,N)), np.eye(N), -beta_t * np.eye(N)], [np.zeros((N,N)) , np.zeros((N,N)), np.eye(N)]] ) z_hat=self.kf.filter(dx.T.reshape(N,1), A_t=A_t) r_hat, x_hat, dx_hat=z_hat[:N], z_hat[N:2*N], z_hat[2*N:] r = gamma * r + (1-gamma)* dx_hat.flatten()**2 self._r = r return x - alpha/(np.sqrt(r) + eps) * dx_hat.flatten()
def __make_Gi_block__(self) -> np.ndarray: """ Makes a block matrix of the MIMO impdeance + position Returns ------- Gi_block : np.ndarray. """ omega = self.hydro.omega.values num_freq = len(omega) Zi = self.hydro.Zi.values num_modes = Zi.shape[2] elem = [[0] * num_modes for i in range(num_modes)] for idx_mode in range(num_modes): for jdx_mode in range(num_modes): elem[idx_mode][jdx_mode] = np.diag(np.concatenate(([self.hydro.hydrostatic_stiffness.values[idx_mode,jdx_mode]], 1j * omega*Zi[:,idx_mode,jdx_mode]))) Gi_block = sparse.dia_matrix(np.block(elem)) return Gi_block
def __make_Zi_block__(self) -> np.ndarray: """ Makes a block matrix of the MIMO impdeance Returns ------- Zi_block : np.ndarray. """ omega = self.hydro.omega.values num_freq = len(omega) Zi = self.hydro.Zi.values num_modes = Zi.shape[2] elem = [[0] * num_modes for i in range(num_modes)] for idx_mode in range(num_modes): for jdx_mode in range(num_modes): elem[idx_mode][jdx_mode] = np.diag(Zi[:,idx_mode,jdx_mode]) Zi_block = sparse.dia_matrix(np.block(elem)) return Zi_block
[3, 2, 1, 0], [2, 3, 2, 1], [1, 2, 3, 2], [0, 1, 2, 3], ]) Q3 = np.array([ [2, 1, 0, 0], [1, 2, 1, 0], [0, 1, 2, 1], [0, 0, 1, 2], ]) Q4 = np.eye(4) Q = np.block([ [Q1, Q2, Q3, Q4], [Q2, Q1, Q2, Q3], [Q3, Q2, Q1, Q2], [Q4, Q3, Q2, Q1], ]) b = -np.array([1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0]) xLen = 16 initialX = np.random.uniform(interval[0], interval[1], size=(xLen)) times = 5 deltaFSum = [] for _ in range(times): # Q 6.1 cd_alg = ConjugateGradient(function, initialX, interval=interval,
def reproduction(self, t, parameters, controls, solution): # effective reproduction number at time t # https://royalsocietypublishing.org/doi/pdf/10.1098/rsif.2009.0386 # The construction of next-generation matrices for compartmental epidemic models t_set = t number_time = len(t) if number_time == 1: t_set = [t] Rt = np.zeros(number_time) for n_t in range(number_time): t = t_set[n_t] q, tau, HFR, kappa, beta, delta, sigma, eta_I, eta_Q, mu, gamma_I, gamma_A, gamma_H, gamma_Q = parameters # alpha, q, tau, HFR, kappa, beta, delta, sigma, eta_I, eta_Q, mu, gamma_I, gamma_A, gamma_H, gamma_Q = controls # alpha, q, tau, HFR, kappa, beta, _, _, _, _, _, _, _, _, _ = controls alpha = self.interpolation(t, self.t_control, controls) # tau_p = self.interpolation(t - np.max(1./sigma), self.t_control, controls[2]) # tau_p = self.interpolation(t, self.t_control, controls[2]) # IHR = np.divide(kappa, np.max(kappa) + tau_p) IHR = kappa QHR = ewm(tau, IHR) pi = self.proportion2factor(IHR, eta_I, gamma_I) # transform the parameter in the vector format ones = np.ones(self.number_group) alpha, q, tau, pi, beta, delta, kappa, sigma, eta_I, eta_Q, mu, gamma_I, gamma_A, gamma_H, gamma_Q = \ ewm(alpha,ones), ewm(q,ones), ewm(tau,ones), ewm(pi,ones), ewm(beta,ones), ewm(delta,ones), ewm(kappa,ones), \ ewm(sigma,ones), ewm(eta_I,ones), ewm(eta_Q,ones), ewm(mu,ones), ewm(gamma_I,ones), ewm(gamma_A,ones), ewm(gamma_H,ones), ewm(gamma_Q,ones) # theta_I = 2 - tau # theta_A = 1 - tau theta_I = 1. - 0 * tau theta_A = 1. - 0 * tau delta = 1. + 0 * delta S = solution[n_t, :self.number_group] zeros = np.zeros((self.number_group, self.number_group)) ItoS = np.diag(beta) * np.diag(1.-alpha) * np.diag(1.-q) * np.diag(delta) * np.dot(self.contact_rate(t), np.diag(theta_I)) * np.diag(np.divide(S, self.N_total)) AtoS = np.diag(beta) * np.diag(1.-alpha) * np.dot(self.contact_rate(t), np.diag(theta_A)) * np.diag(np.divide(S, self.N_total)) T = np.block([ [zeros, AtoS, ItoS], [zeros, zeros, zeros], [zeros, zeros, zeros] ]) Sigma = np.block([ [-np.diag(sigma), zeros, zeros], [np.diag(1.-tau)*np.diag(sigma), -np.diag(gamma_A), zeros], [np.diag(tau)*np.diag(sigma), zeros, -np.diag(pi)*np.diag(eta_I)-np.diag(1.-pi)*np.diag(gamma_I)] ]) w, _ = np.linalg.eig(-np.dot(T, np.linalg.inv(Sigma))) Rt[n_t] = np.max(w) return Rt
def __init__(self, q1 ,q2, n, t, N = 32): import autograd.numpy as np from scipy.linalg import expm from numpy import concatenate as c # Set constants self.q1 = q1 self.q2 = q2 self.n = n self.t = t self.N = N self.tau = t[1]-t[0] self.T = self.t[-1] ## Build constant matrices a = np.ones(N,dtype=float) d = 4*np.ones(N-1,dtype=float) d = c(([2.],d)) d = c((d,[2.])) # d = [2,4,4,...,4,4,2] # Linear spline matrix # M_{ij} = <psi_i,psi_j>_{L_2(0,1)} self.M = np.array( 1./(6.*N) * (np.diag(a, k=-1) + np.diag(d) + np.diag(a, k=1)), dtype=float) # Stiffness matrix # K_{ij} = <psi'_i,psi'_j>_{L_2(0,1)} self.K = np.array(np.multiply(N, (np.diag(-a,k=-1) + np.diag(d/2.) + np.diag(-a,k=1))), dtype=float) L=R=np.zeros((N+1,N+1)) L[0,0]=1 R[-1,-1]=1 ## Compute dynamical system operators self.AN = np.linalg.solve(- self.M,(self.q1*self.K + L),dtype=float) self.BN = np.array(np.linalg.solve(self.M, c(([self.q2],np.zeros(N)))),dtype=float).reshape((N+1,1)) # Discrete-time evolution self.ANhat = expm(self.tau*self.AN) # Discrete-time input self.BNhat= (self.ANhat - np.eye(self.N + 1)) @ np.linalg.solve(self.AN,self.BN) # Discrete-time output self.CNhat = np.zeros(N+1,dtype=float) self.CNhat[-1] = 1. ## Gradient computation # Derivatives of system operators self.dAN_dq1 = np.linalg.solve(-self.M,self.K) self.dBN_dq2 = np.array(np.linalg.solve(self.M, c(([1],np.zeros(N)))),dtype=float).reshape((N+1,1)) mm = np.block([[self.AN,self.dAN_dq1],[np.zeros((N+1,N+1)),self.AN]]) mm = np.multiply(self.tau,mm) AdAExp = expm(mm) self.ANhat = AdAExp[:(N+1),:(N+1)]; self.BNhat = (self.ANhat - np.eye(N+1)) @ np.linalg.solve(self.AN,self.BN) self.dANhat_dq1 = AdAExp[:(N+1),(N+2):] print(self.ANhat.shape, self.BNhat.shape, self.dANhat_dq1.shape) self.dBNhat_dq1 = self.linalg.solve(-self.AN, self.dAN_dq1 @ (self.linalg.solve(self.AN, self.ANhat - np.eye(N+1))) - self.dANhat_dq1) @ self.BN self.dBNhat_dq2 = np.linalg.solve(self.AN, (self.ANhat-np.eye(N+1)))*self.dBN_dq2 # State X = np.zeros((N+1,n,m+1)) for i in range(m+1): X[:,1,i] = np.multiply(self.BNhat , total_u[i,1]) for j in range(1,n): X[:,j,i] = self.ANhat @ X[:,j-1,i] + self.BNhat @ total_u[i,j-1] # Initialize eta for adjoint method # goes from t=tau to t=tau*n. At t=0, everything is 0. eta = np.zeros[N+1,n+1,m+1] for i in range(m+1): eta[:,n,i] = (self.CNhat @ X[:,n,i]-Y[i,n]) @ CNhat.T # Compute gradient contributions dJN = np.zeros[1,2+P+1+1] # Adjoint method for j in range(n-1,0,-1): for i in range(m+1): eta[:,j,i] = self.ANhat.T @ eta[:,j+1,i] + (self.CNhat @ X[:,j,i]-Y[i,j]) @ self.CNhat.T # Gradient for j in range(n+1): for i in range(m+1): # Gradient of system parameters sc = m*(i==m+1)+(i<=m) if j>0: for k in range(2): dJN[k] = dJN[k] + sc*(eta[:,j,i].T @ (dAhat_dq(:,:,k)*X(:,j-1,i) + dBhat_dq(:,:,k)*total_u(i,j-1))); end end JN = JN + sc*(CNhat*X(:,j,i)-Y(i,j))^2; end for r=0:P dJN(r+3) = dJN(r+3) + sc*(eta(:,j,m+1)'*Bhat*SplinesP_linear(r+1,j)); end
def cost(z): Q = np.diag([100, 1, 10, 1]) R = np.diag([10]) H = np.block([[Q, np.zeros([n, m])], [np.zeros([m, n]), R]]) return np.dot(z, np.dot(H, z))