//Copyright (C) 2005 Richard J. Northedge // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library 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 Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //This file is based on the GISModeWriter.java source file found in the //original java implementation of MaxEnt. That source file contains the following header: // Copyright (C) 2001 Jason Baldridge and Gann Bierner // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library 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 Lesser General Public // License along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. using System; using System.Collections.Generic; using System.Text; namespace BotSharp.MachineLearning.IO { /// Abstract parent class for GIS model writers that save data to a single /// file. It provides the persist method which takes care of the structure of a stored /// document, and requires an extending class to define precisely how the data should /// be stored. /// /// /// Jason Baldridge /// /// /// Richard J. Northedge /// /// /// based on GISModelWriter.java, $Revision: 1.5 $, $Date: 2004/06/11 20:51:36 $ /// public abstract class GisModelWriter { private PatternedPredicate[] mPredicates; /// /// Implement as needed for the format the model is stored in. /// /// /// string data to be written to storage. /// protected abstract void WriteString(string data); /// /// Implement as needed for the format the model is stored in. /// /// /// Integer data to be written to storage. /// protected abstract void WriteInt32(int data); /// /// Implement as needed for the format the model is stored in. /// /// /// Double precision floating point data to be written to storage. /// protected abstract void WriteDouble(double data); /// /// Obtains a list of the predicates in the model to be written to storage. /// /// /// Array of PatternedPredicate objects containing the predicate data for the model. /// protected PatternedPredicate[] GetPredicates() { return mPredicates; } /// /// Sets the list of predicates to be written to storage. /// /// /// Array of PatternedPredicate objects to be persisted. /// protected void SetPredicates(PatternedPredicate[] predicates) { mPredicates = predicates; } /// /// Writes the model to persistent storage, using the writeX() methods /// provided by extending classes. /// ///

This method delegates to worker methods for each part of this /// sequence. If you are creating a writer that conforms largely to this /// sequence but varies at one or more points, override the relevant worker /// method(s) to achieve the required format.

/// ///

If you are creating a writer for a format which does not follow this /// sequence at all, override this method and ignore the /// other WriteX methods provided in this abstract class.

///
/// /// GIS model whose data is to be persisted. /// protected void Persist(GisModel model) { Initialize(model); WriteModelType("GIS"); WriteCorrectionConstant(model.CorrectionConstant); WriteCorrectionParameter(model.CorrectionParameter); WriteOutcomes(model.GetOutcomeNames()); WritePredicates(model); } /// /// Organises the data available in the GIS model into a structure that is easier to /// persist from. /// /// /// The GIS model to be persisted. /// protected virtual void Initialize(GisModel model) { //read the predicates from the model Dictionary predicates = model.GetPredicates(); //build arrays of predicates and predicate names from the dictionary mPredicates = new PatternedPredicate[predicates.Count]; var predicateNames = new string[predicates.Count]; predicates.Values.CopyTo(mPredicates, 0); predicates.Keys.CopyTo(predicateNames, 0); //give each PatternedPredicate in the array the name taken from the dictionary keys for (int currentPredicate = 0; currentPredicate < predicates.Count; currentPredicate++) { mPredicates[currentPredicate].Name = predicateNames[currentPredicate]; } //sort the PatternedPredicate array based on the outcome pattern that each predicate uses Array.Sort(mPredicates, new OutcomePatternIndexComparer()); } /// /// Writes the model type identifier at the beginning of the file. /// /// string identifying the model type. protected virtual void WriteModelType(string modelType) { WriteString(modelType); } /// /// Writes the value of the correction constant /// /// the model's correction constant value. protected virtual void WriteCorrectionConstant(int correctionConstant) { WriteInt32(correctionConstant); } /// /// Writes the value of the correction constant parameter. /// /// the model's correction constant parameter. protected virtual void WriteCorrectionParameter(double correctionParameter) { WriteDouble(correctionParameter); } /// /// Writes the outcome labels to the file. /// /// string array of outcome labels. protected virtual void WriteOutcomes(string[] outcomeLabels) { //write the number of outcomes WriteInt32(outcomeLabels.Length); //write each label foreach (string label in outcomeLabels) { WriteString(label); } } /// /// Writes the predicate information to the model file. /// /// The GIS model to write the data from. protected virtual void WritePredicates(GisModel model) { WriteOutcomePatterns(model.GetOutcomePatterns()); WritePredicateNames(); WriteParameters(); } /// /// Writes the outcome pattern data to the file. /// /// /// Array of outcome patterns, each an integer array containing /// the number of predicates using the pattern, and then the list of /// outcome IDs in the pattern. /// protected void WriteOutcomePatterns(int[][] outcomePatterns) { //write the number of outcome patterns WriteInt32(outcomePatterns.Length); //for each pattern foreach (int[] pattern in outcomePatterns) { //build a string with the pattern values separated by spaces var outcomePatternBuilder = new StringBuilder(); for (int currentOutcome = 0; currentOutcome < pattern.Length; currentOutcome++) { if (currentOutcome > 0) { outcomePatternBuilder.Append(" "); } outcomePatternBuilder.Append(pattern[currentOutcome]); } //write the string containing pattern values to the file WriteString(outcomePatternBuilder.ToString()); } } /// /// Write the names of the predicates to the model file. /// protected void WritePredicateNames() { //write the number of predicates WriteInt32(mPredicates.Length); //for each predicate, write its name to the file foreach (PatternedPredicate predicate in mPredicates) { WriteString(predicate.Name); } } /// /// Writes out the parameter values for all the predicates to the model file. /// protected void WriteParameters() { foreach (PatternedPredicate predicate in mPredicates) { for (int currentParameter = 0; currentParameter < predicate.ParameterCount; currentParameter++) { WriteDouble(predicate.GetParameter(currentParameter)); } } } /// /// Class to enable sorting PatternedPredicates into order based on the /// outcome pattern index. /// private class OutcomePatternIndexComparer : IComparer { /// /// Default constructor. /// internal OutcomePatternIndexComparer(){} /// /// Implementation of the IComparer interface. /// Compares two PatternedPredicate objects and returns a value indicating whether /// one is less than, equal to or greater than the other. /// /// /// First object to compare. /// /// /// Second object to compare. /// /// /// -1 if the first PatternedPredicate has a lower outcome pattern index; /// 1 if the second PatternedPredicate has a lower outcome pattern index; /// 0 if they both have the same outcome pattern index. /// public virtual int Compare(PatternedPredicate firstPredicate, PatternedPredicate secondPredicate) { if (firstPredicate.OutcomePattern < secondPredicate.OutcomePattern) { return -1; } else if (firstPredicate.OutcomePattern > secondPredicate.OutcomePattern) { return 1; } return 0; } } } }