/*
 * Encog(tm) Core v3.4 - Java Version
 * http://www.heatonresearch.com/encog/
 * https://github.com/encog/encog-java-core
 
 * Copyright 2008-2016 Heaton Research, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *   
 * For more information on Heaton Research copyrights, licenses 
 * and trademarks visit:
 * http://www.heatonresearch.com/copyright
 */
package org.encog.ml.data.versatile.columns;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.encog.EncogError;
import org.encog.ml.data.versatile.NormalizationHelper;
import org.encog.util.Format;

/**
 * Defines a column definition.
 */
public class ColumnDefinition implements Serializable {
	/**
	 * The name of the column.
	 */
	private String name;
	
	/**
	 * Tye type of column.
	 */
	private ColumnType dataType;
	
	/**
	 * The observed low in a dataset.
	 */
	private double low;
	
	/**
	 * The observed high in a dataset.
	 */
	private double high;
	
	/**
	 * The observed mean in a dataset.
	 */
	private double mean;
	
	/**
	 * The observed standard deviation in a dataset.
	 */
	private double sd;
	
	/**
	 * The observed count for a catagorical column.
	 */
	private int count;
	
	/**
	 * The index of this column in the dataset.
	 */
	private int index;
	
	/**
	 * The classes of a catagorical.
	 */
	private final List classes = new ArrayList();
	
	/**
	 * The normalization helper.
	 */
	private NormalizationHelper owner;
	
	/**
	 * The column definition.
	 * @param theName The name of the column.
	 * @param theDataType The type of the column.
	 */
	public ColumnDefinition(String theName, ColumnType theDataType) {
		this.name = theName;
		this.dataType = theDataType;
		this.count = -1;
		this.index = -1; 
		this.low = this.high = this.mean = this.sd = Double.NaN;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the dataType
	 */
	public ColumnType getDataType() {
		return dataType;
	}

	/**
	 * @param dataType the dataType to set
	 */
	public void setDataType(ColumnType dataType) {
		this.dataType = dataType;
	}

	/**
	 * @return the low
	 */
	public double getLow() {
		return low;
	}

	/**
	 * @param low the low to set
	 */
	public void setLow(double low) {
		this.low = low;
	}

	/**
	 * @return the high
	 */
	public double getHigh() {
		return high;
	}

	/**
	 * @param high the high to set
	 */
	public void setHigh(double high) {
		this.high = high;
	}

	/**
	 * @return the mean
	 */
	public double getMean() {
		return mean;
	}

	/**
	 * @param mean the mean to set
	 */
	public void setMean(double mean) {
		this.mean = mean;
	}

	/**
	 * @return the sd
	 */
	public double getSd() {
		return sd;
	}

	/**
	 * @param sd the sd to set
	 */
	public void setSd(double sd) {
		this.sd = sd;
	}

	/**
	 * @return the count
	 */
	public int getCount() {
		return count;
	}

	/**
	 * @param count the count to set
	 */
	public void setCount(int count) {
		this.count = count;
	}

	/**
	 * Analyze the specified value.
	 * @param value The value to analyze.
	 */
	public void analyze(String value) {
		switch(this.dataType) {
			case continuous:
				analyzeContinuous(value);
				break;
			case ordinal:
				analyzeOrdinal(value);
				break;
			case nominal:
				analyzeNominal(value);
				break;
		}
	}

	/**
	 * Analyze a nominal value.
	 * @param value The value to analyze.
	 */
	private void analyzeNominal(String value) {
		if(!this.classes.contains(value)) {
			this.classes.add(value);
		}
		
	}

	/**
	 * Analyze a nominal value.
	 * @param value The value to analyze.
	 */
	private void analyzeOrdinal(String value) {
		if(!this.classes.contains(value)) {
			throw(new EncogError("You must predefine any ordinal values (in order). Undefined ordinal value: " + value));
		}
	}

	/**
	 * Analyze a nominal value.
	 * @param value The value to analyze.
	 */
	private void analyzeContinuous(String value) {
		double d = this.owner.getFormat().parse(value);
		if( this.count<0) {
			this.low = d;
			this.high = d;
			this.mean = d;
			this.sd = 0;
			this.count = 1;
		} else {
			this.mean = this.mean + d;
			this.low = Math.min(this.low, d);
			this.high = Math.max(this.high, d);
			this.count++;
		}
	}
	
	
	
	/**
	 * @return the classes
	 */
	public List getClasses() {
		return classes;
	}

	@Override
	public boolean equals(Object obj) { 
		boolean result;
		if ( obj instanceof ColumnDefinition ) {
			ColumnDefinition that = (ColumnDefinition) obj;
			// Ignores the this.owner association.
			// Compares floating point values with exact equality, with no delta.
			result = ((this.name == that.name) || ((null != this.name) && this.name.equals(that.name)))
					&& (this.dataType == that.dataType )
					&& Double.valueOf(this.low).equals( that.low )
					&& Double.valueOf(this.high).equals( that.high )
					&& Double.valueOf(this.mean).equals( that.mean )
					&& Double.valueOf(this.sd).equals( that.sd )
					&& (this.count == that.count)
					&& (this.index == that.index)
					&& this.classes.equals( that.classes );
			// Equality ignores owner.
		} else {
			result = false;
		}
		
		return result;
	}
	
	/**
	 * {@inheritDoc}
	 */
	public String toString() {
		StringBuilder result = new StringBuilder();
		result.append("[");
		result.append("ColumnDefinition:");
		result.append(this.name);
		result.append("(");
		result.append(this.dataType.toString());
		result.append(")");
		if( this.dataType==ColumnType.continuous) {
			result.append(";low=");
			result.append(Format.formatDouble(this.low,6));
			result.append(",high=");
			result.append(Format.formatDouble(this.high,6));
			result.append(",mean=");
			result.append(Format.formatDouble(this.mean,6));
			result.append(",sd=");
			result.append(Format.formatDouble(this.sd,6));
		} else {
			result.append(";");
			result.append(this.classes.toString());
		}
		result.append("]");
		return result.toString();
	}

	/**
	 * Define a class for a catagorical value.
	 * @param str The class to add.
	 */
	public void defineClass(String str) {
		this.classes.add(str);
	}	
	
	/**
	 * Define an array of classes for a catagorical value.
	 * @param str The classes to add.
	 */
	public void defineClass(String[] str) {
		for(String s: str) {
			defineClass(s);
		}
	}

	/**
	 * Set the owner of this class.
	 * @param theOwner The owner of this class.
	 */
	public void setOwner(NormalizationHelper theOwner) {
		this.owner = theOwner;
	}

	/**
	 * @return the index
	 */
	public int getIndex() {
		return index;
	}

	/**
	 * @param index the index to set
	 */
	public void setIndex(int index) {
		this.index = index;
	}
	
}

 

Ads help maintain this website.