# Source code for magni.cs.reconstruction.it._stop_criterion

"""
..

Module providing functions for calculating stop criteria used in Iterative
Threholding (IT) algorithms.

Routine listings
----------------
calculate_using_mse_convergence(var)
Calculate stop criterion based on mse convergence.
calculate_using_normalised_mse_convergence(var)
Calculate stop criterion based on normalised mse convergence.
calculate_using_residual(var)
Calculate stop criterion based on residual.
calculate_using_residual_measurments_ratio(var)
Calculate stop criterion based on the residual to measurements ratio.
get_function_handle(method)
Return a function handle to a given calculation method.

"""

from __future__ import division

import numpy as np

[docs]def wrap_calculate_using_mse_convergence(var):
"""
Arguments wrapper for calculate_using_mse_convergence.

Calculate stop criterion based on mse convergence.

"""

n = var['A'].shape
tolerance = var['tolerance']

def calculate_using_mse_convergence(var):
"""
Calculate stop criterion based on mse convergence.

Parameters
----------
var : dict
Dictionary of variables used in calculating the stop criterion.

Returns
-------
stop : bool
The indicator of whether or not the stop criterion is satisfied.
mse : float
The current convergence mean squared error.

Notes
-----
The IT algorithm should converge to a fixed point. This criterion
is based on the mean squared error of the difference between the
proposed solution in this iteration and the proposed solution in the
previous solution.

"""

mse = 1/n * np.linalg.norm(var['alpha_prev'] - var['alpha'])**2
stop = mse < tolerance

return stop, mse

return calculate_using_mse_convergence

[docs]def wrap_calculate_using_normalised_mse_convergence(var):
"""
Arguments wrapper for calculate_using_normalised_mse_convergence.

Calculate stop criterion based on normalised mse convergence.

"""

tolerance = var['tolerance']

def calculate_using_normalised_mse_convergence(var):
"""
Calculate stop criterion based on normalised mse convergence.

Parameters
----------
var : dict
Dictionary of variables used in calculating the stop criterion.

Returns
-------
stop : bool
The indicator of whether or not the stop criterion is satisfied.
mse : float
The current convergence normalised mean squared error.

Notes
-----
The IT algorithm should converge to a fixed point. This criterion
is based on the normalised mean squared error of the difference
between the proposed solution in this iteration and the proposed
solution in the previous solution normalised by the mean squared error
of the proposed solution in the previous iteration

"""

se = np.linalg.norm(var['alpha_prev'] - var['alpha'])**2
norm = np.linalg.norm(var['alpha_prev'])**2
if norm > 0:
nmse = se / norm
stop = se < tolerance * norm
else:
# Previous solution was zero-vector (most likely first iteration)
nmse = se
stop = False

return stop, nmse

return calculate_using_normalised_mse_convergence

[docs]def wrap_calculate_using_residual(var):
"""
Arguments wrapper for calculate_using_residual.

Calculate stop criterion based on residual.

"""

tolerance = var['tolerance']
m = var['A'].shape

def calculate_using_residual(var):
"""
Calculate stop criterion based on residual.

Parameters
----------
var : dict
Dictionary of variables used in calculating the stop criterion.

Returns
-------
stop : bool
The indicator of whether or not the stop criterion is satisfied.
r_mse : float
The current mean squared error of the residual.

Notes
-----
This stopping criterion is based on the mean sqaured error of the
residual.

"""

r_mse = 1/m * np.linalg.norm(var['r'])**2
stop = r_mse < tolerance

return stop, r_mse

return calculate_using_residual

[docs]def wrap_calculate_using_residual_measurements_ratio(var):
"""
Arguments wrapper for calculate_using_residual_measurements_ratio.

Calculate stop criterion based on the residual to measurements ratio.

"""

tolerance = var['tolerance']
y = var['y']

def calculate_using_residual_measurements_ratio(var):
"""
Calculate stop criterion based on the residual to measurements ratio.

Parameters
----------
var : dict
Dictionary of variables used in calculating of the stop criterion.

Returns
-------
stop : bool
The indicator of whether or not the stop criterion is satisfied.
r_norm : float
The current 2-norm of the residual.

Notes
-----
This stop criterion is based on the ratio of the 2-norm of the current
residual to the 2-norm of the measurments.

"""

r_norm = np.linalg.norm(var['r'])
stop = r_norm < tolerance * np.linalg.norm(y)

return stop, r_norm

return calculate_using_residual_measurements_ratio

[docs]def get_function_handle(method, var):
"""
Return a function handle to a given calculation method.

Parameters
----------
method : str
Identifier of the calculation method to return a handle to.
var : dict
Local variables needed in the calculation method.

Returns
-------
f_handle : function
Handle to calculation method defined in this globals scope.

"""

return globals()['wrap_calculate_using_' + method](var)