<commit_before>/*
 * opencog/learning/moses/moses/precision_bscore.cc
 *
 * Copyright (C) 2002-2008 Novamente LLC
 * Copyright (C) 2012,2013 Poulin Holdings LLC
 * All Rights Reserved
 *
 * Written by <NAME>, <NAME>, <NAME>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "precision_bscore.h"

#include <boost/range/irange.hpp>

#include <opencog/comboreduct/table/table_io.h>

namespace opencog { namespace moses {

using namespace std;
        
//////////////////////
// precision_bscore //
//////////////////////

/// NOTE: The "precision" bscore, below, does NOT correspond to the 
/// standard definition of "precision", as usually given in textbooks
/// or wikipedia, but is something similar but different in various
/// details. To get the standard, text-book definition of a "precision"
/// scorer, use the "prerec" class above.  Actually, chances are good
/// that you probably want the "recall" scorer, which maximizes recall
/// while holding precision at or above a minimum level.

precision_bscore::precision_bscore(const CTable& _ctable,
                                   float penalty_,
                                   float min_activation_,
                                   float max_activation_,
                                   bool positive_,
                                   bool worst_norm_)
    : orig_ctable(_ctable), wrk_ctable(orig_ctable),
      ctable_usize(orig_ctable.uncompressed_size()),
      min_activation(min_activation_), max_activation(max_activation_),
      penalty(penalty_), positive(positive_), worst_norm(worst_norm_),
    precision_full_bscore(true)
{
    output_type = wrk_ctable.get_output_type();
    if (output_type == id::boolean_type) {
        // For boolean tables, sum the total number of 'T' values
        // in the output.  Ths sum represents the best possible score
        // i.e. we found all of the true values correcty.  Count
        // 'F' is 'positive' is false.
        vertex target = bool_to_vertex(positive),
            neg_target = negate_vertex(target);
        sum_outputs = [this, target, neg_target](const CTable::counter_t& c)
            -> score_t
        {
            return ((int)c.get(target) - (int)c.get(neg_target)) * 0.5;
        };
    } else if (output_type == id::contin_type) {
        // For contin tables, we return the sum of the row values.
        sum_outputs = [this](const CTable::counter_t& c)->score_t
        {
            score_t res = 0.0;
            for (const CTable::counter_t::value_type& cv : c)
                res += get_contin(cv.first) * cv.second;
            return (positive? res : -res);
        };
    } else {
        OC_ASSERT(false, "Precision scorer, unsupported output type");
        return;
    }

    logger().fine("Precision scorer, penalty = %f, "
                  "min_activation = %f, "
                  "max_activation = %f",
                  penalty, min_activation, max_activation);

    // Verify that the penaly is sane
    OC_ASSERT((0.0 < penalty) && (0.0 < min_activation) && (min_activation <= max_activation),
        "Precision scorer, invalid activation bounds.  "
        "The penalty must be non-zero, the minimum activation must be "
        "greater than zero, and the maximum activation must be greater "
        "than or equal to the minimum activation.\n");

    // For boolean tables, the highest possible precision is 1.0 (of course)
    if (output_type == id::boolean_type)
        max_output = 1.0;
    else if (output_type == id::contin_type) {

        // For contin tables, we search for the largest value in the table.
        // (or smallest, if positive == false)
        max_output = very_worst_score;<commit_msg>Fix a void return ...<commit_after>/*
 * opencog/learning/moses/moses/precision_bscore.cc
 *
 * Copyright (C) 2002-2008 Novamente LLC
 * Copyright (C) 2012,2013 Poulin Holdings LLC
 * All Rights Reserved
 *
 * Written by <NAME>, <NAME>, <NAME>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "precision_bscore.h"

#include <boost/range/irange.hpp>

#include <opencog/comboreduct/table/table_io.h>

namespace opencog { namespace moses {

using namespace std;
        
//////////////////////
// precision_bscore //
//////////////////////

/// NOTE: The "precision" bscore, below, does NOT correspond to the 
/// standard definition of "precision", as usually given in textbooks
/// or wikipedia, but is something similar but different in various
/// details. To get the standard, text-book definition of a "precision"
/// scorer, use the "prerec" class above.  Actually, chances are good
/// that you probably want the "recall" scorer, which maximizes recall
/// while holding precision at or above a minimum level.

precision_bscore::precision_bscore(const CTable& _ctable,
                                   float penalty_,
                                   float min_activation_,
                                   float max_activation_,
                                   bool positive_,
                                   bool worst_norm_)
    : orig_ctable(_ctable), wrk_ctable(orig_ctable),
      ctable_usize(orig_ctable.uncompressed_size()),
      min_activation(min_activation_), max_activation(max_activation_),
      penalty(penalty_), positive(positive_), worst_norm(worst_norm_),
    precision_full_bscore(true)
{
    output_type = wrk_ctable.get_output_type();
    if (output_type == id::boolean_type) {
        // For boolean tables, sum the total number of 'T' values
        // in the output.  Ths sum represents the best possible score
        // i.e. we found all of the true values correcty.  Count
        // 'F' is 'positive' is false.
        vertex target = bool_to_vertex(positive),
            neg_target = negate_vertex(target);
        sum_outputs = [this, target, neg_target](const CTable::counter_t& c)
            -> score_t
        {
            return ((int)c.get(target) - (int)c.get(neg_target)) * 0.5;
        };
    } else if (output_type == id::contin_type) {
        // For contin tables, we return the sum of the row values.
        sum_outputs = [this](const CTable::counter_t& c)->score_t
        {
            score_t res = 0.0;
            for (const CTable::counter_t::value_type& cv : c)
                res += get_contin(cv.first) * cv.second;
            return (positive? res : -res);
        };
    } else {
        OC_ASSERT(false, "Precision scorer, unsupported output type");
    }

    logger().fine("Precision scorer, penalty = %f, "
                  "min_activation = %f, "
                  "max_activation = %f",
                  penalty, min_activation, max_activation);

    // Verify that the penaly is sane
    OC_ASSERT((0.0 < penalty) && (0.0 < min_activation) && (min_activation <= max_activation),
        "Precision scorer, invalid activation bounds.  "
        "The penalty must be non-zero, the minimum activation must be "
        "greater than zero, and the maximum activation must be greater "
        "than or equal to the minimum activation.\n");

    // For boolean tables, the highest possible precision is 1.0 (of course)
    if (output_type == id::boolean_type)
        max_output = 1.0;
    else if (output_type == id::contin_type) {

        // For contin tables, we search for the largest value in the table.
        // (or smallest, if positive == false)
        max_output = very_worst_score;
{'fraction_non_alphanumeric': 0.10351919561243145, 'fraction_numerical': 0.009140767824497258, 'mean_word_length': 2.4392927308447936, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5006023', 'n_tokens_mistral': 2535, 'n_tokens_neox': 2379, 'n_words': 852}