<commit_before># Copyright 2014-2017 The ODL contributors
#
# This file is part of ODL.
#
# This Source Code Form is subject to the terms of the Mozilla Public License,
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at https://mozilla.org/MPL/2.0/.

"""Figures of merit (FOMs) for comparison against a known ground truth."""

from __future__ import division
import numpy as np

import odl

__all__ = ('mean_squared_error', 'mean_absolute_error',
           'mean_value_difference', 'standard_deviation_difference',
           'range_difference', 'blurring', 'false_structures_mask', 'ssim',
           'psnr', 'haarpsi', 'noise_power_spectrum')


def mean_squared_error(data, ground_truth, mask=None, normalized=False):
    """Return mean squared L2 distance between ``data`` and ``ground_truth``.

    See also `this Wikipedia article
    <https://en.wikipedia.org/wiki/Mean_squared_error>`_.

    Parameters
    ----------
    data : `Tensor`
        Input data to compare to the ground truth.
    ground_truth : `Tensor`
        Reference to compare ``data`` to.
    mask : `array-like`, optional
        If given, ``data * mask`` is compared to ``ground_truth * mask``.
    normalized  : bool, optional
        Boolean flag to switch between unormalized and normalized FOM.

    Returns
    -------
    mse : float
        FOM value, where a lower value means a better match.

    Notes
    -----
    The FOM evaluates

    .. math::
        \mathrm{MSE}(f, g) = \\frac{\| f - g \|_2^2}{\| 1 \|_2^2},

    where :math:`\| 1 \|^2_2` is the volume of the domain of definition
    of the functions. For :math:`\mathbb{R}^n` type spaces, this is equal
    to the number of elements :math:`n`.

    The normalized form is

    .. math::
        \mathrm{MSE_N} = \\frac{\| f - g \|_2^2}{(\| f \|_2 + \| g \|_2)^2}.

    The normalized variant takes values in :math:`[0, 1]`.
    """
    l2norm = odl.solvers.L2Norm(data.space)
    l2norm_squared = odl.solvers.L2NormSquared(data.space)

    if mask is not None:
        data = data * mask
        ground_truth = ground_truth * mask

    diff = data - ground_truth
    fom = l2norm_squared(diff)

    if normalized:
        fom /= (l2norm(data) + l2norm(ground_truth)) ** 2
    else:
        fom /= l2norm_squared(data.space.one())

    return fom


def mean_absolute_error(data, ground_truth, mask=None, normalized=False):
    """Return L1-distance between ``data`` and ``ground_truth``.

    See also `this Wikipedia article
    <https://en.wikipedia.org/wiki/Mean_absolute_error>`_.

    Parameters
    ----------
    data : `Tensor`
        Input data to compare to the ground truth.
    ground_truth : `Tensor`
        Reference to compare ``data`` to.
    mask : `array-like`, optional
        If given, ``data * mask`` is compared to ``ground_truth * mask``.
    normalized  : bool, optional
        Boolean flag to switch between unormalized and normalized FOM.

    Returns
    -------
    mae : float
        FOM value, where a lower value means a better match.

    Notes
    -----
    The FOM evaluates

    .. math::
        \mathrm{MAE}(f, g) = \\frac{\| f - g \|_1}{\| 1 \|_1},

    where :math:`\| 1 \|_1` is the volume of the domain of definition
    of the functions. For :math:`\mathbb{R}^n` type spaces, this is equal
    to the number of elements :math:`n`.

    The normalized form is

    .. math::
        \mathrm{MAE_N}(f, g) = \\frac{\| f - g \|_1}{\| f \|_1 + \| g \|_1}.

    The normalized variant takes values in :math:`[0, 1]`.
    """
    l1_norm = odl.solvers.L1Norm(data.space)
    if mask is not None:
        data = data * mask
        ground_truth = ground_truth * mask
    diff = data - ground_truth
    fom = l1_norm(diff)

    if normalized:
        fom /= (l1_norm(data) + l1_norm(ground_truth))
    else:
        fom /= l1_norm(data.space.one())

    return fom


def mean_value_difference(data, ground_truth, mask=None, normalized=False):
    """Return difference in mean value between ``data`` and ``ground_truth``.

    Parameters
    ----------
    data : `Tensor`
        Input data to compare to the ground truth.
    ground_truth : `Tensor`
        Reference to compare ``data`` to.
    mask : `array-like`, optional
        If given, ``data * mask`` is compared to ``ground_truth * mask``.
    normalized  : bool, optional
        Boolean flag to switch between unormalized and normalized FOM.

    Returns
    -------
    mvd : float
        FOM value, where a lower value means a better match.

    Notes
    -----
    The FOM evaluates

    .. math::
         \mathrm{MVD}(f, g) =<commit_msg>ENH: Add force_lower_is_better flag to mean_squared_error and mean_absoulte_error.<commit_after># Copyright 2014-2017 The ODL contributors
#
# This file is part of ODL.
#
# This Source Code Form is subject to the terms of the Mozilla Public License,
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at https://mozilla.org/MPL/2.0/.

"""Figures of merit (FOMs) for comparison against a known ground truth."""

from __future__ import division
import numpy as np

import odl

__all__ = ('mean_squared_error', 'mean_absolute_error',
           'mean_value_difference', 'standard_deviation_difference',
           'range_difference', 'blurring', 'false_structures_mask', 'ssim',
           'psnr', 'haarpsi', 'noise_power_spectrum')


def mean_squared_error(data, ground_truth, mask=None,
                       normalized=False, force_lower_is_better=False):
    """Return mean squared L2 distance between ``data`` and ``ground_truth``.

    See also `this Wikipedia article
    <https://en.wikipedia.org/wiki/Mean_squared_error>`_.

    Parameters
    ----------
    data : `Tensor`
        Input data to compare to the ground truth.
    ground_truth : `Tensor`
        Reference to compare ``data`` to.
    mask : `array-like`, optional
        If given, ``data * mask`` is compared to ``ground_truth * mask``,
        where multiplication is pointwise.
    normalized  : bool, optional
        Boolean flag to switch between unormalized and normalized FOM.
        See `Notes` for details.
    force_lower_is_better : bool, optional
        Boolean flag which enforces that lower values correspond to better
        matches.

    Returns
    -------
    mse : float
        FOM value, where a lower value means a better match.

    Notes
    -----
    The FOM evaluates

    .. math::
        \mathrm{MSE}(f, g) = \\frac{\| f - g \|_2^2}{\| 1 \|_2^2},

    where :math:`\| 1 \|^2_2` is the volume of the domain of definition
    of the functions. For :math:`\mathbb{R}^n` type spaces, this is equal
    to the number of elements :math:`n`.

    The normalized form is

    .. math::
        \mathrm{MSE_N} = \\frac{\| f - g \|_2^2}{(\| f \|_2 + \| g \|_2)^2}.

    The normalized variant takes values in :math:`[0, 1]`.
    """
    l2norm = odl.solvers.L2Norm(data.space)
    l2norm_squared = odl.solvers.L2NormSquared(data.space)

    if mask is not None:
        data = data * mask
        ground_truth = ground_truth * mask

    diff = data - ground_truth
    fom = l2norm_squared(diff)

    if normalized:
        fom /= (l2norm(data) + l2norm(ground_truth)) ** 2
    else:
        fom /= l2norm_squared(data.space.one())

    # The mean squared error is already in the desired order.
    if force_lower_is_better:
        pass

    return fom


def mean_absolute_error(data, ground_truth, mask=None,
                        normalized=False, force_lower_is_better=False):
    """Return L1-distance between ``data`` and ``ground_truth``.

    See also `this Wikipedia article
    <https://en.wikipedia.org/wiki/Mean_absolute_error>`_.

    Parameters
    ----------
    data : `Tensor`
        Input data to compare to the ground truth.
    ground_truth : `Tensor`
        Reference to compare ``data`` to.
    mask : `array-like`, optional
        If given, ``data * mask`` is compared to ``ground_truth * mask``,
        where multiplication is pointwise.
    normalized  : bool, optional
        Boolean flag to switch between unormalized and normalized FOM.
        See `Notes` for details.
    force_lower_is_better : bool, optional
        Boolean flag which enforces that lower values correspond to better
        matches.

    Returns
    -------
    mae : float
        FOM value, where a lower value means a better match.

    Notes
    -----
    The FOM evaluates

    .. math::
        \mathrm{MAE}(f, g) = \\frac{\| f - g \|_1}{\| 1 \|_1},

    where :math:`\| 1 \|_1` is the volume of the domain of definition
    of the functions. For :math:`\mathbb{R}^n` type spaces, this is equal
    to the number of elements :math:`n`.

    The normalized form is

    .. math::
        \mathrm{MAE_N}(f, g) = \\frac{\| f - g \|_1}{\| f \|_1 + \| g \|_1}.

    The normalized variant takes values in :math:`[0, 1]`.
    """
    l1_norm = odl.solvers.L1Norm(data.space)
    if mask is not None:
        data = data * mask
        ground_truth = ground_truth * mask
    diff = data - ground_truth
    fom = l1_norm(diff)

    if normalized:
        fom /= (l1_norm(data) + l1_norm(ground_truth))
    else:
        fom /= l1_norm(data.space.one())

    # The mean absolute error is already in the desired order.
    if force_lower_is_better:
        pass

    return fom


def mean_value_difference(data, ground_truth, mask=None, normalized=False):
    """Return difference in mean value between ``data`` and ``ground_truth``.

    Parameters
    ----------
    data : `Tensor`
        Input data to compare to the ground truth.
    ground_truth : `Tensor`
        Reference to compare ``data`` to.
    mask : `array-like`, optional
        If given, ``data * mask`` is compared to ``ground_truth * mask``.
    normalized  : bool, optional
        Boolean flag to switch between unormalized and normalized FOM.

    Returns
    -------
    mvd : float
        FOM value, where a lower value means a better match.

    Notes
    -----
    The FOM evaluates

    .. math::
         \mathrm{MVD}(f, g) =
{'fraction_non_alphanumeric': 0.12267990074441687, 'fraction_numerical': 0.010719602977667494, 'mean_word_length': 2.3925925925925924, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2336106', 'n_tokens_mistral': 3236, 'n_tokens_neox': 3023, 'n_words': 1055}