⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 orthogonalscaler.cpp

📁 ROSETTA C++库是一个C++类库和例程集合
💻 CPP
字号:
//-------------------------------------------------------------------
// Author........: Aleksander 豩rn
// Date..........: 960307
// Description...:
// Revisions.....:
//===================================================================

#include <stdafx.h> // Precompiled headers.
#include <copyright.h>

#include <kernel/algorithms/orthogonalscaler.h>
#include <kernel/algorithms/keyword.h>

#include <kernel/structures/decisiontable.h>
#include <kernel/structures/dictionary.h>
#include <kernel/structures/attribute.h>
#include <kernel/structures/floatattribute.h>
#include <kernel/structures/integerattribute.h>
#include <kernel/structures/stringattribute.h>

#include <kernel/utilities/creator.h>
#include <kernel/utilities/mathkit.h>
#include <kernel/utilities/iokit.h>

#include <kernel/basic/interval.h>
#include <kernel/basic/vector.h>
#include <kernel/basic/algorithm.h>
#include <kernel/basic/message.h>

#include <kernel/system/fstream.h>
#include <kernel/system/math.h>

#include <common/configuration.h>

//-------------------------------------------------------------------
// Static methods (file scope).
//===================================================================

//-------------------------------------------------------------------
// Method........: StaticLoadCuts
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Loads cuts from file, returns them in-place.
// Comments......: Partial overlap with code elsewhere, generalize
//                 later.  Note masked/unmasked conversion.
//                 Called from CreateDictionary method.
// Revisions.....:
//===================================================================

static bool
StaticLoadCuts(const String &filename, const DecisionTable &table, bool masked, Vector(OrthogonalScaler::Cuts) &cuts) {

	int no_attributes = table.GetNoAttributes(masked);

	// Initialize vector of all cuts.
	cuts.erase(cuts.begin(), cuts.end());
	cuts.reserve(no_attributes);

	int i;

	for (i = 0; i < no_attributes; i++)
		cuts.push_back(OrthogonalScaler::Cuts());

	ifstream cutfile;

	if (!IOKit::Open(cutfile, filename)) {
		Message::Error("Could not open file with cuts.");
		return false;
	}

	// Read contents of cut file.
	while (!IOKit::IsEOF(cutfile)) {

		String line;

		// Get index (virtual) and cut of attribute.
		if (!IOKit::Load(cutfile, line, false))
			return false;

		// Allow for blank lines.
		if (line.IsEmpty())
			continue;

		if (line.GetNoTokens(" \t") != 2) {
			Message::Error("Expected two tokens (index, cut).");
			return false;
		}

		// Split string into (index, cut) pair.
		String istr = line.Before('\t');
		String cstr = line.After('\t');

		// Verify types.
		if (!istr.IsInteger() || !cstr.IsFloat()) {
			Message::Error("Error reading (index, cut) pair from cut file.");
			return false;
		}

		// Extract values.
		int   index = istr.GetInteger();
		float cut   = cstr.GetFloat();

    // Convert from virtual (masked) to actual (unmasked) indexing scheme.
		index = table.GetUnmaskedAttribute(index);

    // Make sure the index is in range.
		if ((index < 0) || (index >= cuts.size())) {
			Message::Error("Index in (index, cut) pair in cutfile out of range.");
			return false;
		}

		// Insert cut into appropriate cut vector.
		cuts[index].push_back(cut);

	}

	// Sort the cuts.
	for (i = 0; i < cuts.size(); i++)
		std::sort(cuts[i].begin(), cuts[i].end());

	return true;

}

//-------------------------------------------------------------------
// Method........: StaticCreateDummyDictionary
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Creates a dummy dictionary.
// Comments......: Called from CreateDictionary method.
// Revisions.....:
//===================================================================

static bool
StaticCreateDummyDictionary(DecisionTable &table, Dictionary &dictionary) {

	int no_attributes_unmasked = table.GetNoAttributes(false);

	// Clear present dictionary.
	dictionary.RemoveAllAttributes();

	int i;

	// Create dummy dictionary.
	for (i = 0; i < no_attributes_unmasked; i++) {

		// Create an integer attribute.
		Handle<Attribute> attribute = Creator::IntegerAttribute();

		// Set dummy name/unit.
		attribute->SetName("A" + String::Format(i));
		attribute->SetUnit(Undefined::String());

		// Append to dictionary.
		if (!dictionary.AppendAttribute(attribute.GetPointer()))
			return false;

	}

	// Assign new dictionary.
	table.SetDictionary(&dictionary);

	Message::Warning("A dummy dictionary was created.");

	return true;

}

//-------------------------------------------------------------------
// Method........: StaticHasEqualMasking
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns true if the two tables have the same
//                 masking.
// Comments......: Called from CreateDictionary method.
// Revisions.....:
//===================================================================

static bool
StaticHasEqualMasking(const DecisionTable &table1, const DecisionTable &table2, bool masked) {

	int no_attributes1 = table1.GetNoAttributes(masked);
	int no_attributes2 = table2.GetNoAttributes(masked);

	if (no_attributes1 != no_attributes2)
		return false;

	int i;

	for (i = 0; i < no_attributes1; i++) {
		if (table1.GetAttributeMask(i) != table2.GetAttributeMask(i))
			return false;
	}

	return true;

}

//-------------------------------------------------------------------
// Method........: StaticHasChanged
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns true if the entries in the two tables
//                 differ on the given attribute.
// Comments......: Called from CreateDictionary method.
// Revisions.....:
//===================================================================

static bool
StaticHasChanged(const DecisionTable &table1, const DecisionTable &table2, int attribute_no, bool masked) {

	int no_objects1 = table1.GetNoObjects(masked);
	int no_objects2 = table2.GetNoObjects(masked);

	if (no_objects1 != no_objects2)
		return true;

	int i;

	for (i = 0; i < no_objects1; i++) {
		if (table1.GetEntry(i, attribute_no, masked) != table2.GetEntry(i, attribute_no, masked))
			return true;
	}

	return false;

}

//-------------------------------------------------------------------
// Methods for class OrthogonalScaler.
//===================================================================

//-------------------------------------------------------------------
// Constructors/destructor.
//===================================================================

OrthogonalScaler::OrthogonalScaler() {
}

OrthogonalScaler::~OrthogonalScaler() {
}

//-------------------------------------------------------------------
// Methods inherited from Identifier.
//===================================================================

IMPLEMENTIDMETHODS(OrthogonalScaler, ORTHOGONALSCALER, Scaler)

//-------------------------------------------------------------------
// Methods inherited from Algorithm.
//===================================================================

//-------------------------------------------------------------------
// Method........: Apply
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================

Structure *
OrthogonalScaler::Apply(Structure &structure) const {

	// Check if input is of expected type.
	if (!IsApplicable(structure))
		return NULL;

	// Cast to verified type.
	Handle<DecisionTable> input = dynamic_cast(DecisionTable *, &structure);

	Vector(DecisionTable::Mask) original_masks;
	Vector(DecisionTable::Mask) temporary_masks;

	if (!GetAttributeMasks(*input, original_masks))
		return NULL;

	// Temporarily hide away non-numerical attributes if specified.
	if (MaskSymbolic()) {
		if (!GetTemporaryAttributeMasks(*input, temporary_masks))
			return NULL;
		if (!SetAttributeMasks(*input, temporary_masks))
			return NULL;
	}

	Handle<DecisionTable> output;

	// If possible, do the actual discretization. (Assuming the output table "inherits" the masking of the input table.)
	if (input->GetNoAttributes(true) > 1) {
		output = Discretize(*input);
	}
	else {
		if (MaskSymbolic()) {
			Message::Warning("Table has no condition attributes after masking.", false);
			SetAttributeMasks(*input, original_masks);
			return &structure;
		}
		else {
			Message::Error("Table has no condition attributes.", false);
			return NULL;
		}
	}

	if (output == NULL) {
		if (MaskSymbolic())
			SetAttributeMasks(*input, original_masks);
		return NULL;
	}

	// Construct a new dictionary. (Masking of both tables should be the same and seen as by the
	// discretization method.)
	if (!CreateDictionary(*input, *output, GetFilename())) {
		Message::Error("Failed to create dictionary.");
		if (MaskSymbolic())
			SetAttributeMasks(*input, original_masks);
		return NULL;
	}

	// Reset masking.
	if (MaskSymbolic()) {
		if (!SetAttributeMasks(*input, original_masks))
			return NULL;
		if (!SetAttributeMasks(*output, original_masks))
			return NULL;
	}

	// Append string to table name.
	output->SetName(input->GetName() + ", discretized");

	return output.Release();

}

//-------------------------------------------------------------------
// Dictionary creation methods.
//===================================================================

//-------------------------------------------------------------------
// Method........: CreateDictionary
// Author........: Aleksander 豩rn
// Date..........:
// Description...: After a decision table has been scaled, the old
//                 dictionary may no longer be 100% valid as the result
//                 of e.g. a float attribute having been transformed
//                 to an "interval" attribute.
//
//                 This method takes as input the decision tables before
//                 and after scaling, and on the basis of these and the
//                 dictionary associated with the before table, creates a
//                 new dictionary which in turn is assigned to the after
//                 table.
//
//                 The filename refers to the file where the cut-values
//                 are stored.
//
// Comments......: Note that the dictionary is indexed with actual (i.e.
//                 unmasked) attributes indices, while the tables are indexed
//                 with virtual (i.e. masked) attribute indices.  That is,
//                 dictionaries associated with decision tables have the
//                 dimension of the unmasked table.
//
// Revisions.....: A

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -