/*
* 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<String> classes = new ArrayList<String>();
/**
* 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<String> 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;
}
}