//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 GISModelReader.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; namespace BotSharp.Models.IO { /// /// Abstract parent class for readers of GIS models. /// /// /// Jason Baldridge /// /// /// Richard J. Northedge /// /// /// based on GISModelReader.java, $Revision: 1.5 $, $Date: 2004/06/11 20:51:36 $ /// public abstract class GisModelReader : IGisModelReader { private char[] _spaces; private int _correctionConstant; private double _correctionParameter; private string[] _outcomeLabels; private int[][] _outcomePatterns; private int _predicateCount; private Dictionary _predicates; /// /// The number of predicates contained in the model. /// protected int PredicateCount { get { return _predicateCount; } } /// /// Retrieve a model from disk. /// ///

This method delegates to worker methods for each part of this /// sequence. If you are creating a reader 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 reader for a format which does not follow this /// sequence at all, override this method and ignore the /// other ReadX methods provided in this abstract class.

///
/// /// Thie method assumes that models are saved in the /// following sequence: /// ///

GIS (model type identifier)

///

1. the correction constant (int)

///

2. the correction constant parameter (double)

///

3. outcomes

///

3a. number of outcomes (int)

///

3b. outcome names (string array - length specified in 3a)

///

4. predicates

///

4a. outcome patterns

///

4ai. number of outcome patterns (int)

///

4aii. outcome pattern values (each stored in a space delimited string)

///

4b. predicate labels

///

4bi. number of predicates (int)

///

4bii. predicate names (string array - length specified in 4bi)

///

4c. predicate parameters (double values)

///
protected virtual void ReadModel() { _spaces = new char[] {' '}; //cached constant to improve performance CheckModelType(); _correctionConstant = ReadCorrectionConstant(); _correctionParameter = ReadCorrectionParameter(); _outcomeLabels = ReadOutcomes(); ReadPredicates(out _outcomePatterns, out _predicates); } /// /// Checks the model file being read from begins with the sequence of characters /// "GIS". /// protected virtual void CheckModelType() { string modelType = ReadString(); if (modelType != "GIS") { throw new ApplicationException("Error: attempting to load a " + modelType + " model as a GIS model." + " You should expect problems."); } } /// /// Reads the correction constant from the model file. /// protected virtual int ReadCorrectionConstant() { return ReadInt32(); } /// /// Reads the correction constant parameter from the model file. /// protected virtual double ReadCorrectionParameter() { return ReadDouble(); } /// /// Reads the outcome names from the model file. /// protected virtual string[] ReadOutcomes() { int outcomeCount = ReadInt32(); var outcomeLabels = new string[outcomeCount]; for (int currentLabel = 0; currentLabel < outcomeCount; currentLabel++) { outcomeLabels[currentLabel] = ReadString(); } return outcomeLabels; } /// /// Reads the predicate information from the model file, placing the data in two /// structures - an array of outcome patterns, and a Dictionary of predicates /// keyed by predicate name. /// protected virtual void ReadPredicates(out int[][] outcomePatterns, out Dictionary predicates) { outcomePatterns = ReadOutcomePatterns(); string[] asPredicateLabels = ReadPredicateLabels(); predicates = ReadParameters(outcomePatterns, asPredicateLabels); } /// /// Reads the outcome pattern information from the model file. /// protected virtual int[][] ReadOutcomePatterns() { //get the number of outcome patterns (that is, the number of unique combinations of outcomes in the model) int outcomePatternCount = ReadInt32(); //initialize an array of outcome patterns. Each outcome pattern is itself an array of integers var outcomePatterns = new int[outcomePatternCount][]; //for each outcome pattern for (int currentOutcomePattern = 0; currentOutcomePattern < outcomePatternCount; currentOutcomePattern++) { //read a space delimited string from the model file containing the information for the integer array. //The first value in the integer array is the number of predicates related to this outcome pattern; the //other values make up the outcome IDs for this pattern. string[] tokens = ReadString().Split(_spaces); //convert this string to the array of integers required for the pattern var patternData = new int[tokens.Length]; for (int currentPatternValue = 0; currentPatternValue < tokens.Length; currentPatternValue++) { patternData[currentPatternValue] = int.Parse(tokens[currentPatternValue], System.Globalization.CultureInfo.InvariantCulture); } outcomePatterns[currentOutcomePattern] = patternData; } return outcomePatterns; } /// /// Reads the outcome labels from the model file. /// protected virtual string[] ReadPredicateLabels() { _predicateCount = ReadInt32(); var predicateLabels = new string[_predicateCount]; for (int currentPredicate = 0; currentPredicate < _predicateCount; currentPredicate++) { predicateLabels[currentPredicate] = ReadString(); } return predicateLabels; } /// /// Reads the predicate parameter information from the model file. /// protected virtual Dictionary ReadParameters(int[][] outcomePatterns, string[] predicateLabels) { var predicates = new Dictionary(predicateLabels.Length); int parameterIndex = 0; for (int currentOutcomePattern = 0; currentOutcomePattern < outcomePatterns.Length; currentOutcomePattern++) { for (int currentOutcomeInfo = 0; currentOutcomeInfo < outcomePatterns[currentOutcomePattern][0]; currentOutcomeInfo++) { var parameters = new double[outcomePatterns[currentOutcomePattern].Length - 1]; for (int currentParameter = 0; currentParameter < outcomePatterns[currentOutcomePattern].Length - 1; currentParameter++) { parameters[currentParameter] = ReadDouble(); } predicates.Add(predicateLabels[parameterIndex], new PatternedPredicate(currentOutcomePattern, parameters)); parameterIndex++; } } return predicates; } /// /// Implement as needed for the format the model is stored in. /// protected abstract int ReadInt32(); /// /// Implement as needed for the format the model is stored in. /// protected abstract double ReadDouble(); /// /// Implement as needed for the format the model is stored in. /// protected abstract string ReadString(); /// /// The model's correction constant. /// public int CorrectionConstant { get { return _correctionConstant; } } /// /// The model's correction constant parameter. /// public double CorrectionParameter { get { return _correctionParameter; } } /// /// Returns the labels for all the outcomes in the model. /// /// /// string array containing outcome labels. /// public string[] GetOutcomeLabels() { return _outcomeLabels; } /// /// Returns the outcome patterns in the model. /// /// /// Array of integer arrays containing the information for /// each outcome pattern in the model. /// public int[][] GetOutcomePatterns() { return _outcomePatterns; } /// /// Returns the predicates in the model. /// /// /// Dictionary containing PatternedPredicate objects keyed /// by predicate label. /// public Dictionary GetPredicates() { return _predicates; } /// /// Returns model information for a predicate, given the predicate label. /// /// /// The predicate label to fetch information for. /// /// /// Array to be passed in to the method; it should have a length equal to the number of outcomes /// in the model. The method increments the count of each outcome that is active in the specified /// predicate. /// /// /// Array to be passed in to the method; it should have a length equal to the number of outcomes /// in the model. The method adds the parameter values for each of the active outcomes in the /// predicate. /// public virtual void GetPredicateData(string predicateLabel, int[] featureCounts, double[] outcomeSums) { try { if (predicateLabel != null && _predicates.ContainsKey(predicateLabel)) { PatternedPredicate predicate = _predicates[predicateLabel]; int[] activeOutcomes = _outcomePatterns[predicate.OutcomePattern]; for (int currentActiveOutcome = 1; currentActiveOutcome < activeOutcomes.Length; currentActiveOutcome++) { int outcomeIndex = activeOutcomes[currentActiveOutcome]; featureCounts[outcomeIndex]++; outcomeSums[outcomeIndex] += predicate.GetParameter(currentActiveOutcome - 1); } } } catch (ArgumentNullException ex) { throw new ArgumentException(string.Format("Try to find key '{0}' in predicates dictionary ({1} entries)", predicateLabel, _predicates.Count), ex); } } } }