Skip to content

Commit

Permalink
Rename class IRuleRefinement to AbstractRuleRefinement and add attrib…
Browse files Browse the repository at this point in the history
…ute "bestRefinement_".
  • Loading branch information
michael-rapp committed Oct 2, 2020
1 parent cde120d commit 29a7b6e
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 190 deletions.
290 changes: 143 additions & 147 deletions python/boomer/common/cpp/rule_refinement.cpp

Large diffs are not rendered by default.

26 changes: 14 additions & 12 deletions python/boomer/common/cpp/rule_refinement.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ struct Refinement {
};

/**
* Defines an interface for callbacks that may be invoked by subclasses of the the class `IRuleRefinement` in order to
* retrieve information that is required to identify potential refinements for a certain feature.
* Defines an interface for callbacks that may be invoked by subclasses of the the class `AbstractRuleRefinement` in
* order to retrieve information that is required to identify potential refinements for a certain feature.
*/
template<class T>
class IRuleRefinementCallback {
Expand All @@ -54,14 +54,12 @@ class IRuleRefinementCallback {
/**
* Defines an interface for all classes that allow to find the best refinement of existing rules.
*/
class IRuleRefinement {
class AbstractRuleRefinement {

public:

virtual ~IRuleRefinement() { };

/**
* Finds and returns the best refinement of an existing rule.
* Finds the best refinement of an existing rule and updates the class attribute `bestRefinement_` accordingly.
*
* @param headRefinement A pointer to an object of type `IHeadRefinement` that should be used to find the
* head of the refined rule
Expand All @@ -70,10 +68,14 @@ class IRuleRefinement {
* @param numLabelIndices The number of elements in the array `labelIndices`
* @param labelIndices A pointer to an array of type `uint32`, shape `(numLabelIndices)`, representing the
* indices of the labels for which the refined rule may predict
* @return A struct of type `Refinement`, representing the best refinement that has been found
*/
virtual Refinement findRefinement(IHeadRefinement* headRefinement, PredictionCandidate* currentHead,
uint32 numLabelIndices, const uint32* labelIndices) = 0;
virtual void findRefinement(IHeadRefinement* headRefinement, PredictionCandidate* currentHead,
uint32 numLabelIndices, const uint32* labelIndices) = 0;

/**
* The best refinement that has been found so far.
*/
Refinement bestRefinement_;

};

Expand All @@ -82,7 +84,7 @@ class IRuleRefinement {
* certain feature. The thresholds that may be used by the new condition result from the feature values of all training
* examples for the respective feature.
*/
class ExactRuleRefinementImpl : virtual public IRuleRefinement {
class ExactRuleRefinementImpl : public AbstractRuleRefinement {

private:

Expand Down Expand Up @@ -119,7 +121,7 @@ class ExactRuleRefinementImpl : virtual public IRuleRefinement {

~ExactRuleRefinementImpl();

Refinement findRefinement(IHeadRefinement* headRefinement, PredictionCandidate* currentHead,
uint32 numLabelIndices, const uint32* labelIndices) override;
void findRefinement(IHeadRefinement* headRefinement, PredictionCandidate* currentHead, uint32 numLabelIndices,
const uint32* labelIndices) override;

};
2 changes: 1 addition & 1 deletion python/boomer/common/cpp/thresholds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ ExactThresholdsImpl::ThresholdsSubsetImpl::~ThresholdsSubsetImpl() {
}
}

IRuleRefinement* ExactThresholdsImpl::ThresholdsSubsetImpl::createRuleRefinement(uint32 featureIndex) {
AbstractRuleRefinement* ExactThresholdsImpl::ThresholdsSubsetImpl::createRuleRefinement(uint32 featureIndex) {
IndexedFloat32ArrayWrapper* indexedArrayWrapper = cacheFiltered_[featureIndex];

if (indexedArrayWrapper == NULL) {
Expand Down
20 changes: 10 additions & 10 deletions python/boomer/common/cpp/thresholds.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,18 @@ class IThresholdsSubset {
virtual ~IThresholdsSubset() { };

/**
* Creates and returns a new instance of the type `IRuleRefinement` that allows to find the best refinement of
* an existing rule, which results from adding a new condition that corresponds to the feature at a specific
* index.
* Creates and returns a new instance of the type `AbstractRuleRefinement` that allows to find the best
* refinement of an existing rule, which results from adding a new condition that corresponds to the feature at
* a specific index.
*
* @param featureIndex The index of the feature, the new condition corresponds to
* @return A pointer to an object of type `IRuleRefinement` that has been created
* @return A pointer to an object of type `AbstractRuleRefinement` that has been created
*/
virtual IRuleRefinement* createRuleRefinement(uint32 featureIndex) = 0;
virtual AbstractRuleRefinement* createRuleRefinement(uint32 featureIndex) = 0;

/**
* Applies a refinement that has been found by an instance of the type `IRuleRefinement`, which was previously
* created via the function `createRuleRefinement`.
* Applies a refinement that has been found by an instance of the type `AbstractRuleRefinement`, which was
* previously created via the function `createRuleRefinement`.
*
* This causes the thresholds that will be available for further refinements to be filtered such that only those
* thresholds that correspond to the subspace of the instance space that is covered by the refined rule are
Expand All @@ -52,8 +52,8 @@ class IThresholdsSubset {

/**
* Recalculates the scores to be predicted by a refinement that has been found by an instance of the type
* `IRuleRefinement`, which was previously created via the function `createRuleRefinement`, and updates the head
* of the refinement accordingly.
* `AbstractRuleRefinement`, which was previously created via the function `createRuleRefinement`, and updates
* the head of the refinement accordingly.
*
* When calculating the updated scores the weights of the individual training examples are ignored and equally
* distributed weights are assumed instead.
Expand Down Expand Up @@ -185,7 +185,7 @@ class ExactThresholdsImpl : public AbstractThresholds {

~ThresholdsSubsetImpl();

IRuleRefinement* createRuleRefinement(uint32 featureIndex) override;
AbstractRuleRefinement* createRuleRefinement(uint32 featureIndex) override;

void applyRefinement(Refinement &refinement) override;

Expand Down
25 changes: 10 additions & 15 deletions python/boomer/common/rule_induction.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Provides classes that implement algorithms for inducing individual classificatio
from boomer.common._arrays cimport float32, array_uint32
from boomer.common._predictions cimport PredictionCandidate
from boomer.common.rules cimport Condition, Comparator
from boomer.common.rule_refinement cimport Refinement, IRuleRefinement
from boomer.common.rule_refinement cimport Refinement, AbstractRuleRefinement
from boomer.common.statistics cimport AbstractStatistics, IStatisticsSubset
from boomer.common.sub_sampling cimport IWeightVector, IIndexVector
from boomer.common.thresholds cimport IThresholdsSubset
Expand Down Expand Up @@ -134,18 +134,16 @@ cdef class TopDownGreedyRuleInduction(RuleInduction):
# An array representing the number of conditions per type of operator
cdef uint32[::1] num_conditions_per_comparator = array_uint32(4)
num_conditions_per_comparator[:] = 0
# A map that stores a pointer to an object of type `IRuleRefinement` for each feature
cdef unordered_map[uint32, IRuleRefinement*] rule_refinements # Stack-allocated map
# A map that stores the best refinement for each feature
cdef unordered_map[uint32, Refinement] refinements # Stack-allocated map
# A map that stores a pointer to an object of type `AbstractRuleRefinement` for each feature
cdef unordered_map[uint32, AbstractRuleRefinement*] rule_refinements # Stack-allocated map
# The best refinement of the current rule
cdef Refinement best_refinement # Stack-allocated struct
best_refinement.head = NULL
# Whether a refinement of the current rule has been found
cdef bint found_refinement = True

# Temporary variables
cdef IRuleRefinement* current_rule_refinement
cdef AbstractRuleRefinement* current_rule_refinement
cdef Refinement current_refinement
cdef unique_ptr[IIndexVector] sampled_feature_indices_ptr
cdef uint32 num_covered_examples, num_sampled_features, weight, f
Expand Down Expand Up @@ -177,7 +175,7 @@ cdef class TopDownGreedyRuleInduction(RuleInduction):
sampled_feature_indices_ptr.reset(feature_sub_sampling.subSample(num_features, rng))
num_sampled_features = sampled_feature_indices_ptr.get().getNumElements()

# For each feature, create an object of type `IRuleRefinement` and put it into `rule_refinements`...
# For each feature, create an object of type `AbstractRuleRefinement`...
for c in range(num_sampled_features):
f = sampled_feature_indices_ptr.get().getIndex(<uint32>c)
rule_refinements[f] = thresholds_subset_ptr.get().createRuleRefinement(f)
Expand All @@ -186,17 +184,14 @@ cdef class TopDownGreedyRuleInduction(RuleInduction):
for c in prange(num_sampled_features, nogil=True, schedule='dynamic', num_threads=num_threads):
f = sampled_feature_indices_ptr.get().getIndex(<uint32>c)
current_rule_refinement = rule_refinements[f]
current_refinement = current_rule_refinement.findRefinement(head_refinement, best_refinement.head,
num_predictions, label_indices)
del current_rule_refinement

with gil:
refinements[f] = current_refinement
current_rule_refinement.findRefinement(head_refinement, best_refinement.head, num_predictions,
label_indices)

# Pick the best refinement among the refinements that have been found for the different features...
for c in range(num_sampled_features):
f = sampled_feature_indices_ptr.get().getIndex(<uint32>c)
current_refinement = refinements[f]
current_rule_refinement = rule_refinements[f]
current_refinement = current_rule_refinement.bestRefinement_

if current_refinement.head != NULL and (best_refinement.head == NULL
or current_refinement.head.overallQualityScore_ < best_refinement.head.overallQualityScore_):
Expand All @@ -206,7 +201,7 @@ cdef class TopDownGreedyRuleInduction(RuleInduction):
else:
del current_refinement.head

refinements.clear()
del current_rule_refinement

if found_refinement:
# If a refinement has been found, add the new condition...
Expand Down
10 changes: 7 additions & 3 deletions python/boomer/common/rule_refinement.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,13 @@ cdef extern from "cpp/rule_refinement.h" nogil:
IndexedFloat32Array* indexedArray


cdef cppclass IRuleRefinement:
cdef cppclass AbstractRuleRefinement:

# Attributes:

Refinement bestRefinement_

# Functions:

Refinement findRefinement(IHeadRefinement* headRefinement, PredictionCandidate* currentHead,
uint32 numLabelIndices, const uint32* labelIndices)
void findRefinement(IHeadRefinement* headRefinement, PredictionCandidate* currentHead, uint32 numLabelIndices,
const uint32* labelIndices)
4 changes: 2 additions & 2 deletions python/boomer/common/thresholds.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ from boomer.common._arrays cimport uint32
from boomer.common._predictions cimport Prediction
from boomer.common.head_refinement cimport IHeadRefinement
from boomer.common.input_data cimport FeatureMatrix, IFeatureMatrix, NominalFeatureVector, INominalFeatureVector
from boomer.common.rule_refinement cimport IRuleRefinement, Refinement
from boomer.common.rule_refinement cimport AbstractRuleRefinement, Refinement
from boomer.common.statistics cimport StatisticsProvider, AbstractStatistics
from boomer.common.sub_sampling cimport IWeightVector

Expand All @@ -15,7 +15,7 @@ cdef extern from "cpp/thresholds.h" nogil:

# Functions:

IRuleRefinement* createRuleRefinement(uint32 featureIndex)
AbstractRuleRefinement* createRuleRefinement(uint32 featureIndex)

void applyRefinement(Refinement &refinement)

Expand Down

0 comments on commit 29a7b6e

Please sign in to comment.