def svd_dotH(self, s1, q1): """ Performs diagonal matrix multiplication conjugate Implements :math:`q_0 = \\mathrm{diag}(s_1)^* q_1`. :param s1: diagonal parameters :param q1: input to the diagonal multiplication :returns: :code:`q0` diagonal multiplication output """ srep = repeat_axes(np.conj(s1), self.sshape, self.srep_axes, rep=False) q0 = srep * q1 return q0
def est_init(self, return_cost=False, ind_out=None, avg_var_cost=True): """ Initial estimator. See the base class :class:`vampyre.estim.base.Estim` for a complete description. :param boolean return_cost: Flag indicating if :code:`cost` is to be returned :param Boolean avg_var_cost: Average variance and cost. This should be disabled to obtain per element values. (Default=True) :returns: :code:`zmean, zvar, [cost]` which are the prior mean and variance """ # Check if ind_out is valid if (ind_out != [0]) and (ind_out != None): raise ValueError("ind_out must be either [0] or None") zmean = repeat_axes(self.zmean, self.shape, self.zmean_axes) zvar = self.zvar if not avg_var_cost: zvar = repeat_axes(zvar, self.shape, self.var_axes) if not return_cost: return zmean, zvar # Cost including the normalization factor if self.map_est: clog = np.log(2*np.pi*self.zvar) if avg_var_cost: cost = repeat_sum(clog, self.shape, self.var_axes) else: cost = clog else: cost = 0 if not self.is_complex: cost = 0.5*cost return zmean, zvar, cost
def svd_dot(self, s1, q0): """ Performs diagonal matrix multiplication. Implements :math:`q_1 = \\mathrm{diag}(s_1) q_0`. :param s1: diagonal parameters :param q0: input to the diagonal multiplication :returns: :code:`q1` diagonal multiplication output """ srep = repeat_axes(s1, self.sshape, self.srep_axes, rep=False) q1 = srep * q0 return q1
def est(self,r,rvar,return_cost=False,ind_out=None,avg_var_cost=True): """ Estimation function The proximal estimation function as described in the base class :class:`vampyre.estim.base.Estim` :param r: Proximal mean :param rvar: Proximal variance :param Boolean return_cost: Flag indicating if :code:`cost` is to be returned :param Boolean avg_var_cost: Average variance and cost. This should be disabled to obtain per element values. (Default=True) :returns: :code:`zhat, zhatvar, [cost]` which are the posterior mean, variance and optional cost. """ # Check if ind_out is valid if (ind_out != [0]) and (ind_out != None): raise ValueError("ind_out must be either [0] or None") # Infinite variance case if np.any(rvar==np.Inf): return self.est_init(return_cost, avg_var_cost) zhatvar = rvar*self.zvar/(rvar + self.zvar) gain = self.zvar/(rvar + self.zvar) gain = repeat_axes(gain,self.shape,self.var_axes,rep=False) if not avg_var_cost: zhatvar = repeat_axes(zhatvar,self.shape,self.var_axes) zhat = gain*(r-self.zmean) + self.zmean # EM tuning if self.tune_zvar: if not avg_var_cost: raise VpException("must use variance averaging when using auto-tuning") self.zvar = np.mean(np.abs(zhat-self.zmean)**2, self.var_axes) +\ zhatvar if not return_cost: return zhat, zhatvar # Computes the MAP cost zvar1 = repeat_axes(self.zvar,self.shape,self.var_axes,rep=False) rvar1 = repeat_axes(rvar, self.shape,self.var_axes,rep=False) cost = (np.abs(zhat-self.zmean)**2) / zvar1 \ + (np.abs(zhat-r)**2) / rvar1 if avg_var_cost: cost = np.sum(cost) # Compute cost nz = np.prod(self.shape) if self.map_est: clog = np.log(2*np.pi*self.zvar) if avg_var_cost: clog = np.mean(clog)*nz else: clog = np.log(2*np.pi*zvar1) cost += clog else: d = np.log(self.zvar/zhatvar) if avg_var_cost: cost += np.mean(d)*nz else: cost += d # Scale for real case if not self.is_complex: cost = 0.5*cost return zhat, zhatvar, cost