nikcleju@17: # -*- coding: utf-8 -*- nikcleju@17: """ nikcleju@17: Created on Thu Oct 13 14:05:22 2011 nikcleju@17: nikcleju@17: @author: ncleju nikcleju@17: """ nikcleju@17: nikcleju@17: #from numpy import * nikcleju@17: #from scipy import * nikcleju@17: import numpy as np nikcleju@17: import scipy as sp nikcleju@17: from scipy import linalg nikcleju@17: import math nikcleju@17: nikcleju@17: from numpy.random import RandomState nikcleju@17: rng = RandomState() nikcleju@17: nikcleju@17: nikcleju@17: nikcleju@17: def Generate_Analysis_Operator(d, p): nikcleju@17: # generate random tight frame with equal column norms nikcleju@17: if p == d: nikcleju@17: T = rng.randn(d,d); nikcleju@17: [Omega, discard] = np.qr(T); nikcleju@17: else: nikcleju@17: Omega = rng.randn(p, d); nikcleju@17: T = np.zeros((p, d)); nikcleju@17: tol = 1e-8; nikcleju@17: max_j = 200; nikcleju@17: j = 1; nikcleju@17: while (sum(sum(abs(T-Omega))) > np.dot(tol,np.dot(p,d)) and j < max_j): nikcleju@17: j = j + 1; nikcleju@17: T = Omega; nikcleju@17: [U, S, Vh] = sp.linalg.svd(Omega); nikcleju@17: V = Vh.T nikcleju@17: #Omega = U * [eye(d); zeros(p-d,d)] * V'; nikcleju@17: Omega2 = np.dot(np.dot(U, np.concatenate((np.eye(d), np.zeros((p-d,d))))), V.transpose()) nikcleju@17: #Omega = diag(1./sqrt(diag(Omega*Omega')))*Omega; nikcleju@17: Omega = np.dot(np.diag(1 / np.sqrt(np.diag(np.dot(Omega2,Omega2.transpose())))), Omega2) nikcleju@17: #end nikcleju@17: ##disp(j); nikcleju@17: #end nikcleju@17: return Omega nikcleju@17: nikcleju@17: nikcleju@17: def Generate_Data_Known_Omega(Omega, d,p,m,k,noiselevel, numvectors, normstr): nikcleju@17: #function [x0,y,M,LambdaMat] = Generate_Data_Known_Omega(Omega, d,p,m,k,noiselevel, numvectors, normstr) nikcleju@17: nikcleju@17: # Building an analysis problem, which includes the ingredients: nikcleju@17: # - Omega - the analysis operator of size p*d nikcleju@17: # - M is anunderdetermined measurement matrix of size m*d (m params['noise_level']: nikcleju@17: was_infeasible = 1; nikcleju@17: if was_feasible == 1: nikcleju@17: xhat = xprev; nikcleju@17: break; nikcleju@17: lagmult = lagmult/lagmultfactor; nikcleju@17: if lagmult < lagmultmin or lagmult > lagmultmax: nikcleju@17: break; nikcleju@17: xprev = xhat; nikcleju@17: arepr = np.dot(Omega[Lambdahat, :], xhat); nikcleju@17: return xhat,arepr,lagmult; nikcleju@17: nikcleju@17: nikcleju@17: ######################################################################## nikcleju@17: ## Computation using conjugate gradient method. nikcleju@17: ######################################################################## nikcleju@17: #if strcmp(class(MH),'function_handle') nikcleju@17: if hasattr(MH, '__call__'): nikcleju@17: b = MH(y); nikcleju@17: else: nikcleju@17: b = np.dot(MH, y); nikcleju@17: nikcleju@17: norm_b = np.linalg.norm(b, 2); nikcleju@17: xhat = xinit; nikcleju@17: xprev = xinit; nikcleju@17: residual = TheHermitianMatrix(xhat, M, MH, Omega, OmegaH, Lambdahat, lagmult) - b; nikcleju@17: direction = -residual; nikcleju@17: iter = 0; nikcleju@17: nikcleju@17: while iter < params.max_inner_iteration: nikcleju@17: iter = iter + 1; nikcleju@17: alpha = np.linalg.norm(residual,2)**2 / np.dot(direction.T, TheHermitianMatrix(direction, M, MH, Omega, OmegaH, Lambdahat, lagmult)); nikcleju@17: xhat = xhat + alpha*direction; nikcleju@17: prev_residual = residual; nikcleju@17: residual = TheHermitianMatrix(xhat, M, MH, Omega, OmegaH, Lambdahat, lagmult) - b; nikcleju@17: beta = np.linalg.norm(residual,2)**2 / np.linalg.norm(prev_residual,2)**2; nikcleju@17: direction = -residual + beta*direction; nikcleju@17: nikcleju@17: if np.linalg.norm(residual,2)/norm_b < params['l2_accuracy']*(lagmult**(accuracy_adjustment_exponent)) or iter == params['max_inner_iteration']: nikcleju@17: #if strcmp(class(M), 'function_handle') nikcleju@17: if hasattr(M, '__call__'): nikcleju@17: temp = np.linalg.norm(y-M(xhat), 2); nikcleju@17: else: nikcleju@17: temp = np.linalg.norm(y-np.dot(M,xhat), 2); nikcleju@17: nikcleju@17: #if strcmp(class(Omega), 'function_handle') nikcleju@17: if hasattr(Omega, '__call__'): nikcleju@17: u = Omega(xhat); nikcleju@17: u = math.sqrt(lagmult)*np.linalg.norm(u(Lambdahat), 2); nikcleju@17: else: nikcleju@17: u = math.sqrt(lagmult)*np.linalg.norm(Omega[Lambdahat,:]*xhat, 2); nikcleju@17: nikcleju@17: nikcleju@17: #disp(['residual=', num2str(norm(residual,2)), ' norm_b=', num2str(norm_b), ' omegapart=', num2str(u), ' fidelity error=', num2str(temp), ' lagmult=', num2str(lagmult), ' iter=', num2str(iter)]); nikcleju@17: nikcleju@17: if temp <= params['noise_level']: nikcleju@17: was_feasible = 1; nikcleju@17: if was_infeasible == 1: nikcleju@17: break; nikcleju@17: else: nikcleju@17: lagmult = lagmultfactor*lagmult; nikcleju@17: residual = TheHermitianMatrix(xhat, M, MH, Omega, OmegaH, Lambdahat, lagmult) - b; nikcleju@17: direction = -residual; nikcleju@17: iter = 0; nikcleju@17: elif temp > params['noise_level']: nikcleju@17: lagmult = lagmult/lagmultfactor; nikcleju@17: if was_feasible == 1: nikcleju@17: xhat = xprev; nikcleju@17: break; nikcleju@17: was_infeasible = 1; nikcleju@17: residual = TheHermitianMatrix(xhat, M, MH, Omega, OmegaH, Lambdahat, lagmult) - b; nikcleju@17: direction = -residual; nikcleju@17: iter = 0; nikcleju@17: if lagmult > lagmultmax or lagmult < lagmultmin: nikcleju@17: break; nikcleju@17: xprev = xhat; nikcleju@17: #elseif norm(xprev-xhat)/norm(xhat) < 1e-2 nikcleju@17: # disp(['rel_change=', num2str(norm(xprev-xhat)/norm(xhat))]); nikcleju@17: # if strcmp(class(M), 'function_handle') nikcleju@17: # temp = norm(y-M(xhat), 2); nikcleju@17: # else nikcleju@17: # temp = norm(y-M*xhat, 2); nikcleju@17: # end nikcleju@17: # nikcleju@17: # if temp > 1.2*params.noise_level nikcleju@17: # was_infeasible = 1; nikcleju@17: # lagmult = lagmult/lagmultfactor; nikcleju@17: # xprev = xhat; nikcleju@17: # end nikcleju@17: nikcleju@17: #disp(['fidelity_error=', num2str(temp)]); nikcleju@17: print 'fidelity_error=',temp nikcleju@17: #if iter == params['max_inner_iteration']: nikcleju@17: #disp('max_inner_iteration reached. l2_accuracy not achieved.'); nikcleju@17: nikcleju@17: ## nikcleju@17: # Compute analysis representation for xhat nikcleju@17: ## nikcleju@17: #if strcmp(class(Omega),'function_handle') nikcleju@17: if hasattr(Omega, '__call__'): nikcleju@17: temp = Omega(xhat); nikcleju@17: arepr = temp(Lambdahat); nikcleju@17: else: ## here Omega is assumed to be a matrix nikcleju@17: arepr = np.dot(Omega[Lambdahat, :], xhat); nikcleju@17: nikcleju@17: return xhat,arepr,lagmult nikcleju@17: nikcleju@17: nikcleju@17: ## nikcleju@17: # This function computes (M'*M + lm*Omega(L,:)'*Omega(L,:)) * x. nikcleju@17: ## nikcleju@17: #function w = TheHermitianMatrix(x, M, MH, Omega, OmegaH, L, lm) nikcleju@17: def TheHermitianMatrix(x, M, MH, Omega, OmegaH, L, lm): nikcleju@17: #if strcmp(class(M), 'function_handle') nikcleju@17: if hasattr(M, '__call__'): nikcleju@17: w = MH(M(x)); nikcleju@17: else: ## M and MH are matrices nikcleju@17: w = np.dot(np.dot(MH, M), x); nikcleju@17: nikcleju@17: if hasattr(Omega, '__call__'): nikcleju@17: v = Omega(x); nikcleju@17: vt = np.zeros(v.size); nikcleju@17: vt[L] = v[L].copy(); nikcleju@17: w = w + lm*OmegaH(vt); nikcleju@17: else: ## Omega is assumed to be a matrix and OmegaH is its conjugate transpose nikcleju@17: w = w + lm*np.dot(np.dot(OmegaH[:, L],Omega[L, :]),x); nikcleju@17: nikcleju@17: return w